Vagrant, PHPStorm, Xdebug and PHP Software Collections

This topic has come up in a few places and at this point, I've memorized all the bits and bobs to get this stuff set up but I have to jar that memory every time someone wants help setting it up. Soooo...

Installing Xdebug

This assumes you've installed the PHP 5.6 Software Collection. Make sure to install devel packages as well (php56-php-devel).

# Change to root user.
$ sudo su

# Install PHP56 Devel Package if you haven't already.
$ yum install php56-php-devel

# Load version of PHP you want to install Xdebug for.
$ module load php56

# Install Xdebug via PECL
$ pecl install xdebug

# Pay attention to output and you'll see
# Installing '/opt/remi/php56/root/usr/lib64/php/modules/'
# install ok: channel://
# configuration option "php_ini" is not set to php.ini location
# You should add "zend_extension=/opt/remi/php56/root/usr/lib64/php/modules/" to php.ini

# Modify /opt/remi/php56/root/etc/php.ini to set zend_extension at bottom
# zend_extension=/opt/remi/php56/root/usr/lib64/php/modules/

# Verify Xdebug enabled.
$ php -v
PHP 5.6.30 (cli) (built: Jan 19 2017 07:08:58)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Xdebug v2.5.0, Copyright (c) 2002-2016, by Derick Rethans

If you use PHP 7, the same steps will apply. Just make sure the PHP70(71 or 72) software collections are installed, load which one you want as root and then pecl install xdebug.

Set up a remote interpreter in PHPStorm

  1. Open Preferences
  2. Navigate to "Languages & Frameworks > PHP"
  3. Click the ... next to “Interpreter”
  4. Add a new “Remote…” interpreter
  5. Select Vagrant and set “Vagrant Instance Folder” to your Vagrant project
  6. The “PHP interpreter path” should be /opt/remi/php56/root/bin/php or /usr/bin/php56
  7. Make sure you set up a path mapping for your shared folder (not the default /vagrant shared folder)
  8. Click okay and if you get the “input stream closed” Java IO exception, check out the section below. Otherwise, you’ve added the remote interpreter.

The infamous "inputstream is closed" or "pipe closed" error

So, this is (was?) a pain to Google around for. At the time of this writing, I found the solution pretty quickly, but I also knew pretty much exactly how to Google-fu it. If you get these error messages (on CentOS, at least) it has to do with the SFTP subsystem not being configured properly. So, we're going to open up our SSHD configuration and see that the subsystem is pointing at the wrong path, find the correct path and then fix the config and restart sshd.

  1. Open SSH config (vi /etc/sshd/sshd_config)
  2. See that Subsystem sftp /usr/lib/openssh/sftp-server points to a path that doesn't exist
  3. Install mlocate which allows us to find where software is on a system
  4. Run locate sftp-server which returns /usr/libexec/openssh/sftp-server
  5. Update sshd_config
  6. Restart sshd (systemctl restart sshd)
  7. Open PHPStorm preferences and go to your remote interpreter from before
  8. Click the refresh button and it should detect. If it doesn't, restart PHPStorm. Sometimes, it seems to cache previous SSH connection attempts and lie. Bad IDE. Bad.

At this point, should have a remote interpreter.

Make a test file

I used this one:


// Set a variable
$a = 1;
$b = 2;

// Do something we'll test the value of
$c = $a + $b;

// Conditionally echo it out
if ($c > 0) {
    echo "$a + $b = $c" . PHP_EOL;

You should be able to right click in the active editor window when you create this and click "Run". It should execute over SSH inside the IDE:

If that works, you can then set some breakpoints and execute a debug session.

  1. Set a breakpoint at $c = $a + $b and inside the if block
  2. Start a debug session in the IDE

Further work

This is enough to make sure the technical bits are working. You will want to create a run/debug configuration for your application rather than running individual files. At this point, you should also have a lot of the legwork done to set up PHPUnit in the IDE. That said, if you ever have a question, feel free to ping me on Twitter @mdwheele. More than happy to help.