On 31st March 2018 homebrew’s homebrew-php tap was archived and formulae were merged back into homebrew-core or deleted. See https://github.com/Homebrew/homebrew-php#readme. Among the ones deleted are the xdebug extensions, so there is now no easy way to install it.

Let’s do it anyway!

1. Install xdebug

According to xdebug’s site, the best way to install it when using homebrew is to use the pecl version. So step 1, make sure we have pecl.

$ which pecl

Pecl should really come with a homebrew php version, so you should have this. Installing it if you don’t have it falls outside the scope of this article.

$ pecl install xdebug
downloading xdebug-2.6.0.tgz ...
Starting to download xdebug-2.6.0.tgz (283,644 bytes)
.............done: 283,644 bytes
79 source files, building

<a long list of config vars and build script output here>

Build process completed successfully
Installing '/usr/local/Cellar/php/7.2.5/pecl/20170718/xdebug.so'

Warning: mkdir(): File exists in System.php on line 294

Warning: mkdir(): File exists in ↵
/usr/local/Cellar/php/7.2.5/share/php/pear/System.php on line 294
ERROR: failed to mkdir /usr/local/Cellar/php/7.2.5/pecl/20170718


I’ve run into this problem the first time I wanted to install this. Here’s how to fix it. If you got the following, skip to part 2.

Build process completed successfully
Installing '/usr/local/Cellar/php/7.2.5/pecl/20170718/xdebug.so'
install ok: channel://pecl.php.net/xdebug-2.6.0
Extension xdebug enabled in php.ini


1.1 Fixing xdebug install path

Can’t create a directory. Let’s try this:

$ cd /usr/local/Cellar/php/7.2.5/
$ ls -la
total 208
-rw-r--r--   1 javorszky  admin   2.2K 26 Apr 19:29 INSTALL_RECEIPT.json
-rw-r--r--   1 javorszky  admin   3.1K 24 Apr 16:10 LICENSE
-rw-r--r--   1 javorszky  admin    85K 24 Apr 16:10 NEWS
-rw-r--r--   1 javorszky  admin   1.6K 24 Apr 16:10 README.md
drwxr-xr-x  12 javorszky  admin   384B 26 Apr 19:29 bin
-rw-r--r--   1 javorszky  admin   628B 26 Apr 19:29 homebrew.mxcl.php.plist
drwxr-xr-x   3 javorszky  admin    96B 24 Apr 16:10 include
drwxr-xr-x   4 javorszky  admin   128B 24 Apr 16:10 lib
lrwxr-xr-x   1 javorszky  admin    23B 26 Apr 19:29 pecl -> /usr/local/lib/php/pecl
drwxr-xr-x   3 javorszky  admin    96B 24 Apr 16:10 sbin
drwxr-xr-x   4 javorszky  admin   128B 24 Apr 16:10 share

So pecl is a symlink to /usr/local/lib/php/pecl. But which pecl told us that lived in /usr/local/bin/pecl, which itself is a symlink to /usr/local/Cellar/php/7.2.5/bin/pecl.

Which means we can remove the symlink from /usr/local/Cellar/php/7.2.5/, and try installing xdebug again. That way the mkdir, which failed because you can’t create a directory with the same name as a symlink, should succeed.

2. Configuring xdebug

Let’s start with what php thinks its ini files are:

$ php --ini
PHP Warning:  Failed loading Zend extension 'xdebug.so' ↵
  (tried: /usr/local/lib/php/pecl/20170718/xdebug.so ↵
  (dlopen(/usr/local/lib/php/pecl/20170718/xdebug.so, 9): image not found), ↵
  /usr/local/lib/php/pecl/20170718/xdebug.so.so ↵
  (dlopen(/usr/local/lib/php/pecl/20170718/xdebug.so.so, 9): image not found)) ↵
  in Unknown on line 0

Warning: Failed loading Zend extension 'xdebug.so' ↵
  (tried: /usr/local/lib/php/pecl/20170718/xdebug.so ↵
  (dlopen(/usr/local/lib/php/pecl/20170718/xdebug.so, 9): image not found), ↵
  /usr/local/lib/php/pecl/20170718/xdebug.so.so ↵
  (dlopen(/usr/local/lib/php/pecl/20170718/xdebug.so.so, 9): image not found)) ↵
  in Unknown on line 0
Configuration File (php.ini) Path: /usr/local/etc/php/7.2
Loaded Configuration File:         /usr/local/etc/php/7.2/php.ini
Scan for additional .ini files in: /usr/local/etc/php/7.2/conf.d
Additional .ini files parsed:      /usr/local/etc/php/7.2/conf.d/ext-opcache.ini,

Lovely, so we need to configure everything.

Opening the entire directory of /usr/local/etc/php/7.2 in Sublime provides me quick and easy access to all the ini files that then I can edit.


Two things here.

  1. the xdebug installer added the zend_extension="xdebug.so" line to the top of the actual php.ini; it should not be there
  2. and it points to the wrong file; xdebug.so should have a full path

To fix them, I created a new file called xdebug.ini in the conf.d folder, which php reads and parses and uses all ini files from, and in that file I’ve added the following configs:


Make sure that the xdebugtmp directory actually exists.

I’ve also removed the xdebug entry from the top of the actual php.ini file.

NOTE: the config above has xdebug.profiler_enable=1 on it. This will SIGNIFICANTLY slow down your site. In return you get a lot of awesome data. This is not always needed though, so be sure to turn it off if you don’t need profiling!

After restarting valet, php --ini should yield you

Configuration File (php.ini) Path: /usr/local/etc/php/7.2
Loaded Configuration File:         /usr/local/etc/php/7.2/php.ini
Scan for additional .ini files in: /usr/local/etc/php/7.2/conf.d
Additional .ini files parsed:      /usr/local/etc/php/7.2/conf.d/ext-opcache.ini,

With no errors, and xdebug.ini actually showing up.

3. Configure PhpStorm

You need to open Preferences (CMD + , on mac), and then find Languages & Frameworks | PHP, and on that look for the CLI interpreter. Click the ... next to it, and then refresh. Xdebug should show up.


Then we need to configure xdebug itself. Open up Preferences, then find Languages & Frameworks | PHP | Debug (it is just within the PHP option):


Make sure that the port you set here is the same that you set in the xdebug.ini file above. I set it to xdebug.remote_port=9000, but truth be told it could be anything above 1024 (not including) as long as the port is not used by anything else.

Thirdly the project needs to have its path mappings set. That setting is in Languages & Frameworks | PHP | Servers.


The only path mapping I set is the one you see in the screenshot.

And finally run the Web Server Debug Validation, which is under the Run option:


That should give you a popup window with a Validate button. Clicking that you want green ticks everywhere:


You might need to add a server here. Click the ... next to the dropdown for Deployment server, and add a new one.

4. Use xdebug

Finally the proof is in the pudding. Turn on listening:


After you’ve added your break points, and click Debug..., you should see it working:


5. Notes

I’m using Laravel Valet to serve files locally. For that the debug configuration (see 2. Configuring Xdebug) has two options that I need to untick: Force break at first line....

Getting this working is also non-trivial, so it might require fiddling. Your milage may vary.

Hope this helps.

Photo by rawpixel.com on Unsplash