Automated PHP 5.3 compatibility testing for your (old) code

Update (Mar 5, 2012) : check here for the latest version, supporting PHP 5.4 as well.

Update (Dec 22, 2010) : code has seen some minor modifications to ensure compatibility with the latest PHP_CodeSniffer release (1.3.0RC1) – thanks to Sebastian Bergmann. Also updated the instructions below.

Note (Dec 22, 2010) : this compatibility test will also test all testable cases for 5.0, 5.1 and 5.2

So you or your team has built anywhere between 5 and 500 projects in PHP 4, 5.1 and 5.2 over the past 5 years. And now PHP 5.3 is there, offering a lot of very interesting features, including namespace support, late static binding (finally !), closures, nested exceptions and a bunch more (see the new feature list).

So naturally, you’d like to upgrade. But doing so might break some old code. Why ? Because of some backward incompatibilities :

  • New reserved keywords (goto, namespace)
  • Deprecated functions that will throw an error (the brand new E_DEPRECATED error in fact !)
  • Call-by-value on functions with by-reference parameters will now raise a fatal error
  • and again… many more (see the list)

So how do you ensure your code is PHP 5.3 ready ? Well, there’s a few options.

Option 1 : run your unit tests

You just knew I was going to say that, didn’t you ? Yes, unit tests are still the best way to test the inner working of your code. Although even 100% code coverage will not guarantee a bugfree system ofcourse (some bugs are by design, others by neglect, others…)

Option 2 : test your application

Seems logical, doesn’t it ? Install PHP 5.3 on a separate environment or on your test environment and test the entire application. Ofcourse there are issues for some :

  • Old projects often don’t have any budget allocated for this kind of tedious testing
  • Testing an old project is not easy if the original developers aren’t around anymore… so the testing is best done by the actual user… but you don’t want users to see how their application breaks “because of old code”
  • If you have a lot of projects, testing them one-by-one could take a while… maybe 5.4 will be out by then :p

Option 3 : automate your PHP 5.x compatibility tests

Although the first 2 options are really required to ensure your code is PHP 5.3 ready, using automated tests can get you a long way in detecting deprecated functions, unsupported extensions, etc.

Because I’m in charge of moving about 50 projects to PHP 5.3 in the next few weeks/months, I decided to make at least part of this tedious task a little smoother (and faster).

To use the system, all you need is PHP_CodeSniffer and a new sniff standard I created. You will see errors and warnings popping up if part of the code is not PHP 5.3 compatible.

What’s being tested

  • Deprecated functions
  • Deprecated php.ini directives set via ini_set() or retrieved via ini_get()
  • Deprecated assigning of the return value of new() by reference
  • Prohibited names in function name, class name, namespace name and constant name
  • Magic methods can no longer be private, protected or static
  • Removed, unsupported or deprecated extensions
  • All of the above is being tested for PHP 5.0, 5.1, 5.2 and 5.3 compatibility issues

How to download and install

~ > git clone git://github.com/wimg/PHP53Compat_CodeSniffer.git PHP53Compatibility

  • Copy the PHP53Compatibility directory to {your pear path}/PHP/CodeSniffer/Standards

How to run

Start PHP_CodeSniffer like this :

phpcs --standard=PHP53Compatibility <path-to-your-PHP-source-directory>

Sample output

FILE: C:\temp\bla.php
--------------------------------------------------------------------------------
 
FOUND 15 ERROR(S) AND 2 WARNING(S) AFFECTING 12 LINE(S)
--------------------------------------------------------------------------------
 
  4 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'goto' (since version 5.3)
  6 | ERROR   | Extension 'dbase' is not available in PHP 5.3 anymore
 12 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'const' (since version all)
 12 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'const' (since version all)
 12 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'const' (since version all)
 12 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'const' (since version all)
 12 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'const' (since version all)
 14 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'do' (since version all)
 16 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'goto' (since version 5.3)
 18 | ERROR   | Function name, class name, namespace name or constant name can
    |         | not be reserved keyword 'namespace' (since version 5.3)
 20 | ERROR   | Assigning the return value of new by reference is deprecated in
    |         | PHP 5.3
 31 | ERROR   | Magic methods must be public (since PHP 5.3) !
 31 | ERROR   | Magic methods can not be static (since PHP 5.3) !
 36 | ERROR   | Extension 'mhash' is not available in PHP 5.3 - use the 'hash'
    |         | extension instead
 42 | ERROR   | Extension 'msql' is not available in PHP 5.3 anymore
 48 | WARNING | The use of function magic_quotes_runtime() is discouraged
 50 | WARNING | The use of ini directive 'safe_mode' is discouraged
--------------------------------------------------------------------------------

Some important notes about the system

  • The system checks for deprecated functions, new reserved keywords and other changes from PHP 5.0 to 5.3. However, it doesn’t check for every incompatibility, only a subset that was easily testable using PHP_CodeSniffer. So you still need to check your application manually to see if it runs properly. However, at least part of the job has been made a little easier.
  • You need to run the tests on a system with PHP 5.3 installed (sounds logical, but seemed like a good idea to mention it…)
  • The tests were written on a sunny afternoon with lots of interruptions, so they’re all but perfect. Please let me know if you find bugs, things missing or just want to flame me ;-)

As always, no guarantees that it will do the job… but if you feel it’s of use to you, let me know in the comments !

ShareFlattr the authorTweet about this on TwitterShare on FacebookShare on Google+Share on LinkedIn

flattr this!

Tags: , , , ,

26 Responses to “Automated PHP 5.3 compatibility testing for your (old) code”

  1. [...] This post was mentioned on Twitter by Greg Sherwood, Wim Godden. Wim Godden said: While waiting for news on #zendcon : new blog post : Automated PHP 5.3 compatibility testing : http://bit.ly/bn9OiQ #php53 #lesstediouswork [...]

  2. Wernight says:

    I wish this will soon be merged in phpcs core. It’s pretty much a must-have. False-positive are static analysis tools’ killer.

  3. mike says:

    I was just telling someone people should reuse existing PHP QA tools like PHPCS to detect keywords and other syntax things that may be deprecated in PHP 5.3.

    I was excited to see you did most of the footwork. However, it doesn’t work for me. It requires PHPCS version 1.2.2. Not the latest one. :) The latest one looks for ruleset.xml files inside of each Standards dir.

    So here’s the modified instructions:

    1) Make sure you are running PHP 5.3!
    2) Grab and unpack PHP_CodeSniffer version 1.2.2 from pear.php.net (or pear install it)
    3) cd /CodeSniffer/Standards (i.e. cd PHP_CodeSniffer-1.2.2/CodeSniffer/Standards)
    4) git clone git://github.com/wimg/PHP53Compat_CodeSniffer.git PHP53Compat
    5) run phpcs –standard=PHP53Compat

    (the _Sniffer on there messed it up, and the –standard needs to match the directory name, etc.)

    • wimg says:

      You’re absolutely right. Because 1.3.0 is still an alpha release, I decided to create the rules for the latest stable release.

      I just added the ruleset.xml and refactored the class names so they’re now supported on 1.2.2 and 1.3.0-alpha1.

      Thanks for reminding me, cause I completely forgot ;-)

  4. [...] this new post to his blog today, Wim Godden looks at how you can use the PHPUnit unit testing framework to be [...]

  5. I have been thinking about doing exactly that for a long time. My idea was not that bad after all. ;)

  6. [...] derUmstellung von PHP 5.2 auf PHP 5.3 lässt sich der Code mit einem Sniff für den PHP_CodeSniffer auf bekannte Problemstellen [...]

  7. Alberto says:

    Hi,

    I used your solution in my work and I wrote an script to run this solution in my blog http://blog.albertoviana.com/2011/09/28/how-to-automated-php-5-3-compatibility/ .

  8. Roystan says:

    I search high and low for such a script and you have it. Yahooo! but I have a problem. I’m not well verse in php and my few accounts are hosted in shared server using Cpanel 11. I tried to follow your steps in installing but stuck in installing. Basically I have downloaded and untar them both – PHP_CodeSniffer-1.3.3,tgz and wimg-PHP53Compat_CodeSniffer-v1.2.6-gbc750fc.tar.gz . But what next?

    In which directory do I put these files?
    Where and how to run this: phpcs –standard=PHP53Compatibility
    Is it in my Cpanel?

    Please help as my accounts are now “blank” when host upgrade from PHP 5.2 to 5.3.

    • wimg says:

      You will need to install the PEAR package PHP_CodeSniffer first. Then you need to untar the package in the PEAR/PHP/CodeSniffer/Standards directory. Then you should be able to run the command.
      It might be best to contact your hosting provider or even better to run the tests locally.

  9. Jenna Hall says:

    Thank you very much for this script. It’s very useful for legacy code!

  10. chuenniger says:

    Thank you for the script!

    Great :)

  11. Ian Tresman says:

    Many of us are PHP-challenged, and it is not trivial to install such scripts, especially on Windows. It would be very nice to have an online version available, where we could simply upload a PHP file for checking. Please :-)

    • wimg says:

      Honestly, PHP_CodeSniffer isn’t hard to install. And to be fair, if you’re PHP-challenged… shouldn’t you let someone else write PHP for you ? ;-)

  12. lizzy says:

    Hi,
    thanks for your script. I can installed on windows with xampp, it seems to work fine – but:
    if i use
    –standard=PHP53Compatibility
    then i have this error:
    the php53Compatibility coding standard ist not installed.

    download by http://pear.php.net/package/PHP_CodeSniffer/download 1.4.2
    or was the file downloaded directly when i install via pear ..?
    I also find no folder for Codesniffer in my PEAR folder ..
    whats wrong?
    Please excuse my bad english…

  13. Natan Vermeersch says:

    Hey Wim,

    your sample output says:

    “Assigning the return value of new by reference is deprecated in PHP 5.3″

    this is indicated as an “ERROR”

    I suppose this must be a “WARNING” ??

  14. Pano says:

    Hey, just a heads up, the git link that you have is broken, I imagine the right one is the one in https://github.com/wimg/PHPCompatibility

    • wimg says:

      True. As mentioned at the top of the post, there’s a new Codesniffer ruleset. If you follow the link at the top of the post, you’ll get there.

  15. Anthony says:

    My hosting company upgraded to PHP 5.3 on the server and now getting a lot of errors on my software. Is there an easy way (FREE or inespensive) to correct the code on my software so it will be compatible with PHP5.4 and 5.5?

    Anthony (813) 431-8519

Leave a Reply