By now, we’ve all learned to love Vagrant and the development flexibility it provides. No matter the platform, you can easily have a development environment up and running in no time that’s not only stable, but also identical in every regard to the environment your colleagues, mentors or mentees use. But as the applications we’re developing reside inside a virtual machine, they’re a bit tricky to debug with Xdebug which is, by default, tuned for localhost.
Xdebug is a PHP extension which allows you to debug and profile your code, view detailed and readable stack traces when errors happen, and much more. For a detailed walkthrough, see Shameer’s post. If you’re completely unfamiliar with it, you would do well to first install it following the procedures below, and then refer to the post linked above for a breakdown of everything Xdebug can do for you and your apps.
In this tutorial, we’ll set up Xdebug with PHPStorm for Vagrant hosted PHP apps.
To prepare the environment, please install and boot Homestead.
Once it’s booted,
vagrant ssh into it, and install a sample Laravel app. You can do this by executing:
composer create-project laravel/laravel Laravel --prefer-dist
When you get the Laravel greeting screen, you’re good to go.
This step can be skipped. Homestead comes with Xdebug installed and enabled. You can see this by looking at phpinfo() after booting Homestead:
or by checking out the conf.d folders of PHP FPM and PHP CLI:
If you see
xdebug.ini in there, it’s loaded. If you’re using any other Vagrant box instead and xdebug isn’t present, refer to Shameer’s post for installation instructions.
To allow Xdebug to be used remotely, we need to alter the
ini file and give it some parameters that are off by default. Homestead’s default
xdebug.ini file (found in
/etc/php5/mods-available) originally only contains the directive that tells PHP to enable it, but nothing else:
Under that line, add the following options:
xdebug.remote_enable = on
xdebug.remote_connect_back = on
xdebug.idekey = "vagrant"
Close the file and restart php-fpm:
sudo service php5-fpm restart. That’s all we need to configure on Xdebug’s end.
Configuring PHPStorm – Servers
PHPStorm needs a bit of configuration, too. First, use it to open the directory of the Laravel app we created in step 1:
Then, go to project settings and under PHP -> Servers add a new one. Give it port 8000, the name of your choice, and under host, put the name of your site’s virtual host (default:
homestead.app). Then, use Path Mappings to map paths so that the location of your codebase on the host machine corresponds to the location on the VM. Do the same for the
public subfolder. Basically, transplant the
folders block from
Homestead.yaml to this window. Follow my example:
Configuring PHPStorm – Debug Configuration
To run the debugger on an app, we need to create a debug environment. Go into
Run -> Edit Configurations. In there, create a new configuration for “PHP Web Application”:
Apply the new settings and close the configuration.
That’s all there is to setting it up. Let’s see if it works as expected.
app/routes.php, alter the home route’s closure so that it looks like the code below:
$a = [1, 2, 3, 4, 5];
Then, put a breakpoint next to each line of the closure that does something, like so:
Let’s test these breakpoints. If you have the app open in your browser, close that tab now, otherwise PHPStorm won’t be able to re-run it. Then, go to
Run -> Debug and run your predefined debug configuration. A new tab should launch and immediately return you to PHPStorm with an output similar to this one:
The left frame lists the stacktrace – the files the request already went through – and stops at
routes.php, our file. You’ll notice in the right panel that only the superglobals are declared – no other variables are present at this time. Clicking the Resume button moves on to the next breakpoint and produces the following output:
$a variable is there now. Also notice you can expand it to see what it contains. Clicking the Resume button once more produces a slightly different output:
$a array has one less element due to the
array_pop operation we performed. This proves our breakpoints work as intended, and Xdebug has been successfully set up.
Despite initial impressions, Xdebug is very easy to install for use via Vagrant when one knows what has to be done. These instructions are easily applicable to Xdebug’s integration into any other IDE as well, so feel free to adapt them as you see fit – only the PHPStorm sections likely need changing.
Do you debug through the VM layer? Are you using any other approaches? Have any problems we neglected to mention? Let us know!