Tag Archive for 'web development'

PHP Best Practices

Yesterday I attended the Ubuntu 8.04 Hardy Heron LTS Release Party event the folks from Ubuntu Peru and Linurp organized here in Lima at Universidad Ricardo Palma. Nice talks on Ubuntu, KDE, GNOME, Drupal and PHP among some other stuff. I particularly liked the talk by the good old Jesus Castagnetto of PEAR and Professional PHP Programming fame. His slides (spanish) are posted at his site. My summary including bits i’ve been adding follows:

  • PHP is an easy language to pick up & learn but it’s a bit tricky to master
  • During the development phase of your project set the error_reporting value of php.ini to E_STRICT in order to get all sort of errors
  • Please set an error log and read it! You are going to need it to monitor your application when it’s deployed for production. Don’t forget to stop displaying errors to the end user in production sites. If you do, chances are you’re disclosing very useful information for an attacker trying to take control of your site or shutting it down.
  • If you’re using clean urls (and you should!) and not using the .php extension for your pages you don’t need to disclose that you’re site is running PHP. Setting the expose_php value to zero in php.ini might be a good idea.
  • Please get rid of code (yours or written by someone else) that depends on registers_globals = On. This configuration option won’t even exists when PHP 6 is released. Having PHP or your own code create global variables automagically from data sent by the user is a major security threat. So please resit the temptation of using it.
  • Please stop using magic quotes. Today they’re not a good idea. Actually they never were a good idea and will be depracated in PHP 6. As the programmer you’re responsible for adding quotes properly to any string that might need them.
  • Since version 5, PHP got exception handling. Please don’t abuse then exception handling mechanism by raising an exception at the minimal user-generated error. Raise an exception instead when a critical condition that is need for your program to continue working properly is not met, specially when you expect some other part of you code catching the exception and doing something about it.
  • Exceptions can consume considerable memory if your stack trace gets big. They are useful but not cheap.
  • Don’t debug you’re code using exclusively echoes, prints and var_dumps. You should be using a proper debugger instead. A very good one is XDebug. You get the extra advantages of getting a full stack trace and profiling capabilities.
  • No matter if you’re a solo coder or part of a team you need to follow coding standard in order to produce a consistent-looking codebase that can be easily read by anyone including yourself. PEAR has a good coding standard that has been proved in many PEAR contributions over a good few years. The Zend Framework provides you with a newer coding stardard (draft) that is also based on PEAR’s.
  • Documenting might be a bit boring but it’s critical for the success of your project over it’s lifetime. If you’re code is non-trivial you’re much better embedding good documentation in it that will help you in the first place to understand that are those lines of code doing when you come back to make changes. A quality tool for generating PHP documentation is phpDocumentor. It’s fast and can generate not just only API docs but tutorials by parsing your code if you learn to use it properly.
  • Please don’t reinvent the wheel. PHP has lots of useful functions that are implemented in C and will definitely run faster than you’re code. If you caught yourself reimplementing native functionality it’s your fault for not reading the manual and keep up with the changes and additions to PHP and it’s core extensions. Know your tool. Investing a bit of time in reading the manual will definitively pay off.

There are a few tips related to OOP with PHP, specially PHP 5:

  • Don’t over-engineer your code. PHP is not Java and in many circumstances you’ll be good using just a simple array which is a native data structure instead of a user defined class. Keep things simple.
  • Don’t use is_a() but instanceof() instead for checking if an object is a member of a class since is_a() was depracated as of PHP 5.

In order to improve the security of your code you can follow this guidelines:

  • You must ALWAYS initialize your variables, specially those involved in authentication, authorization and security checks.
  • Never ever trust your user on providing the right kind of input for your program to work properly. You must always validate that the user’s input is good for you
  • PHP has the filter and ctype extensions for validating user input. You can always use regular expressions for custom validations.

Finally, for performance improvements you have this recommendations available:

  • Don’t use double quotes in strings if there’s no variable interpolation or character escaping taking place. This saves a few miliseconds in each string so if you have many strings in your code and many visits in your website this alone can be a huge CPU and time saver.
  • In many places you can speed things a bit up by avoiding string concatenation. Just use a comma in echo to get the same output effect.
  • Prefix variable incrementation is a bit faster than postfix incrementation so if you’re not assigning the value of the variable before incrementing it you can easily gain a few extra milliseconds and consume less server CPU with this simple change so you ++$i instead of $i++ whenever you have the chance.
  • By all means you must avoid recreating the same dynamic content over and over again if you can be sure it won’t be changing. This is when content caching comes handy. Something as simple as reading a generated HTML chunk from a file in the filesystem instead of issuing again the database queries and/or performing the calculations needed to generate can be a big improvement. Generally cached content is not useful or trusty after some period of time has passed so put your attention in regenerating the cached content when it’s no longer valid.
  • Your own PHP can benefit a lot from using a caching mechanism so PHP doesn’t have to compile your code over and over again if it hasn’t change. Avoid wasting server CPU and response time. APC is a very good code caching solution for PHP and is mantained by Rasmus Lerdorf, the creator of PHP himself.
  • Don’t guess which parts of your code are the bottlenecks. Use a profiling tool instead. Remember XDebug includes a profiler.
  • Even if it’s not something you do at the PHP level you can always take advantage of a data compressing mechanism like Apache’s mod_gzip. Compressing content in both requests and replies is something that has been available in the HTTP specs for a while and you can easily save up to 80% of the bandwidth and response time.

I really think it’s a good idea to use lists like this as check-lists and use the techniques in your projects.