Jump to Content

Minding Your PHP P's and Q's

Yes, I admit it. Despite the curious title, this is actually an article about coding styles, naming conventions, and where those little curly braces should be going. But take a second to consider the prospect of returning to a PHP jungle of poor indentation, haphazard braces and cryptic variable/function names in 2 year old code... and you might consider reading further!

Personal or Prescriptive?

As long as you're consistent, why shouldn't you use your own unique style? Well, none of us code in a complete vacuum - your code needs to be maintained by your current and future colleagues, and most projects entail at least some collaboration. A funky mix of two different coding styles is almost as bad as no coding style at all.

Conventions are your friend, be boring and use them. Seriously, they have generally developed over time as the most popular methodology. When referring to coding style, the popular way is what most people find easiest to understand. Use that.

Good Points
Anybody can look at your code and figure out what's gong on.
People make fewer mistakes in consistent environments.
Bad Points
The standard is usually stupid because it's not what I do.
Standards stifle creativity.

Capitals, Underscores and Naming

Names are at the core of any programming language, labelling variables, functions, classes and so on. In their creation, the single most important consideration is making names that fit. Never use nonsense names. Use a name that will intuitively give the unfamilar reader at least a clue what it is used for. Nonsense names are often used in academic computer science tests as generics, but even here such names serve no useful purpose and add nothing to the reader's understanding of the code.

The exception to this rule are temporary variables. Because these variables usually exist only within a small block of code, they do not need to have explanatory names. They should be short and concise. In particular, numeric variables used for iteration should always be named i, j, k, m or n. Try to avoid the use of l, it looks too much like the number one!

Name wisely, it makes a huge different to code readability:

PHP 5

  1. <?php
  2. // BAD naming.. what's going on here?
  3. function test($baz)
  4. {
  5. for ($foo=0;$foo<$baz;$foo++) {
  6. $bar[$foo]="test_$foo";
  7. }
  8. return $bar;
  9. }
  10. // GOOD naming.. intuitive.
  11. function createTestArray($size)
  12. {
  13. for ($i=0;$i<$size;$i++) {
  14. $retval[$i]="test_$i";
  15. }
  16. return $retval;
  17. }
  18. ?>

In addition to descriptive names, capitalisation and underscore conventions can help us to recognise what something is (i.e. variable, function, etc.) simply by the format in which it is named. The PEAR coding standards are the usual conventions for PHP: its rules are summarised in the table.

Naming Conventions
Type Convention Example
Note that abbreviations should not be capitalised in names just because they are abbreviations. The function name printXhtml() is correct, printXHTML() is not!
Variable all lowercase, use _ as a word separator $my_variable
Constants all uppercase, use _ as a word separator $MY_CONSTANT
Functions capitalise first letter of each word apart from the first (Camel caps) myFunction()
Classes capitalise first letter of each word (Pascal case) MyClass
Class Methods capitalise first letter of each word apart from the first (Camel caps) myMethod()

In PHP 4, private class properties and methods are conventionally prefixed with an underscore. This is useful to indicate your intentions to another developer, but unnecessary if you are coding in PHP 5 as you can explicitally declare the visibility.

Namespaces

Lets illustrate the issue with an example: two PHP libraries need to be combined - one deals with xml operations and has the class File. One caches web-pages and also has a File class. The problem is obvious: the two names clash and both libaries can't both be used in the same script.

One solution often used in other languages is Namespaces. These are abstract containers that can be used to prevent name clashes with different libraries. For instance, in the original example we might define a namespace for each library, and then be able to use both File classes in one script, using the namespace label to differentiate between them. Unfortunately, namespaces didn't quite make it into PHP5, but at least they are likely to be included in PHP6.

In the meantime, without namespaces, what's the solution? Many developers simulate namespaces by adding prefixes to function and class names. In fact, this practice is recommended by the core PHP team. Such prefixes should be short and concise, and separated from the function or class name by an underscore.

In our example, we might have chosen XML as the namespace prefix for one library, and WEBCACHE as the prefix for the other. If we have followed these prefixing rules, our two classes would be named XML_File and WEBCACHE_File. Simulating namespaces isn't pretty, but it is does solve the problem. If necessary it's also possible to nest these simulated namespaces by adding more than one prefix also separated by an underscore.

Indenting, Line Length and Whitespace

In addition to naming conventions, code clarity can be greatly aided by a neat consistent layout. For example, the importance of indentation for organising your code cannot be exaggerated. Indentation is such an in-grained aspect in any programmer there is little need to stress its value. However, the nature of the indentation is often overlooked: there are several types of tabs and these will render differently across various IDEs. The choice lies between regular tabs and "soft" tabs. Soft tabs are not really tabs at all: each soft tab is actually represented by a certain number of spaces (usually four). I would recommend the use of soft tabs as they always appear the same, regardless of the editor's tab-spacing settings.

Most editors support soft-tabbing, and many editors auto-detect such formatting conventions based on "magic" comments in the source code. For example, the following comment sets the editor to use 4-space soft tabs in vim or emacs:

PHP 5

  1. <?php
  2. /*
  3. * vim: expandtab softtabstop=4 tabstop=4 shiftwidth=4
  4. *
  5. * Local variables:
  6. * tab-width: 4
  7. * c-basic-offset: 4
  8. * indent-tabs-mode: nil
  9. * End:
  10. */
  11. ?>

Keep lines short: I break up any line that is over 80 characters long (the width of a standard Unix terminal window, and a reasonable width for printing without wrapping). In addition, don't hesitate to use extra whitespace to group assignments and show associations. Compare the two identical examples below that differ only in terms of whitespace:

PHP 5

  1. <?php
  2. // example of POOR use of whitespace:
  3. $host='db.example.com';
  4. $username='phpuser';
  5. $passwd='mypwd';
  6. $db_name='mydb';
  7. $dbh = mysql_connect($host,$username,$passwd)
  8. or die('db failure.');
  9. mysql_select_db($db_name,$dbh) or die('db name failure.');
  10. $query = 'SELECT Name FROM country LEFT
  11. JOIN CountryLanguage ON
  12. Code=CountryCode WHERE CountryCode IS NULL';
  13. $result = mysql_query($query,$dbh);
  14. // reformatted to make BETTER use of whitespace:
  15. $host = 'db.example.com';
  16. $username = 'phpuser';
  17. $passwd = 'mypwd';
  18. $db_name = 'mydb';
  19. $dbh = mysql_connect($host,$username,$passwd)
  20. or die('db failure.');
  21. mysql_select_db($db_name,$dbh)
  22. or die('db name failure.');
  23. $query = 'SELECT Name
  24. FROM country LEFT JOIN CountryLanguage
  25. ON Code=CountryCode
  26. WHERE CountryCode IS NULL';
  27. $result = mysql_query($query,$dbh);
  28. ?>

Braces

There are two bracing conventions often used in PHP code: K&R and BSD styling.

PHP 5

  1. <?php
  2. // K&R Braces:
  3. if ($condition) {
  4. // statement
  5. }
  6. // BSD Braces:
  7. if ($condition)
  8. {
  9. // statement
  10. }
  11. ?>

For some, bracing styles is a passionately debated topic. I don't really see what all the fuss is about, myself, but you do need to be consistent. I follow the PEAR convention of using the more concise K&R styling for control structures, and the longer BSD styling for function and class declarations.

PHP 5

  1. <?php
  2. function isEven($number)
  3. {
  4. if ($number & 1) {
  5. return false;
  6. } else {
  7. return true;
  8. }
  9. }
  10. ?>

Code Comments

Documenting your code is very important, and although it will not be discussed any further here, I strongly recommend the phpdocumenter package. It's an invaluable tool, and brings the added advantage of a set of conventions with which to comment your code.

Non-documentation comments (or "inline comments") are also essential, to help understand what your code is actually doing rather than to describe the API to a potential user. Use C or C++ style comments (forward-slash star, or double forward-slash prefix) rather than the Perl-style comments (a hash prefix). Remember that inline comments should be used to clarify code - a classic example of a worthless comment is:

PHP 5

  1. <?php
  2. // increment i
  3. $i++;
  4. ?>

This comment doesn't add anything - it simply reiterates what should be obvious by reading the code. Your comments should aid understanding rather than just clutter the code:

PHP 5

  1. <?php
  2. function isEven($number)
  3. {
  4. // use the bitwise AND operator to see if
  5. // the first bit in $number is set, to
  6. // determine if it is odd/even.
  7. return !($number & 1);
  8. }
  9. ?>

Out, Out, You Pendant!

We've now covered the cornerstones of good code style: naming, indentation, braces and commenting. There's plenty of other useful conventions, but this article is not the place for a comprehensive list of them all. Instead, I will leave you with a few that I regard the most useful:

  • Always use full php tags:

    PHP 5

    1. <?php ... ?>
  • Avoid using echo to construct XHTML. One of the beauties of PHP is that it allows for embedding of PHP in XHTML. You should take advantage of this ability.
  • Add a single space after control construct keywords (if, while, foreach, ...) to differentiate them from function calls. For example:

    PHP 5

    1. <?php
    2. $my_variable = myFunction($arg1, $arg2);
    3. if ($condition) {
    4. // statement
    5. }
    6. ?>

That's it! No more code spagetti from now on, you promise?

Snapshot

A gentle nudge in the direction of writing well-presented PHP code. Why is convention important? And why are developers so pendantic about spaces and braces? We discuss the benefits of coding to a standard, and what that standard might be for PHP.

Related Reading

Share

Articles

Who we are

Openknot is the web design agency of Rob Tuley. We specialise in creating visually clean, dynamic sites with PHP and MySQL.

Find out more

Find out what we do. Browse our previous work. Take a closer look at who we are. Enjoy our articles. We hope you'll see we are passionate about our work.

Get in touch

Want us to work for you? Have a question about what we do?