Installing XHProf for MAMP and PHP 5.2 on Mac OS 10.6 (Snow Leopard)

About Lion (10.7) Compatibility: The vast majority of this guide works as-is with MAMP 2.0 under OS X 10.7. The most significant changes are the file paths, which can be found by running the "locate" command as detailed below. Look for the notes below on where the setup does differ.

Exciting discussions have been bubbling up in the Drupal community about using XHProf to analyze the performance of PHP code. Developed by Facebook and released as open source, XHProf is a PHP extension that can track the progress of any PHP application (Drupal included) and generate detailed analytics that help developers isolate performance hot spots.

Unfortunately, if you're using a Mac for PHP development and rely on the MAMP package to manage your sites, installing PHP extensions can be a real pain. A "stab yourself in the eye" kind of pain. In this article, I'll walk you through the process of installing and building XHProf, while avoiding some of the common pitfalls that occur when compiling extensions for MAMP.

MAMP Component Source

The first step to adding an extension to MAMP is downloading the source code for the various components that come with MAMP, and ensuring that you grab the versions that match the MAMP installation you're already using. To find out what version of MAMP you're currently running, launch the appplication and then click 'About MAMP' or 'About MAMP PRO' in the menu bar. The absolute latest version at the time of this writing is 1.9.6.1, but I'm running MAMP 1.9.

To grab the actual downloadable source, visit the SourceForge page for MAMP, and locate the component source that matches your version. To do that click on 'Files', then 'mamp', then to click the link for your version. On the resulting page, you should see a link to a component source download. In my case it was titled MAMP_components_1.9.dmg. Let's go ahead and download that bad boy! And… wait… and wait some more. It's about 120MB, and SourceForge is clocking in at 85KB/sec for me. How about for you?

ZZZZzzzzzzzzzzz…

"Anything we can do while we wait?"

Actually there is! Another reason that installing PHP extensions for MAMP can be so challenging is that Mac OS already comes with PHP installed, so sometimes the wires get crossed between the different PHP binary files. For this reason, I also like to ensure that by default I am using my preferred MAMP version of the PHP binaries.

To do this, pop open a Terminal window and use the which command to see where these binaries are found. If you're like me, you probably see something like this:

These files are the PHP binaries that come already installed on Mac OS. What I'd like to do is have it look to the MAMP versions of these binaries, so that we can be sure XHProf gets installed for the right version of PHP.

Well, where do the MAMP versions of these binaries reside? Good question. I always forget, so instead I just use locate to find where the files are. pecl is a file that isn't as frequent as php, so I'll search for that.

Since I do most of my work using PHP 5.2, I need to make sure that the binaries inside of Applications/MAMP/bin/php5.2/bin are used. The way that I'll do this is by symlinking all the binaries in there. I don't want to actually overwrite the files that are in /usr/bin, as Mac OS will happily overwrite them later, forcing me to do this all over again. Instead, I'll symlink them into /usr/local/bin.

To fix this, I'll pop open my .bash_profile file inside my user's home directory and be sure that /usr/local/bin is before /usr/bin. Keep in mind, you'll probably want to make this permanent by editing your .bash_profile as well, but for the sake of brevity, let's just change this variable for this session.

Yay! which php now shows /usr/local/bin/php as my php binary, and php -i confirms that we are using PHP 5.2. Phew, that was kind of a mess, huh? Thankfully things only get worse from here. Errr... Scratch that. Reverse it.

"Hey my component source download is done!"

Great! So, now that we have the component source for our version of MAMP downloaded, let's pop it open and figure out what needs to be done. We'll cd into the directory and move some files into our MAMP installation.

Now that we've got the PHP source, we need to configure it for our machine. This is a pretty simple step:

cd /Applications/MAMP/bin/php5.2/include/php
./configure

Voilà!

"Can we install XHProf yet?"

Ok, ok! Let's install XHProf. But, I'm warning you, it's not as simple as sudo pecl install xhprof. This is due mostly to some issues with how PECL expects the package tree to be formed.

To get around this, we'll first need to download XHProf directly. To do this, head over to the PECL XHProf project page and see what the latest version of XHProf is. For me, it shows XHProf 0.9.2.

Now that we know the version of XHProf, we can go ahead and download the source. Normally I'd download this into /tmp, but in the case of XHProf, we want to keep the source handy, as it includes web scripts used to display the metrics. For this reason, I'm instead going to download the XHProf source into my MAMP web root. For me, I have this at ~/Sites, but you may have it some other place, like /Applications/MAMP/htdocs. Regardless of where your web root is, just cd into that directory.

Ok, now that we've gotten XHProf downloaded, we need to get it ready for compiling. To do this, we need to set up some environment variables. The reason for this is that MAMP PHP is compiled as a 32 bit application, but if we don't tell that to XHProf when we configure it, it will get compiled as 64 bit. With MAMP 2 on OS X 10.7, this step isn't required, as MAMP is a universal binary. It's likely not required with MAMP 2 on OS X 10.6, though we haven't tested that combination ourselves.

Ok, the somewhat icky part is out of the way, now let's move forward and configure XHProf! Before we run these commands, though, let's just double check to make sure phpize and php-config are set up properly.

$ which phpize
/usr/bin/phpize

Whoops! What happened there? There was a small step that I missed above, after we symlinked. Some quick debugging shows me that the PHP binaries were not set up as executable. Note: if you didn't run into this, that means you followed my instructions above perfectly. 2 gold stars, my friend.

If you see a API version starting with 2009 above, you probably did something wrong (unless you're using PHP 5.3 on MAMP 2). Retrace your steps, and ensure you are using MAMP's phpize. Let's move on by configuring and installing.

./configure
make
sudo make install

After running all that, if you see something similar to "Installing shared extensions: /Applications/MAMP/bin/php5.2/lib/php/extensions/no-debug-non-zts-20060613/", you should be good! If not, try making some burnt offerings on your Steve Jobs alter... Or just leave a comment.

"Yay! I think... Now what?"

Ok, now we need to actually let PHP know to use our new extension we just created. To do this we need to edit php.ini. If you have MAMP Pro, you can open it up, click 'File', then 'Edit Template' and then select the appropriate version of PHP. If not, just search for php.ini:

The xhprof.output_dir can be any directory you like, and you may want it to live inside /tmp instead. You might need to create the directory before it actually works, though, so just keep that in mind.

If you do have MAMP Pro, you'll also want to make the same change in /Applications/MAMP/conf/php5.2/php.ini. This is the php.ini that is used for command line PHP, which we are about to use to see if XHProf is working. Taking this extra step will also allow you to use XHProf inside of Drush scripts, which is actually pretty nifty!

Once you've edited the php.ini files, let's run a little test to see if XHProf is getting loaded properly.

$ php -i | grep xhprof
xhprof => 0.9.2

If you see that 0.9.2 in there, you're good to go.

"Can I go home now?"

That's it! Phew, that was rough, huh? If your brain is feeling a bit like cottage cheese right now, don't worry—the hard part is over. We now have XHProf compiled for the version of PHP that came with MAMP. Stay tuned for a follow up entry on how to get this wired up to work with Devel module, and how we can use this new tool to help isolate performance bottlenecks and other issues.

About the author, James Sansbury

An experienced Drupal developer and architect himself, James manages Lullabot's back-end development team. He lives near Atlanta, GA and enjoys fishing, hiking, and camping.