Friday, October 10, 2008

PHP Profiling with webgrind

I've returned from a blogging hiatus. Read - not feeling so lazy today. Profiling PHP scripts has always been one of those things I know that should be done, but there never seemed to be time to set it up. Today I put off a lot of work to focus on getting profiling working in my dev setup. The environment consists of OS X 10.4, PHP 5.1.6, Apache 2.2.4, Xdebug 2.0.3 and webgrind.

First thing's first - webgrind requires the json PHP extension to be enabled to work. As of PHP 5.2.0 json is enabled by default, and if you happen to be so fortunate as to be running that version or later your setup tasks are reduced significantly. However I'm running PHP 5.1.6 because that's the setup in the production environment I get paid for. Someday I plan to have multiple PHP versions running on different apache ports, but not today. This means the json extension has to be installed and configured in PHP manually.

Now, I spend the later part of the day getting json working in my MAMP setup and tried so many different configuration options to get it working that I've lost track. Let me just give you some pointers if it's still not working for you after you do a

pecl install json

on the command line.

Check your path to php, phpize and php-config. Make sure if you issue a phpize command, the right version of phpize is going to execute. I had a conflict because OS X comes with PHP 4.4.8 installed at /usr/bin/php, and I had compiled and installed PHP 5.1.6 at /usr/local/bin/php. However /usr/bin was set in my path and /usr/local/bin was not. So unless you want to specifly the absolute path to php everytime, make a link from /usr/bin/local/php to /usr/bin/php (same for the other PHP executables).

Check that the json extension is installed by the command:
php -m

You will see output similar to:
[PHP Modules]
bz2
ctype
curl
date
dom
gd
hash
iconv
json
libxml
mbstring
mysql
openssl
pcre
PDO
posix
Reflection
session
SimpleXML
soap
SPL
standard
tokenizer
wddx
xdebug
xml
xmlreader
xmlwriter
xsl
zlib

[Zend Modules]
Xdebug


If it's not listed it's not installed. Alternatively you can load a page on your localhost that calls phpinfo() and see if json is listed as one of the extensions.

Check php.ini. There should be a line

extension=json.so

The json.so file should be located in the directory that the command:
php-conf --extension-dir
shows.

You also have to tell Xdebug to profile. Add these lines to php.ini if not present:

xdebug.profiler_enable=1
xdebug.profiler_enable_trigger=1

profiler_enable_trigger allows you to instruct Xdebug to profile the page when you add xdebugprofile=1 to the query string of the URL.

Restart apache after making changes to php.ini.

By default Xdebug will output profiling information in files named like cachegrind.out.

webgrind parses these cachegrind.out files into human-readable performance info. To install webgrind download it here http://code.google.com/p/webgrind/ and uncompress it into your apache htdocs directory (i.e. http:/localhost/webgrind/). The initial view should look like this:




Select one of the cachegrind files from the selection list and click the update button. You should get some pretty performance statistics similar to this:







Congratulations if you get this far. You've fought the good fight, pecl be damned. There is essentially no documentation for webgrind, so your are kind of on your own as to what to do from here. Play with the interface for a few minutes though and it will start to make sense. Hopefully you can find some code that could be improved, and you can be a hero.


Useful links:
webgrind http://code.google.com/p/webgrind/
Xdebug http://www.xdebug.org/
PECL http://pecl.php.net/

Webgrind: A Web Frontend for Xdebug
http://jokke.dk/blog/2008/04/webgrind_a_web_frontend_for_xdebug

No comments: