Before you read: This post isn’t an Xdebug tutorial, the things I write are reflections. You may even come across certain booboo’s in this post, if you have any valuable insights, find a spelling/grammatical error feel free to let me know @DeBelserArne.

Synopsis

  1. You don’t need to loose your entire Xdebug install whenever you destroy your box
  2. You need to specify a session_name parameter when debugging through a web browser
  3. If you want to locally debug your PHPUnit tests with Xdebug you also need to install Xdebug on your host machine

Some Smalltalk

I have been out of the discovery phase of Laravel for a while now. One of the first things I encountered during this period is “testing”, and to be honest, Xdebug is key when testing.

As far as I understand, there are two main ways to debug a laravel application.

  1. You can do cumbersome browser testing with Laravel Dusk, slow, fragile, but if they work, very accurate.
  2. Or you can use the much faster browser simulating PHPUnit for your unit and feature tests.

Both of these methods each have their own purposes, but that’s a topic for another day. Let’s focus on Xdebug. For most of my practice days I have been using PHPUnit without Xdebug. If I ever needed to debug something I would use the dd(); helper.

Worth noting, at this time I had already been running Xdebug on my homestead installation for a few months. This was quite a hassle to set up, but I managed to get it working and it works great.

This brings me to the first “Thing I wish I knew”

  1. You don’t need to loose your entire Xdebug install whenever you destroy your box

When you’re installing Homestead, it will automatically create an after.sh file in your root directory.

This is a simple script file that runs every time you provision your vagrant box, in our case, our homestead box.

The interesting thing here is that we can actually leverage this file to install Xdebug we install Homestead.

Admit it, we’ve all did something terrible to our boxes which had us wipe the entire thing only to rebuild it a bit later.

If you paste the code below into your after.sh file and then run vagrant --provision your vagrant box will be provisioned and Xdebug will be installed.

Note: You will need to update the PHP versions every now and then.

wget https://xdebug.org/files/xdebug-2.6.0.tgz
tar xvzf xdebug-2.6.0.tgz
cd xdebug-2.6.0
phpize
./configure
make
sudo cp modules/xdebug.so /usr/lib/php/20160303/
cd /etc/php/7.3/fpm/conf.d/
sudo service php7.3-fpm restartvim

if [ ! -f /etc/php/7.3/mods-available/xdebug.ini ]; then
    echo "xdebug.ini not found"
else
    sudo truncate -s 0 /etc/php/7.3/mods-available/xdebug.ini
    sudo sh -c 'echo "zend_extension=xdebug.so" >> /etc/php/7.3/mods-available/xdebug.ini'
    sudo sh -c 'echo "xdebug.remote_enable=1" >> /etc/php/7.3/mods-available/xdebug.ini'
    sudo sh -c 'echo "xdebug.remote_connect_back=1" >> /etc/php/7.3/mods-available/xdebug.ini'
    sudo sh -c 'echo "xdebug.remote_port=9000" >> /etc/php/7.3/mods-available/xdebug.ini'
    sudo sh -c 'echo "xdebug.max_nesting_level=250" >> /etc/php/7.3/mods-available/xdebug.ini'
    sudo sh -c 'echo "xdebug.remote_autostart = 1" >> /etc/php/7.3/mods-available/xdebug.ini'
fi

if [ ! -f "/etc/php/7.3/cli/conf.d/20-xdebug.ini" ]; then
    sudo ln -s /etc/php/7.3/mods-available/xdebug.ini /etc/php/7.3/cli/conf.d/20-xdebug.ini
else
    echo '20-xdebug.ini symlink exists'
fi
sudo service php7.3-fpm restart
php -v
rm -rf ~/xdebug-2.6.0
rm ~/xdebug-2.6.0.tgz
rm ~/package.xml

A session name is important

  1. You need to specify a session_name parameter when debugging through a web browser

When I first started debugging I couldn’t get it to work. I would’ve set up everything like the tutorial said, but whenever I made a request via my browser nothing would happen in my IDE. This frustrated me.

Digging deeper I found out that I needed to append XDEBUG_SESSION_START=sessions_name as a parameter to the URL, which would look like www.arnedebelser.be/?XDEBUG_SESSION_START=vscode. But this could become quite tedious pretty quickly. Luckily for us there’s a nifty chrome extension which we can install to do this for us.

Welcome “Xdebug helper”, you can download it here

After installing, a little icon with a grey bug will popup right of your screen, click here and click Debug, I’m not really sure how this plugin internally works, but it must set some kind of cookie which enables the debugging process.

Xdebug Helper how to click

Note: All of this is written out in the official Xdebug documentation, but when I was learning all this stuff I didn’t even bother reading the documentation, it is only later when I knew that I actually found it in the official docs… Silly me

Last but not least, your host machine & homestead do not share the same environment

  1. If you want to locally debug your PHPUnit tests with Xdebug you also need to install Xdebug on your host machine

This one took me the longest to figure out, and to this day it still blows my mind that something so simple to me so long to grasp. I would configure everything correctly, then I would try to run Xdebug in my PHPUnit tests only to find out that nothing is being debugged.

Although I could blame it on a part of that didn’t really need the debug option, since I still had my dd(); helper whenever I got stuck in my tests.

But then at one night it struck me.

I had always been debugging my source code in Homestead, which was on a vagrant box which had Xdebug installed. But whenever I tried to run Xdebug on PHPUnit tests it would be running on my own machine. Which of course had no Xdebug installed. So I installed the latest version of XAMPP to get PHP. I then ran php -i in the command prompt, copied that output into the Xdebug installation wizard

Added a few lines of code to my php.ini file:

[XDebug]
zend_extension = "c:\xampp\php\ext\php_xdebug-2.7.2-7.3-vc15-x86_64.dll"
xdebug.max_nesting_level = 250 
xdebug.default_enable = 1
xdebug.idekey = "vscode" #seems to work without this too
xdebug.remote_enable = 1

And I was set to go!

I have to admit, I still feel stupid that it took me so long to figure this out. I’m glad I did, there’s things Xdebug provides when debugging which a simple dd(); can’t help you with.

This is as far as my reflections on Xdebug go, or atleast as far as I can remember. If you have read this to the end, congratulations! I hope I have been able to entertain you a little. Thanks!


If you ever came across simular issues, or have had some headaches trying to setup Xdebug, feel free to hit me up on twitter! @DeBelserArne

If and when I ever write another post like this one I’ll fire it on twitter! :wink:

Extra

For those interested I want to share my launch.json file. (VSCODE)

{
    "version": "0.2.0",
    "configurations": [

        // Configuration for local debugging
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "env": {
                "XDEBUG_CONFIG": "idekey=VSCODE"
            },
        },

        // Configuration for remote (homestead) debugging
        {
            "name": "Listen for XDebug on Homestead",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "pathMappings": {
                "/home/vagrant/code": "${workspaceFolder}"
            },
            "env": {
                "XDEBUG_CONFIG": "idekey=VSCODE"
            },
            "log": true,
        }
    ]
}
Share on: