Install and configure Xdebug on your M1 Mac to debug PHP applications with Valet and PhpStorm

Old and rusty car with the hood open.
Looking under the hood... of your code.

Xdebug allows you to set breakpoints in your PHP application. When you run that application, the execution will stop at each breakpoint you defined, providing you with an opportunity to inspect the state of your application, including things like which variables are defined, what value they contain, and a stack trace.

We're going to install Xdebug, configure PHP and PhpStorm, and then set up a browser helper to set necessary cookies to begin debugging our code.

Prerequisites

Xcode

Apple has a program called Xcode, which includes a set of development tools. One of those tools is for working with the command line interface.

Let's install it with:

xcode-select --install

Now, if you get an error, you may already have it installed:

xcode-select: error: command line tools are already installed, use "Software Update" to install updates

If you use Git, there's a good chance you do.

Homebrew / PHP

We also need to install Homebrew and PHP. Follow this link on how to get Homebrew and PHP up and running, or even the entire guide on how to get a working development environment on your Mac.

Once done, run php --version in Terminal:

PHP 8.1.11 (cli) (built: Sep 29 2022 19:44:28) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.11, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.11, Copyright (c), by Zend Technologies

There shouldn't be a reference to Xdebug above. If it mentions Xdebug, you can skip the Xdebug installation step, because you already have it installed.

Valet

Valet installs Nginx and Dnsmasq. Nginx is our web server and Dnsmasq allows us to use local domains (e.g. something.test) instead of 127.0.0.1 and a port to serve our web applications.

You can follow this guide on how to install Valet on your Mac.

PhpStorm

You'll also need PhpStorm, which is the IDE we're going to use to debug our web application. You can get the latest version of PhpStorm by clicking the link.

Install Xdebug

Open up Terminal and confirm which CPU your Mac has:

file `which php`

If you have the Apple M1 chip, you'll see something like arm64 at the end:

/opt/homebrew/bin/php: Mach-O 64-bit executable arm64

And if that's the case, install Xdebug as follows:

arch -arm64 pecl install xdebug

If you have an older Mac, you can install Xdebug via:

pecl install xdebug

The output should end with something like this:

Build process completed successfully
Installing '/opt/homebrew/Cellar/php/8.1.11/pecl/20210902/xdebug.so'
install ok: channel://pecl.php.net/xdebug-3.1.5
Extension xdebug enabled in php.ini

If you run php --version, you should now see a reference to Xdebug:

PHP 8.1.11 (cli) (built: Sep 29 2022 19:44:28) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.11, Copyright (c) Zend Technologies
    with Xdebug v3.1.5, Copyright (c) 2002-2022, by Derick Rethans
    with Zend OPcache v8.1.11, Copyright (c), by Zend Technologies

Configure PHP

Let's enable remote debugging in PHP.

Find out where your PHP configuration files are stored:

php --ini

This should reveal something like:

Configuration File (php.ini) Path: /opt/homebrew/etc/php/8.1
Loaded Configuration File:         /opt/homebrew/etc/php/8.1/php.ini
Scan for additional .ini files in: /opt/homebrew/etc/php/8.1/conf.d
Additional .ini files parsed:      /opt/homebrew/etc/php/8.1/conf.d/error_log.ini,
/opt/homebrew/etc/php/8.1/conf.d/ext-opcache.ini,
/opt/homebrew/etc/php/8.1/conf.d/php-memory-limits.ini

Move into your configuration directory (conf.d):

cd /opt/homebrew/etc/php/8.1/conf.d

And add the following configuration to a xdebug.ini file:

xdebug.mode=debug

You can do this without opening the file by simply running this:

echo "xdebug.mode=debug" > xdebug.ini

Last, let's restart Valet for the changes to take effect:

valet restart

Configure PhpStorm

Open PhpStorm and create or load a PHP project. Press + , to open PhpStorm's preferences, and then navigate to: PHP > Debug.

Under Xdebug, uncheck the option: Force break at first line when the script is outside of the project. Click on OK.

When this option is checked, Xdebug will automatically stop execution in a file called server.php, which belongs to Valet, and you have to skip this breakpoint to continue to your application. By unchecking this box, we're only focusing on files within our project and save a step.

Now in your menu bar, go to: Run > Start Listening for PHP Debug Connections. There is also a little bug icon in your toolbar (usually top right) to start/stop listening as well.

Find a file that you know gets executed when you open the web application in your browser. In that file, find a line, and click on the line number in PhpStorm. It should mark that line with a dot, which is a breakpoint.

Set up debugging in browser

Visit PhpStorm's browser debugging extensions page. Find the Xdebug row and the browser column of your choice. If you're using the Brave browser, you can simply click on Chrome's Xdebug helper extension.

After you install the extension, it'll add a bug icon in your address bar on Firefox, or your extensions bar (to the right of the address bar) in Chrome and Brave.

Now open the web application you opened in PhpStorm in your browser, click the bug, and select Debug to enable debugging. Refresh the page.

PhpStorm should come to the front with a window called: Incoming Connections From Xdebug. Simply click on Accept.

The execution should now be paused on the breakpoint you defined.

Debugging in PhpStorm

You'll see the files it executed, and in which order, toward the bottom left. Note the server.php file I mentioned earlier– it's the file outside of the project we chose to ignore.

You'll see all of the application variables, server variables, and constants that are defined on the right, and by expanding them, you can see their values.

In the toolbar right above, you have a few options to proceed with debugging.

Here are the most common ones:

  1. Stop button: Stop debugging.
  2. Play button: Resume execution to the next breakpoint (or finish).
  3. Down arrow button: Step into that line (like a function or method).
  4. Angled right arrow button: Step over the line and go to the next.
  5. Up arrow button: Step out of the function/method we followed.

Troubleshooting

If the debugger isn't working, PhpStorm has a built-in validation tool to see if there is a configuration issue.

Go to: Run > Web Server Debug Validation. Enter your local domain name in Url to validation script and click on Validate.

If anything doesn't have a green checkmark, expand that line to learn more on how to resolve that particular issue.

That's it– you now have Xdebug installed and configured, and can use it to debug your PHP applications without having to change your code and print out variables all over the place.

If you have any questions or comments, don't hesitate to leave them below.

Featured image by Zach Vessels.