Bread crumbs in version control

I’m sorry but sometimes I really don’t get why even seasoned developers doesn’t learn the art of the commit message in version control system. All too often I’ve come across check-ins where the entire commit message just reads “bugfix”, “change”, “oops” or something just as mindless.

The effort of writing a useful message compared to the potential benefit seems to be one the best ratios – but of course the pay-back is usually some time away – too bad. Once you work on the same code for years – or even better inherit code from others, you’ll quickly learn to appreciate anyone who used more than 10 seconds on composing a thoughtful message for the future.

Here are 3 rules you should always, always obey when committing to a version control system.

Always leave a reference to the issue/bug tracking system.

All professional development uses some sort of issue tracking system, to keep track of bugs, new features and other changes to the system. The issue tracking system should always be able to tell who asked for a change, why it was asked for and what considerations was made before the code change. By leaving a reference to the issue tracker, it’s often much easier to get “the big picture” if the change need to be changed years later. To make sure you get it in, just write “Bug #number#: “ as the initial part of the commit message.

Don’t write what, write why

Don’t write it’s a bug fix – most people will know it from look either at the code or in the issue tracking system (see point 1 above), rather write why it fixes the issue (“New check to check for missing parameters”, “Now handles no search result from db correct” – not just “bugfix”).

Keep it brief.

Log messages are not a place to store documentation, user guides or any other important information. You can assume it’s the future you (or another future fellow developer) who will look at the code and try to make sense of it. Think of this, when writing the message – it’s not for the project manager, it’s not for the end-users – it’s for a developer doing maintenance work on the code in the future.

PHP best practice: Function Parameters

I’ve been developing web applications for some years now, and while I make no claims to being the world greatest developer, I do figure, that I do have some solid experience which may help others – or at least encourage thoughts and discussion. This is the first in a series of posts, and while it may be from a PHP developers point of view, it may applicable to other programming languages, and maybe even beyond web applications. Here are my four tips on function parameters.

Always have a default value on all parameters

Functions parameters are often used as input to SQL queries, calling webservices or computations. Null or non-existing values often tend to break these things and throws horrible messages to the end-user.

While the parts of the program using your function always should provide proper values, laziness, oversights or unexpected scenarios, may prove it not to be the case. If at all possible, always try to provide default values on all parameters to a function – and if you really can’t make sure it’s handled gracefully.

Choose reasonable defaults

When providing default values, don’t choose extremes. If you’re browsing in a list of usernames, don’t use a (pure) wildcard as default value – use an “A” to list all users starting with the letter A. If you’re function allows a limit on the number of rows returned form a database query (say for paging purposes), set the default to 10, 20 or some other low number, don’t go for worst case scenarios like 9999, or 999999.

If the developer using the function needs plenty of rows, it’s easy to pass a specific value, and if the developer forgets to specify the number of rows, expected, they get a reasonable result, which may help them to ask for more (if actually needed).

Always sanitize input

Even though a given function naturally only will be used with valid input and so on, every function should take steps to secure them selves.
One of the most basic steps is to make sure all input is sanitized. Protecting your function from making SQL injection threats or other security issues, is not the responsibility of the places utilizing the function, but the responsibility of the function it self, and thus it should take steps to make sure it doesn’t introduce security issues.

As basic validation of simple input parameters, look at the ctype functions in PHP. If you can always try to validate against a whitelist (which characters are allowed) instead of blacklists (these characters are not allowed) as missing things which may introduce issues in a black list is harder, than allowing what you expect, to pass through.

Accept an array of key value pairs

If a simple function accepts a single or two parameters, they may be passed as regular parameters, but once the list of possible parameters starts to grow, changing it a single parameter – which is an array with key/value-pairs, seems to be a much more solid long-term solution on keeping the interface developer friendly. Sure you can have endless lists of 10-15 parameters, but if you have default values on the first 14 values and just need to change the last, the code ought to be much more clean by being able to pass an array with the single key/value-pair needed to be changed from the default value.

That was the first four tips on function parameters. More on PHP and Security.

Build-in time bombs

I’ve been refactoring and refactoring some old code, and it’s kind of odd what short-cuts (or even time bombs), you’ll find in code, which apparently wasn’t supposed to live on for years.
In a now retired CMS system, we had an issue every new year, when some kind of bug would reset all “schedules” for upcoming stories and content. No-one ever got around to fix it, as the system was soon to be decommissioned – but sadly the bug did survive a few years anyway.

These days, I’m was working in the system, which came to replace the broken system from before. Here’s another odd thing – It was apparently hard coded into the editor in the backend, that stories need to have a “published date” between 1996 and 2011. As there really isn’t any documentation and the original developer has left the company, it’s hard to know why it was made so. While there probably was a reason, it’s lost by now.

 <select name="year" size="1" style="width:55px;" title="Year">
 <?php
   for ($i = 1996; $i < 2011; $i++) {
       printf("<option value=\"%1\$d\"%2\$s>%1\$d</option>",$i,($year == $i) ? " selected" : "");
   }
   ?>
</select>

We fixed it by making the latest “published date” go between 1996 and current year plus one.

While it was an odd thing, I’m surely glad that we from time to time do some sort of maintenance of old code – even while it seems to work perfectly. It’s far from the only bad thing we found, and while most people worry mainly about new code, sometimes you should also remember the old stuff.

Your mileage may vary

It’s always fun to read articles with tips and tricks by other developers and see how they figure “best practices” are handled. Most developers do seem to thing they observations and practices are easily adopted by anyone, and should be accepted without any argumentation or reasoning behind the advice.

One of the nice examples of this, was a story called “5 tips and tools to develop php applications fast”, and while it may apply to the web applications developed by the author, it’s one of those where I question who is supposed to be the audience. All 5 tips are often found in many textbooks and other stories on the net, and in my experience they are all wrong (more or less naturally).

1) Use a MVC framework – it’s an industry accepted standard.
MVC as an idea may be accepted, but there are many ways of implementing the MVC – even with the various PHP frameworks. If you know the MVC pattern it may be an idea to look at the frameworks supporting it, but don’t get carried away.

  • If all your old code is non-MVC code and you don’t have any plans to MVC-refactor it, it may cause you maintenance overhead to try a completely different style  on a single project/web application.
  • If you aren’t used to using a (MVC) framework you need to invest time in learning it.

Do keep an eye on the overhead caused by the framework. If you web application has a heavy load and the framework causes 5-10% overhead, it may a bad idea.

2) Ajax Frameworks
Great idea.. but to utilize the power of an ajax framework, you need to learn how to use it. Also Ajax isn’t the holy grail of the internet. Sometimes it’s cleaver to use it, other times it isn’t. By using plain old HTML and reloading the page from time to time, it may be easier to debug the application.

Do also notice, that writing great/professional quality Javascript often requires just as great skills as writing professional PHP.

3) IDEs
An IDE – Integrated Development Environment – can be a great idea if you know your way around it, and use it regularly. An IDE is – like any other tool – something you need to invest time and resources into, if you want something back – and especially if we’re talking a beast like Eclipse-based tools.

4) Database creation/management software
Let me skip comments on database creating management tools. I’ve never really used them and don’t know if they’re a pain or a benefit. I have often seen though, that too easy access to the database, leads to sloppy database design (or at least something, that isn’t thought through).

So far it’s been my experience, that people who knows the command-line clients to databases, often has invested much more time in thinking their data models through and often spend a little more time considering the table layout, the field definitions, indexes and other important aspects, than those who use a nice graphical interface.

5) Object Relational Mapping
Object-Oriented programming isn’t a holy grail, and most people doing OO programming (in my experience) doesn’t genuinely do object-oriented programming – instead they use the OO-facilities in the language to slap functions together in a class.

There’s nothing wrong with procedural programming as such, and trying to force object-orientation into your code – and even abstracting it away through Object-relational mapping, has often lead to slow performance and odd database designs. If you know what you’re doing great, but there’s no free lunch, and trying to utilze ORM without having a pretty solid grip on what’s happening and why, rarely does anything good to your productivity.

I’m quite sure for some developers, using some sort of object-relational mapping might be a gain in programmer productivity, but do keep in mind, that if you’re developing a site with massive traffic, the programmer gains may easily be crushed in added server resource requirements – spending a few minutes extra optimizing and tuning applications, may in some cases save hours and hours of cpu cycles once the solution is deployed.

Getting back to the article, I’m sure the advise is well-meant and thought through by the author, but do always – as with all advise – think it through and see how may apply to your adoptation. In may daily development some of it is quite terrible (as I often work on a site with thousands if not millions of pageviews every week).

I’m wondering what my 5 tips would be for developing PHP applications fast would be. Check back in a few days, and there may be an answer – which may or may not – apply to you.

Code archeology

I’ve been spending quite some time the past days digging around in old code (3+ years old with no or very little changes). It’s quite fun noticing what efforts pay off and which doesn’t when you go back to make chance to old stuff. I’m sure my observations aren’t generally applicable. We’re web developers and are keeping web platform (several pretty big websites on a common codebase) alive year after year.

Proper and sane variable- and function names pays off instantly. Incredibly short or misguiding function and variable names doesn’t. While it may be fun naming functions “doMagic” or likewise, chances that you – or someone else maintaining the code years after will probably not appreciate it at all.

Reasonable commenting on functions and tricky code parts often come to good use, but too much commenting is distracting. Some is good, and less is often more valuable.

Version control logs can be quite valuable, if they’re descriptive for the change made. Too often though, was the comment “misc. bug fixing”, “problem solved” or something which years later was of no use or value at all.

Documentation kept apart from the source code seem to have none or very little value. Not once have I bothered to look in the wiki-documents or any other documentation which was in the code. In the few instances I did, minor changes and bug fixes had changed the code to such an extend (while not updating the documentation) that it was misleading at best.

The only cases where the documentation apart seem to make a positive is database diagrams and descriptions. They do seem to have value.

PHP Dynamic Caching with ZendPlatform

I recently had a little fun playing with the dynamic cache available in the Zend Platform. The Zend Platform is a commercial product, which provides a number of cool professional features to a PHP setup – one of these is the option to do dynamic caching.

With dynamic caching you can cache the output of a function for a determined period and instead of doing database queries or web service calls for a feature, you can cache the results, save resources and get faster pages.

If you have access to a PHP setup with Zend Platform, but haven’t looked at dynamic page caching, here’s a little example to get you inspired and started.

Dynamic Caching Example

Let’s suppose you have a busy news website and publish lists of news from categories – on the front page, along side news articles and several other places. to retrieve the most recent articles for each category, we’ve created a class with a function to retrieve the five most recent stories from a category specified by a parameter.

Our first version may look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class NewsCategory
{
        public function getCurrent($category)
        {
                $newsLines = Array();
		if (intval($category)) {
                $sql = sprintf('SELECT * FROM news WHERE category="%n"
                                     ORDER BY date LIMIT 5', $category);
                /* Asume connection to dbserver exists and is valid */
                $res  = mysql_query('newsdb', $sql);
                $data = mysql_fetch_array($res);
                $newsLines = Array();
                while ($newsItem = mysql_fetch_array($res)) {
                        array_push($newsLines, $newsItem);
                }
        }
        return $newsLines;
        }
}

Since news doesn’t happen too often and the lists of news are displayed on many pages, we want to cache the results for an hour – and we want to make sure, that the site works, even if we for some reason decide to disable the Zend Platform.

Rewriting the class to utilize the caching API takes a few changes and the Dynamic Cache-enabled version looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
 * SAMPLE CODE; NOT FOR PRODUCTION USE
 */
class NewsCategory
{
        const CACHE_TIME = 3600; // caching time in seconds. Global caching set to 1 hour.
        const CACHE_KEY  = 'NewsCategory_getCurrent_'; // prefix for caching key
 
        /**
         * Returns array with current newsitems from the specified category.
         *
         * @param integer $category
         * @return array with news items
         */
        public function getCurrent($category)
        {
                if (function_exists('output_cache_fetch')) { // caching available?
                        return unserialize(output_cache_fetch(
                                self::CACHE_KEY . $category,
                                "serialize(self::fetchCurrent($category))",
                                self::CACHE_TIME));
                } else { // No ZendPlatform Available
                        return self::fetchCurrent($category);
                }
        }
 
        /**
         * Internal function for looking up the current news identified by $category.
         *
         * @param integer $category
         * @return array - returns empty array if no news is found.
         */
        protected function fetchCurrent($category)
        {
                $newsLines = Array();
		if (intval($category)) {
                $sql = sprintf('SELECT * FROM news WHERE category="%n"
                                     ORDER BY date LIMIT 5', $category);
                /* Asume connection to dbserver exists and is valid */
                $res  = mysql_query('newsdb', $sql);
                $data = mysql_fetch_array($res);
                $newsLines = Array();
                while ($newsItem = mysql_fetch_array($res)) {
                        array_push($newsLines, $newsItem);
                }
        }
        return $newsLines;
        }
}

The changes are:

  • The public function from the first version is replaced by a method, that handles the caching. The function doing the work is now hidden in a protected method in the class.
  • If the caching API isn’t available, the new function just acts a proxy passing data through.
  • The new caching functions creates caching keys from the method name and the parameter to make them predictable and avoid namespace clashes.
  • do notice that the cached results are serialized in the cache – the cache can only store string values.

Before going crazy with Dynamic Caching do consider a few things:

  • Is the data suited for caching? (or do you need the most accurate data every time)
  • What level do you expect the cache ratio to be at? (how often is the cache utilized)
  • Are other caching mechanisms in place? (ie. proxy-servers or likewise)

Loading data from a file with PHP

In programming languages common tasks should be easy, and surprisingly often I find my self loading data from some source file into a database. With PHP loading a CSV file into the database – or posting the data to an API – is quite easy.

The only trick is to know the functions file_get_contents, split (and possibly list). The routine goes something like this:

1
2
3
4
5
6
7
8
9
10
$fileName = 'rawData.csv';
 
$content = file_get_contents($fileName);
$rows = split("\n", $content );
 
foreach ($rows as $row) {
	list($item1, $item2, item3) = split(';', $row);
 
	// Do something interesting...
}

The script gets the contents of file into a variable ($contents). Split the contents into an array ($rows) and the forach loop across each row. The first line of the loop splits the row into three fictitious items and the rest of the loop could do something interesting to the data read from the file.

I usually run scripts like these from the command-line (yes, you can do that with PHP scripts).

PHP: Removing an item from an array

If you have a php array, but need to nuke an item from it, the unset function is just the tool to do that. When iterating through the array after removing the item, you should be slightly careful.

The unset function does remove the item, but it doesn’t “reindex” the array, so you should traverse the array by index-numbers after removing the item. The issue is probably best illustrated by this example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$myArray = Array('item 1', 'item 2', 'item 3');
 
// remove item
var_dump($myArray);
 
unset($myArray[1]);
var_dump($myArray);
 
// Failing bad loop
for ($loop = 0; $loop < count($myArray); $loop++) {
        echo $myArray[$loop] . "\\n";
}
 
// Good loop
foreach ($myArray as $item) {
        echo $item . "\\n";
}

You can dowload the above example code here.

ZendStudio for Eclipse

For professional PHP development, nothing beats ZendStudio in my book. Currently ZendStudio is in the process of moving from a standalone application to something build on
top of Eclipse. I’m sure it might be a wise move on the long term, but there are a few things bugging me with th current version. The number one issue is shown in the screenshot to the right.

Would someone please tell either Eclipse or ZendStudio, that PHP files do not need to be build, compiled or what ever it is doing – besides wasting my time for a few minutes.