Your browser may have trouble rendering this page. See supported browsers for more information.

|<<>>|210 of 274 Show listMobile Mode

Debugging PHP

Published by marco on

PHP is a programming language like any other; like any other, it’s possible to construct a bug complex enough that it can only reasonably be solved with a debugger. Granted, most PHP code is quite simple and limited to single pages with single include files and a limited library or framework. However, the advent of PHP5 has ushered in more than one team with the courage to build a full-fledged web framework. You would think that the state of PHP development had concordantly improved to the point that debugging scripts—on a local web server, at the very least—would be a no-brainer.

You’d be surprised.

The developer of the earthli WebCore[1] was courageous enough to attempt building a framework with PHP3. Since debuggers for PHP at that time (circa 1999) weren’t on anyone’s radar, PHP developers made do with the vaunted echo and print commands to simulate debugging. The WebCore quickly acquired a Javascript-based logger to which logging commands were written. Such methods only take one so far: for more complexly nested and recursive code which is more object-oriented and has a much larger stack, a debugger is really needed.

The port from PHP3 to PHP4 was accomplished without a debugger, but that was long ago. When it came time to port from PHP4 to PHP4.3, things were much harder. It is highly likely that very few developers encountered issues during that upgrade but complex libraries with heavy use of references felt the pain. PHP4.3 was ostensibly a maintenance release but included fixes for reference handling that not only caused a tsunami of new warnings but also subtly changed how references were handled. This was a portent of things to come in the far greater problems encountered when porting from PHP4.3 to PHP5.

Developers that never developed for PHP4 will need a bit of background on how references used to work. Succintly put, PHP4 by default created copies on variable assignment rather than assigning references. In order to get a reference instead, a developer had to explicitly request one with a special operator (&). Larger libraries with many methods soon became littered with ampersands. Even better, forgetting just one in a parameter caused PHP to create a new copy of the passed object. Changes made to that object within that routine were applied to the copy and mysteriously disappeared when the method call returned.

This was obviously an untenable situation so PHP5—based on the Zend 2.0 engine—reversed the default. Under PHP5, assignments that previously created copies now created only references. Mix this with a large library with many such implicit copies hidden throughout the code and let the fun begin. Luckily, incredibly savvy developers who had read of this change enforced an iron discipline and limited these types of implicit copies to only a few, well-marked places.[2] Thus, the massive pain entailed in a port from PHP4 to PHP5 was somewhat ameliorated.

As you, dear reader, can imagine, the need for a debugger at this point became overwhelming. Let the search begin.

PHPEclipse was the default editor throughout the development of the earthli WebCore, so the first step was to check out what they had to offer. It turns out that the current version of PHPEclipse supports both the XDebug and DBG debuggers. The XDebug debugger was mentioned much more often in the forums, so it seemed like a good place to start.

Though you can debug PHP using only the executable (PHP.EXE), you’d have to configure that executable to include all the extensions and settings that are already configured with the local web server you’ve likely got installed. It’s not that it can’t be done, but that the most convenient way to debug would be to just execute the page on the web server you’re already using for testing. So, step one is to get the debugger extension loaded in your local server. If you’re developing on Windows[3], the WAMP server package is an excellent, highly-configurable solution. For porting from PHP4 to PHP5, it also offers the unique ability to change from one to the other within seconds. It has numerous addons corresponding to previous releases of Apache, MySql and PHP which seamlessly integrate with the main installation. What it does not have is an installer for configuring the appropriate version of either XDebug or DBG.

It seems that PHP developers don’t, in general, use debuggers.

As usual with such things online—that is, things that very few people do—instructions are available, but they must be pieced together from several different locations. XDebug was up first and was, after many false starts, loaded by the local server. Some things to watch out for:

  • Get the first version of the extension; the wrong version is simply not loaded and the error message is either entirely suppressed or so well-hidden in the log files as to be well-nigh undetectable.
  • Instructions to set the property “zend_extension” on Windows are wrong; you must use “zend_extension_ts” instead (the threaded version).
  • Make sure you are editing the correct PHP.INI file; in WAMP, this is the file located in the bin folder of the currently-loaded version of Apache.

Once you are rewarded with the XDebug extension in the phpinfo() page, you’re ready to start debugging. Following the instructions at the PHPEclipse wiki, though confusing, will get you stopping at a break point soon enough. Imagine that! A breakpoint in PHP! Press F6 to step over that line and … wait … and wait … listen to the fan on your laptop start. Apache is using 100% CPU or as close to it as it can. Wait several minutes for things to sort themselves, but they never do. Use the Task Manager to kill the offending instance of Apache and you simply transfer the problem to Eclipse, which begins using 100% CPU. Long story short, debugging with XDebug never got farther than this relatively low point. The inital breakpoint worked, but nothing else.

On to DBG.

To keep things a bit shorter, DBG never even stopped at the initial breakpoint, regardless of settings.

The open-source world, it seems, has nothing to offer on the PHP debugging front.

On to Zend.

Zend makes the scripting engine used by PHP. They make numerous tools for analysis as well as the Zend Developer Studio. It costs 399 Euros and brags about its debugging capabilities right on the home page. It has a 30-day trial. It all sounds so promising. One 330MB-download and installation later and you’ve got the Zend Studio up and running. Once you’ve configured a new project, you can set up a debug configuration, which comes with copious well-written help as well as a “Test Debugger” button right in the configuration window.

As before, you can run the debug session using a local executable, but the more useful setup is to run the debugger through the local web server. To do this, you need to install the Zend debugger extension, which has much better instructions in the Zend Studio help.

Long story short, 399 Euros buys you a working debugger for PHP that flawlessly debugged code in several files—including code located in “Include Paths”—and was exactly like any other debugging experience in Eclipse.

So, if you need to debug PHP, you can either take the cheap route and hope that the open-source solutions work for your code or you can take the plunge and use the Zend Studio—if you’re actually earning money with PHP development, choice (B) is the logical one.

This PHP developer, on the other hand, is going to get his port from PHP4 to PHP5 done in the next 30 days.


[1] You guessed it: yours truly.
[2] Obviously, that was sarcasm. Discipline goes a long way, but only goes so far.
[3] The WebCore is currently developed there because it’s the most powerful machine available—the PowerPC Mac Mini just doesn’t hold up with Eclipse-based IDEs