Archive for the Category Development

 
 

PHP versions on shared hosting in Belgium

Since the PHP build version became so important with Zend Framework, I made a list of some (on the Belgian market) prominent hosting companies and the PHP version they offer on their shared hosting.

It does not pretend to be a complete list, but rather an alphabetical list of hosting providers I bump or bumped in to once in a while. The PHP version listed is mentioned on their site or, if not on their site, retrieved through their support.

PHP version Mentioned on site
www.alfahosting.be 5.2.8 (*) No
www.combell.be 5.1.2 Yes
www.hostbasket.be 5.2.3 No
www.level27.be 5.2.4 (*)
No
www.nucleus.be 5.2.4 No
www.one.com 5.2.8 No
www.openminds.be 5.2.8 (*) No
www.priorweb.be 5.2.8 No
www.uniweb.be 5.2.4 No
www.weble.be 5.2.6 (*) Yes

(*) they offered to install any version required.

As you can see, Combell is worst for PHP developers. There currently is also no way to get any higher version with them. It is a sad thing.

Besides them, only Weble mentions (luckily a proper) full version number on their site. Although customers that tend to find the complete PHP version number important are probably a (growing) minority, it can make a sale.

Also, I’m surprised by the cheapest one, One. It’s the only “big” one that offers a recent version.

Please, don’t hesitate to add any others to the list.

Zend Framework PHP requirements

I try to enforce Zend Framework for every new project started. If not in the requirements section of my quote, it is not that hard to convince a client of its advantages.

Tell a client how Zend Framework

  • improves stability,
  • lowers development time

and in particular

  • makes them less dependent on you as other ZF developers can pick up projects you started a lot easier.

Now, please don’t start to think about job security. Just don’t.

But, Zend Framework has a fairly high PHP version requirement. Since version 1.7 Zend has quietly changed the requirements to PHP 5.2.4. In respect of a client’s (shared) hosting, this can be the most difficult part.
This was probably a logical thing to do since the requirements mentioned PHP 5.1.4 until ZF 1.6.2 and pre-5.2.4 versions miss some great features and contain nasty bugs (in reality some ZF components didn’t even run on PHP 5.1.4).

In Belgium however, it is difficult to find a hosting company that supports PHP 5.2.4.

FireFox does not save cookies

Since I installed a recent update of FireFox 3, cookies were not being saved after a browser session ended.

While there seem to be different causes, if you’re on Windows and using AVG, the file that contains cookies may be locked by AVG for some reason. Deleting that file or disabling AVG to scan cookies may help.

FireFox saves cookie information on Windows in:

[DRIVE]:\Documents and Settings\[USER]\Application Data\
Mozilla\Firefox\Profiles

The file is named cookies.sqlite.

If you delete it however, you’ll have to check quite a few “remember me” boxes in the near future.

New PHP IDE: Aptana Studio with PHP support

After PHPEclipse and PDT, a new PHP IDE based on Eclipse is available: Aptana Studio.

Aptana Studio

Read more about it in Federico Cargnelutti’s post on PHP::Impact ( [str Blog] ).

I’ve had a look at the screencast available on the Aptana site and in my opinion the only neat difference to PDT is the “Generate Getters and Setters…” option. As you could suspect, it generates get and set methods based on a selection of existing class properties.

Apart from that, the majority of features shown also exist in PDT.

But it is only version 1.0 so who knows what future versions may bring.

Eyedropper

Ever wondered what color that one pixel on your screen is?

While you also have great FireFox alternatives, Instant Eyedropper lets you select a pixel anywhere on your desktop by magnifying a 5 pixels square underneath your cursor.
Of course it also copies the selected color’s hex value to your clipboard when you release your mouse.

It saves me a lot of time!

Improve site visit length with Google Analytics

You can use Google Analytics in 2 main ways: as a bloated Webalizer or as a list of possible improvements for the site in question (or both of course).

If you just start using it the second way, the number one improvement suggestion that has always been in front of your nose is the list of Top Landing Pages (which you’ll find under “Content” in the menu) and their bounce rate. Keep it sorted by “Entrances” and the only thing you then have to do is pick the page with the highest bounce rate in the top 10. Now fix that page (as clearly something is wrong).

Make sure people that hit that page find ways to lengthen their visit to other parts of the site. Clearly visitors to that page aren’t noticing your navigation or other links.

You can use this knowledge to direct them to the content that you want them to see or to the content that they are looking for. To get a hint of the latter, click on the page in question in your report and click on the “Entrance Keywords” under “Landing Page Optimization”. The list of search keywords used to reach that page, for instance, could set you off in the right direction.

Of course you can continue with other high bounce rate-pages but it may be a good idea to monitor if your changes had any effect first.

The more data available, the more relevant the Top Landing Pages report is. But even if your site only attracts a few visitors per day, just stretch the time span your report covers to have a larger data sample.

Hopefully this helps to improve retention bit by bit.

Euro conversion rate feed

I came across this while searching for a good currency conversion feed or web-service for Clickini earlier this year.

It’s probably useful in your project too:
http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml

The European Central Bank updates it once a day (hence, daily) at 14:15 CET (currently GMT +1).

Besides this, they also provide a history since 1999 and various other formats (PDF, CSV and iPhone). Who knows what you can use that for.

Any alternatives?

Ext JS available via CDN

As many JavaScript libraries relied on Google or AOL, Ext JS didn’t have a CDN.

Until now: they have partnered with CacheFly.

If you, for instance, need the complete library, use:

  • http://extjs.cachefly.net/ext-2.2/ext-all.js
  • http://extjs.cachefly.net/ext-2.2/resources/css/ext-all.css

This is great. Ext JS can be one of the bigger libraries (even minified & packed).

Speed up Zend Framework

The performance of frameworks has always been subject to discussion and Zend Framework is no exception.

But with the release of version 1.7 an appendix has been added to the manual with guidelines to improve performance.

Most notably:

  • How to optimize your include path (even if it is in your vhost conf).
  • Do not use XML translation formats if possible and certainly use caching for these framework parts.
  • Different techniques to improve view rendering.

Read the complete appendix for a detailed explanation.

Language specific tables in MySQL

Since a large part of the world doesn’t care about i18n and L10n, remarkably little articles on best practices are available about these topics.

If you live in a multilingual country however, you can’t build an application without. For a recent project I was looking at a way to avoid language specific tables (it goes without saying language specific fields are not an option either!).

Since we all like to keep our data as clean as possible, I have created my language specific tables like this example:

CREATE TABLE IF NOT EXISTS `country` (
  `code` char(2) NOT NULL,
  `language` char(2) NOT NULL default 'en',
  `name` varchar(100) NOT NULL,
  PRIMARY KEY  (`code`,`language`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

A sample country table with the ISO code as identifier, a language ISO code and the country name in that specific language. Notice that code and language form the composed primary key. In a multi-table set-up you would probably have a country table and a country_language table. Although this solution looks so much cleaner it creates a challenge when it comes to querying.

Imagine you would have these records:

DE,en,Germany
DE,de,Deutschland
DE,fr,Allemagne
US,en,United States
US,fr,Étas-Unis

and you want to get a list of countries for a German audience.

Since much data in these kinds of tables won’t be translated into all possible languages (which is the case for German in this example), you will probably want to settle for a default language if German is not available: let’s say English in this case.

Basically you want to have a result with Deutschland and United States. After some thought, this query is my best bet:

SELECT IFNULL(language_set.`code`, default_set.`code`) AS 'code',
  IFNULL(language_set.`language`, default_set.`language`) AS 'language',
  IFNULL(language_set.`name`, default_set.`name`) AS 'name'
FROM `country` AS default_set
LEFT OUTER JOIN `country` AS language_set
  ON default_set.`code` = language_set.`code`
  AND language_set.`language` = 'de'
WHERE default_set.`language` = 'en'

This creates a set of German data joined by English data if German is not available. Since MySQL supports sub-queries for some time, you can use this set as a sub-query in any larger query. In my project I’ve put this default query in each language-based model for re-use in larger queries. For example:

$sql = "SELECT DISTINCT country.*
  FROM (" . $completeSet . ") AS 'country'
  INNER JOIN other_table ON country.`code` = other_table.`country_code`
  ORDER BY country.`name`";

This would query all countries that have records in other_table.

Until now, I haven’t found a situation where this could not be used. I don’t guarantee that there isn’t one though. Any improvements are highly appreciated!