Debug PHP with Vagrant using Xdebug and Sublime Text

Vagrant and Xdebug
Standard

Following hot on the trail of my recent post about getting started with Vagrant, I figured I would let you know how you can debug the PHP that is running on your Vagrant box with Xdebug, using your host IDE (in this case, everybody’s favourite editor Sublime Text).

Xdebug will allow you to place breakpoints in your PHP code, and step through the code, letting you see how your variables are set. Gone are the days where you have to dump variables to screen to see what they are set as.

We are going to do a little bit of command line and bash scripting, but as always, I am going to explain what all those scary commands mean (and hey, if you still don’t get it, that is what copy and paste is for right?).

In this guide we are going to:

  • Edit our Vagrant provision file (I set this up in the previous tutorial) to automatically install and configure Xdebug
  • Setup Sublime Text to work with Xdebug on Vagrant
  • Install an extension for Chrome that makes working with Xdebug easier.

It is worth noting that I am using a Mac OSX, so my examples will be targeted towards that particular system. I’m also using iTerm 2 as my terminal program, and I am using Sublime Text 3 beta.

Installing Xdebug with Vagrant

If you remember the previous tutorial, we installed everything we needed for our Vagrant LAMP stack with the following line in our Shell provisioning file:

This bit of code installs MySQL, Apache and PHP.

To install Xdebug, we need to install something called PEAR, which stands for PHP Extension and Application Repository. In other words it will let us install handy little extras for PHP.

As well as PEAR, we are also going to install the php5-dev package, which will let us add modules to PHP, and the build-essential package, which will let us run the commands required to build the Xdebug package, in particular the ‘make‘ command, which is used to compile code.

Let’s add them into our provisioning file so they get installed in Vagrant:

We can now install Xdebug with the command pecl install xdebug. The command pecl got installed with PEAR, and stands for PHP Extension Community Library. We also need somewhere to install our Xdebug logs, so lets do that with the following block of code placed after we install our packages:

This code makes a directory called xdebug in the /var/log/ folder. Is then changes the owner of that directory (chown) to be www-data so that Apache can write to it. Finally we install Xdebug as a super user using sudo (super user do), with the line sudo pecl install xdebug.

There we go, Xdebug will be installed the next time we provision our Vagrant box. Are we done here? Not quite, we need to configure PHP to use it.

Configuring PHP to use Xdebug

In order to get PHP to work with Xdebug, we need to tinker with the php.ini file, that comes installed with PHP. I will show you how to do that in just a moment, but first let me explain what we need to add to that file:

The first thing you will notice is we haven’t put a path for the zend_extension parameter (denoted by the [enter path here] place holder). This is because this path is variable (it changes from instance to instance), but it should look a little something like /usr/lib/php5/20090626+lfs/xdebug.so.

Fortunately for us, we can find this path with the shell command find / -name 'xdebug.so' 2> /dev/null. So we will, when we put it in our script in a little bit.

That path, tells PHP where our Xdebug install is.

I will not go into the above script in detail, but the important parts are that we are telling PHP that we are enabling remote debugging (so we can get at it from our hosts instance of Sublime Text), that it should do this on port 9000, and our remote IDE environment (Sublime Text) is available on port 10.0.2.2.

Automating the configuration of php.ini

Like I said, we are going to make Vagrant do all of this configuration for us. We will do this with the following chunk of code:

That block of code does exactly what we said to the php.ini file, with the exception that echo '[code goes here]' >> /etc/php5/apache2/php.ini writes the line (as a new line) to the php.ini file, which in this instance is located at /etc/php5/apache2/php.ini.

The only other point you will notice, is that we automatically figure out where our xdebug.so file is by adding the command find / -name 'xdebug.so' 2> /dev/null into our script here:

By wrapping it in the $(...) we are telling our script to run the command, not just echo it.

Before we are finished though, we don’t want to start writing to php.ini every time we provision our Vagrant install (using vagrant provision).

In our provision.sh we have a handy if statement that checks to see if we have made /var/www/ into a symbolic link or not with the following code (if you don’t know what I’m talking about, have a look at the previous tutorial):

We are only going to do that once, so lets put the code that writes to php.ini into that.

Our finished provisioning script

Here is our final provision.sh file that now installs Xdebug and configures the php.ini:

Now to get it all up and running, navigate to the root of your project (for example: cd path/to/your/project) and enter the following command:

Yup, that script installed WordPress too (and if you still don’t know what I’m talking about, have a look at the previous tutorial).

Configuring Sublime Text to use Xdebug

Firstly, if you haven’t already, go ahead and install Sublime Text, with the handy installer (phew, a bit of a rest from command line).

Sublime Text has a really handy feature, where you can run commands with the shift + cmd + p key combination. This will fire up a prompt box, and as you start typing, you will notice lots of commands that you can take advance of.  One of these will let you install plugins, or at least it would, if we had installed the package that lets us do that yet (Package Control), so let’s go and do that first.

Go ahead and install Package Control by using their handy guide.

Once you have done this you can now install the Xdebug Client for Sublime Text by hitting  the shift + cmd + p key combination and by starting to type install.

Installing a package using Package Control

Installing a package using Package Control

Hit the enter key and you will be given another prompt. This time start typing xdebug to be presented with the following screen:

Installing the Xdebug Client

Installing the Xdebug Client

Hit enter again, and you will have installed the Xdebug Client for Sublime Text (you may have to restart Sublime Text for the changes to kick in).

We should now have a new addition to our context menu under Tools we should now have an options menu for Xdebug.

Xdebug context menu

Xdebug context menu

Configuring the Xdebug Client

Next up, we need to make sure that our Xdebug Client is configured correctly. There are a few ways to do this, but as we potentially will have many instances of Vagrant running, it is probably best to do the configuration on a per-project basis.

So let’s create a project in Sublime Text by using the contextual menu to go to Project > Add Folder to Project…

Add Folder to Project context menu

Add Folder to Project context menu

Once you have done this your Sublime Text window will now have a sidebar that contains all of the project files.

The project sidebar

The project sidebar

We still haven’t made a project though. To do this go to Project > Save Project As… and save the project file in the root of your project folder.

You should now have a file with an extension of .sublime.project. Open this up.

Your project folder

Your project folder

Here is where we are going to make our changes.

Here we have a file that seems to consist of JSON, it looks like the following:

We are going to add the following code into this:

Well, almost that exact code, you will notice the [your user name] and [path to your project] holding text. Change these so they match your solution. For example they might be configured something like /Users/mattwatson/dev/my-project-name/public. I use my own project path in the full example below, you will need to change this.

Putting it all together we should have a file that looks similar to the following:

Save the file, and open it again using Sublime Text (by double clicking on it in your finder). It should launch the project.

Testing it works

If you have read the previous tutorial, you should know that you can now hit http://localhost:8080 and view the start page of the WordPress installer, so go ahead and do that.

WordPress installer screen

WordPress installer screen

Nothing should happen just yet, because we haven’t yet done two things:

  • Started debugging
  • Added any breakpoints to our project

In Sublime Text go ahead and navigate to /public/index.php go down to the first big of PHP code you can see on that page (in this case line 14). You can now either right click (or option + click if that is your kind of thing, you Mac puritan you) to view the contextual menu that will let you add a breakpoint.

Inserting a breakpoint

Inserting a breakpoint

To insert a breakpoint I prefer to hit command + F8 though (well, because I’m using a MacBook I have to hit function + command + F8, otherwise I will just turn the volume down or something).

Anyway, when you have done that, you should end up with a breakpoint on line 14.

File with breakpoint

File with breakpoint

We can now either in Sublime Text go to Tools > Xdebug > Start Debugging, or hit command + F9 to fire up our debugger.

Running the debugger

Running the debugger

You will notice the new panels in Sublime Text that are going to present us with our debug information. You will notice that the Xdebug Breakpoint window is telling us about that breakpoint we placed on line 14.

In your browser go to http://localhost:8080/?XDEBUG_SESSION_START=sublime.xdebug that query string tells Sublime that we are ready to start debugging. We can remove that string after we have run it once, as it gets stored in a session.

If we look at Sublime Text now, you will notice that that breakpoint we added is highlighted yellow. That is because the PHP has paused where our breakpoint is.

Breakpoint hit

Breakpoint hit

If you look at the Xdebug Context window you can now see all the variables that have defined so far.

If you use your arrow keys, you can move your cursor over these arrays, and view their contents the debug window.

Debug window

Debug window

There you go, you now can debug your WordPress code using Sublime Text.

Easier debugging with the Chrome Extension

One last thing, that query string that we have to enter (http://localhost:8080/?XDEBUG_SESSION_START=sublime.xdebug) is a little awkward, don’t you think?

If you are using Chrome then there is an extension you can install to tidy that up a little bit.

In the Chrome Web Store, search for ‘Xdebug‘. You should find an extensions called ‘Xdebug helper‘. Go ahead and install this.

Xdebug helper

Xdebug helper

I will not go into the details of how to install and configure this, as you can find it all right there in the Google store. But essentially this extensions will give you a little ‘bug’ in your browser bar that you can click to enable debugging.

Xdebug helper in browser

Xdebug helper in browser

This sets the session, so you don’t have to muck about with all of that query string nonsense.

Matt Watson

Technical Lead at Make Do
Matt Watson is the co-founder and technical lead of WordPress agency Make Do. Matt loves writing and learning about code, and considers himself lucky to be doing what he loves for a living. Find out more about Matt, or get in touch to hire Matt for your project.

4 thoughts on “Debug PHP with Vagrant using Xdebug and Sublime Text

  1. Hi,

    There is more to do if you want to be able to use xdebug in CLI (Command Line Interface):

    1) As you inserrted the xdebug config in php.ini, you have to do the same in the cli php.ini:
    /etc/php5/cli/php.ini (and restart apache)
    2) export variables:
    export PHP_IDE_CONFIG="serverName=sandbox.yourdomain.com" (to replace with your local url for dev)
    export XDEBUG_CONFIG="remote_host=10.0.2.2 idekey=sublime.xdebug"
    php -f /var/www/vhosts/yourdomain.com/current/tools/mytool.php

    Thanks to http://aaronbonner.io/post/35630984902/remote-cli-xdebugging-with-phpunit you might be able to use:
    PHP_IDE_CONFIG='serverName=sandbox.yourdomain.com' php -dxdebug.remote_host=10.0.2.2 -f /var/www/vhosts/yourdomain.com/current/tools/mytool.php

  2. Elvis

    Thanks for the well done writeup! I am debugging remotely and had everything in place except the path_mapping setting. After adding that I am debugging fine in sublime.

Leave a Reply