HomePHP Page 5 - PHP Application Development Part One
PHP coding conventions - PHP
Settling for the "quick and dirty" solution often costs far more time than it saves. This is as true of PHP coding practices as anything else. In this first article in the series, you will learn practices that will save you time and headaches in the long run, and help you write better PHP code.
The last topic of this article deals with fundamental PHP coding conventions. While it is never appropriate to prematurely optimize code, there is a set of basic rules to adhere to when coding PHP to maximize the efficiency of your code at the lowest level. In many applications these tips may never be an issue because the website may never be busy enough to require finely optimized code, however this does not mean we should write sloppy, inefficient PHP. Furthermore, there are many times when every microsecond of performance makes a difference, and when you are working on this type of mission critical project it is important that you have already trained yourself to write code that adheres to conventions stylistically as well as linguistically.
One of the simplest of these fundamental rules is the appropriate use of single quotes (‘) and double quotes (“). PHP will parse everything between a pair of double quotes searching for variables or nested expressions, whereas PHP treats anything inside of single quotes as a literal string. Consider the following example.
<?php $typeOfString = “double quoted”; $myString = “This is a \”$typeOfString\” string<br />\n”; ?>
Not only is this difficult to read, because the variable is tucked into a string literal, it is inefficient. While it may only take a miniscule amount of time for the parser to deal with these strings, in a larger context with a great deal of string processing, the extra parse time can have a noticeable effect on performance. Instead, strings should be coded like the following example.
<?php $typeOfString = ‘single quoted’; $myString = ‘This is a “’.$typeOfString.’” string<br />’.”\n”; ?>
In this example, all string literals are enclosed in single quotes. The only double quoted string here is the newline escape sequence “\n” which will not be correctly interpreted by PHP in single quotes. The parser simply has to concatenate two string literals with a variable and an escape sequence here, meaning very little text is actually processed.
While the next point does not apply in PHP 5, objects in PHP 4 are by default passed by value, not by reference, which can lead to inefficiencies throughout code. Objects in PHP 4 should be assigned initially by reference and then passed by reference as often as possible to minimize needless object creation. Consider the difference between the following examples.
<?php $obj = new MyObject(); callSomeFunction($obj); ?>
In this example, PHP will first create an instance of the “MyObject” class, then copy it into the “$obj” variable. When we execute “callSomeFunction($obj)”, the object is again copied and sent to the function for local use. If “MyObject” is a substantial class containing a lot of data, this is a big problem. More importantly, there are really not any common situations where an object should be passed by value – with that in mind consider the following example.
In this example PHP creates the “MyObject” instance and assigns it to “$obj” by reference instead of by value, meaning no additional copy is created, simply a pointer to a location in memory. This is repeated in the call to “callSomeFunction($obj)” where we pass a reference to the original object rather than a copy. This allows the function to do meaningful work with the object and even change its state without having to return a copy of the object to the calling code – it can simply modify the object reference, which is effectively modifying the original object itself.
One of the major points of concern I have observed in PHP applications is the needless coding of objects and functions to perform tasks that can already be performed by some function in PHP. This is most often the case with string, array and error handling functions. The only point I wish to make on this matter is that anyone working on a PHP application should be comfortable with using the manual. I frequently consult the manual even after more than three years of developing PHP applications full time. Always be sure to check the manual for functions that can satisfy your needs – using built in functions is significantly faster than using user functions.
On this point, it is important to choose the proper control structures for a job – knowing which structures are faster in which situations comes from experience and research. It is also important to use control structures in the most efficient way possible. In a loop, for example, minimizing the recalculation of values that do not change during execution of the structure is a good way to maintain efficiency. Consider the following examples.
Here the number of elements in “$myArray” is saved when we initialize our incrementor, and never recalculated. Small matters like this, compounded with many other seemingly small matters discussed in this article, when tended to properly, can lead to code that scales smoothly without refactoring.
On to the next point – never use register_globals. Not only is it a security risk, it strips your data of context, forcing your code to make assumptions about the source and the trustworthiness of the data. Take advantage of the superglobal variables and use the “$GLOBALS” variable sparingly – constants are typically more suitable for data that needs to be globally accessible. Furthermore, avoid the use of the “global” statement – it creates inflexible, monolithic code that can often lead developers on a wild goose chase in search of the initial meaning of the variables being declared as global. If you have objects that need to be accessed in a global context, simply pass the object as a reference to any code that depends on it. This makes intent clear and never leaves you or other developers wondering where information comes from.
The last fundamental efficiency issue that I would like to bring up is avoiding excessive use of included files. While I completely advocate and encourage organization of code and minimizing duplication, it is also important to avoid going overboard with modularizing your code. If you do need highly modular code and have code spread across a great deal of include files, be sure that the actual Web scripts that depend on those files only include the files they need. If you have fifty class files and a script only needs two of them, it should not include them all. In very small applications, and even in some medium sized applications, there is no performance hit for this, depending on traffic and the server hardware.
Excessive use of include files leads to excessive disk IO, a fact that can hinder performance at exponential rates as traffic on a Web application increases. Do not be afraid to modularize your code because of this; simply be judicious and avoid wasteful file includes. One way to help with this is to use the “include_once” and “require_once” statements to avoid duplicate file inclusions. Another is to allow include files to include dependent files on their own, effectively chaining include files together. This allows your main script to include a class file directly and allows the class file to include any other files that it depends on itself, keeping the class functionality independent of the parent script. This helps a great deal in maintenance and avoiding confusion about what files must be included to use which pieces of functionality.