Pecl install xdebug error

Xdebug: A powerful debugger for PHP

This section describes on how to install Xdebug.

How you install Xdebug depends on your system. There are the following possibilities:

  • Linux with a package manager such
    as apt, yum, or something else.
  • Linux without an Xdebug package with PECL.
  • macOSX with homebrew, through PECL.
  • Windows, with help from a wizard.
  • Unix-like operating systems, from source.

Installing on Linux #

Installing Xdebug with a package manager is often the fastest way. Depending on your distribution, run the following command:

  • Alpinelinux:
    sudo apk add php7-pecl-xdebug, or
    sudo apk add php8-pecl-xdebug
  • Arch Linux:
    sudo pacman -S xdebug
  • CentOS:
    sudo yum install php-xdebug
  • CentOS (Remi Repo):
    sudo yum install php74-php-xdebug3, or
    sudo yum install php80-php-xdebug3, or
    sudo yum install php81-php-xdebug3
  • Debian (9/stretch, testing/buster/bullseye/sid):
    sudo apt-get install php-xdebug
  • Fedora (32):
    sudo yum install php-xdebug
  • Fedora (Remi Repo):
    sudo yum install php74-php-xdebug3
  • Gentoo:
    emerge dev-php/xdebug
  • Manjaro (20.1/Mikah):
    sudo pacman -S xdebug
  • RHEL:
    sudo yum install php-xdebug
  • RHEL (Remi Repo):
    sudo yum install php74-php-xdebug3
  • SUSE (openSUSE, Enterprise):
    sudo zypper in php7-xdebug, or
    sudo zypper in php8-xdebug
  • Ubuntu (18.04 LTS/Bionic, 20.04 LTS/Focal):
    sudo apt-get install php-xdebug
  • Ubuntu (Ondřej Surý’s PPA):
    sudo apt-get install php7.4-xdebug, or
    sudo apt-get install php8.0-xdebug, or
    sudo apt-get install php8.1-xdebug

Xdebug’s latest version is 3.2.0.

For packages that have the PHP version in the package name, such as in
php81-php-xdebug3, you can substitute the PHP
version with the one that matches the PHP version that you are running.

Linux distributions might be providing an old and/or outdated version.
If the package manager
installs a version that is no longer supported (see Supported Versions), please install
Xdebug with PECL, or from source
instead.

Installing with PECL #

You can install Xdebug through PECL on Linux & macOS with Homebrew.

Prerequisites:

  • macOS:
    • Xcode’s command line tools (run: xcode-select
      --install
      ).
    • PHP installed through Homebrew.
  • Linux:
    • GCC and associated libraries.
    • PHP development headers (see Compile below).

Run:

pecl install xdebug

On Apple M1 hardware, programs can either be compiled for the native M1/ARM64
architecture, or for the emulated x86_64 architecure. Sometimes there is a
mismatch with the default and PECL will fail, or Xdebug won’t load with a
message such as:

PHP Warning:  Failed loading Zend extension 'xdebug.so' (tried: /opt/homebrew/lib/php/pecl/20190902/xdebug.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/xdebug.so, 9): no suitable image found.  Did find:
        /opt/homebrew/lib/php/pecl/20190902/xdebug.so: mach-o, but wrong architecture
        /opt/homebrew/lib/php/pecl/20190902/xdebug.so: stat() failed with errno=22), /opt/homebrew/lib/php/pecl/20190902/xdebug.so.so (dlopen(/opt/homebrew/lib/php/pecl/20190902/xdebug.so.so, 9): image not found)) in Unknown on line 0

You can verify what your PHP’s architecture is with:

file `which php`

If that says arm64e, then you need to run:

arch -arm64 sudo pecl install xdebug

And if it’s x86_64, then you need to run:

arch -x86_64 sudo pecl install xdebug

You should ignore any prompts to add
"extension=xdebug.so" to
php.ini — this will cause problems.

In some cases pecl will change the php.ini file to
add a configuration line to load Xdebug. You can check whether it did by
running php -v. If Xdebug shows up with a version number, than
you’re all set and you can configure Xdebug’s other functions, such as
Step Debugging, or Profiling.

If pecl did not add the right line, skip to the Configure PHP section.

1 On macOS, you should have PHP installed with Homebrew.

Installing on Windows #

There are a few precompiled modules for Windows, they are all for the non-debug
version of PHP. You can get those at the download
page. Follow these instructions to get Xdebug
installed.

Installation From Source #

Obtain #

You can download the source of the latest stable release 3.2.0.

Alternatively you can obtain Xdebug from GIT:

git clone git://github.com/xdebug/xdebug.git

This will checkout the latest development version which is currently
3.2.0dev. This development branch might not always work as
expected, and may have bugs.

You can also browse the source on GitHub at https://github.com/xdebug/xdebug.

Compile #

There is a wizard available that provides you
with the correct file to download, and which paths to use.

You compile Xdebug separately from the rest of PHP. You need access to the
scripts phpize and php-config. If your system
does not have phpize and php-config, you will
need to install the PHP development headers.

Debian users can do that with:

apt-get install php-dev

And RedHat and Fedora users with:

yum install php-devel

It is important that the source version matches the installed version as there
are slight, but important, differences between PHP versions. Once you have
access to phpize and php-config, take the
following steps:

  1. Unpack the tarball:

    tar -xzf xdebug-3.2.0.tgz

    You should not
    unpack the tarball inside the PHP source code tree.
    Xdebug is compiled separately, all by itself, as stated above.

  2. cd xdebug-3.2.0

  3. phpize

    If phpize is not in your path, please make sure
    that it is by expanding the PATH environment variable. Make sure
    you use the phpize that belongs to the PHP version that you want to use Xdebug
    with. See this FAQ entry if you’re having some
    issues with finding which phpize to use.

  4. ./configure --enable-xdebug

  5. make

  6. make install

Configure PHP #

  1. Find out which PHP ini file to modify.

    Run a script with the following to find all configuration files that PHP has
    loaded:

    <?php
    var_dump(php_ini_loaded_file(), php_ini_scanned_files());
    

    Alternatively, you can run php --ini on the command line.

    If there is a file with xdebug in the name, such as
    /etc/php/7.4/cli/conf.d/99-xdebug.ini, then this is the
    file to use.

    If that file does not exist, but there are other files in a
    conf.d or similar directory, you can create a new file there too.
    Please name it 99-xdebug.ini in that case.

    Otherwise, modify the php.ini file that is displayed through
    the script, or php --ini command.

    There could be more than one
    php.ini file. In many set-ups there is a different one for the
    command line (often cli/php.ini) and the web server (often
    fpm/php.ini).

    If you want to use Xdebug and
    OPCache together, you must have the zend_extension line for Xdebug
    below the line for OPCache, or in a file starting with a higher number (ie.
    99-xdebug.ini vs 20-opcache.ini), otherwise they
    won’t work properly together.

  2. Add the following line to this PHP ini file:

    zend_extension=xdebug

  3. Restart your webserver, or PHP-FPM, depending on what you are
    using.

  4. Verify that Xdebug is now loaded.

    Create a PHP page that calls xdebug_info(). If you request the
    page through the browser, it should show you an overview of Xdebug’s settings
    and log messages.

    On the command line, you can also run php -v. Xdebug and its
    version number should be present as in:

    PHP 7.4.10 (cli) (built: Aug 18 2020 09:37:14) ( NTS DEBUG )
    Copyright (c) The PHP Group
    Zend Engine v3.4.0, Copyright (c) Zend Technologies
      with Zend OPcache v7.4.10-dev, Copyright (c), by Zend Technologies
      with Xdebug v3.0.0-dev, Copyright (c) 2002-2020, by Derick Rethans
    

    If Xdebug does not show up, or you get a warning from PHP that an
    xdebug.so file or similar was not found, you might need to use the
    full path instead of just zend_extension=xdebug, such as
    zend_extension=/usr/lib/php/20190902/xdebug.so.

    On Windows, you should place the php_xdebug.dll in the
    ext/ directory, which is a child directory in your PHP
    installation tree.

If you have trouble with this, please refer to the installation wizard to help you guide through this
process.

With Xdebug loaded, you can now enable individual features, such as
Step Debugging, or Profiling.

Related Content #

  • Activation and Triggers

    This video explains how to activate, through triggers and other method’s Xdebug’s step debugger, profiler, and tracer.

  • Xdebug 3: Diagnostics

    This video teaches you how to troubleshoot your Xdebug setup. It explains how to find out how Xdebug is configured, which settings have been made, and what it is attempting to do regarding its different features.

  • Xdebug 3: Modes

    This video introduces Xdebug 3’s modes — the new way to configure which parts of Xdebug you have enabled.

Related Settings and Functions #

  • string xdebug.log =
  • integer xdebug.log_level = 7
  • string xdebug.mode = develop
  • xdebug_info() : mixed

Settings #


string xdebug.log = #

Configures Xdebug’s log file.

Xdebug will log to this file all file creations issues, Step Debugging
connection attempts, failures, and debug communication.

Enable this functionality by setting the value to a absolute path. Make sure
that the system user that PHP runs at (such as www-data if you are
running with Apache) can create and write to the file.

The file is opened in append-mode,
and will therefore not be overwritten by default. There is no concurrency
protection available.

The log file will include any attempt that Xdebug
makes to connect to an IDE:

[2693358] Log opened at 2020-09-02 07:19:09.616195
[2693358] [Step Debug] INFO: Connecting to configured address/port: localhost:9003.
[2693358] [Step Debug] ERR: Could not connect to debugging client. Tried: localhost:9003 (through xdebug.client_host/xdebug.client_port).
[2693358] [Profiler] ERR: File '/foo/cachegrind.out.2693358' could not be opened.
[2693358] [Profiler] WARN: /foo: No such file or directory
[2693358] [Tracing] ERR: File '/foo/trace.1485761369' could not be opened.
[2693358] [Tracing] WARN: /foo: No such file or directory
[2693358] Log closed at 2020-09-02 07:19:09.617510

It includes the opening time (2020-09-02 07:19:09.616195), the
IP/Hostname and port Xdebug is trying to connect to
(localhost:9003), and whether it succeeded (Connected to
client
). The number in brackets ([2693358]) is the
Process ID.

It includes:

[2693358]
process ID in brackets
2020-09-02 07:19:09.616195
opening time

For Step Debugging:

INFO: Connecting to configured address/port: localhost:9003.
ERR: Could not connect to debugging client. Tried: localhost:9003 (through xdebug.client_host/xdebug.client_port).

For Profiling:

ERR: File '/foo/cachegrind.out.2693358' could not be opened.
WARN: /foo: No such file or directory

For Function Trace:

ERR: File '/foo/trace.1485761369' could not be opened.
WARN: /foo: No such file or directory

All warnings and errors are described on the Description of errors page, with
detailed instructions on how to resolve the problem, if possible. All errors are always logged through
PHP’s internal logging mechanism (configured with error_log
in php.ini). All warnings and errors also show up in the
diagnostics log that you can view by calling xdebug_info().

Step Debugger Communication

The debugging log can also log the communication between Xdebug and an IDE.
This communication is in XML, and starts with the <init XML
element:

<init
    xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
    fileuri="file:///home/httpd/www.xdebug.org/html/router.php"
    language="PHP" xdebug:language_version="7.4.11-dev"
    protocol_version="1.0" appid="2693358" idekey="XDEBUG_ECLIPSE">
        <engine version="3.0.0-dev"><![CDATA[Xdebug]]></engine>
        <author><![CDATA[Derick Rethans]]></author>
        <url><![CDATA[https://xdebug.org]]></url>
        <copyright><![CDATA[Copyright (c) 2002-2020 by Derick Rethans]]></copyright>
</init>

The fileuri attribute lists the entry point of your
application, which can be useful to compare to breakpoint_set
commands to see if path mappings are set-up correctly.

Beyond the <init element, you will find the configuration of
features:

<- feature_set -i 4 -n extended_properties -v 1
-> <response
       xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
       command="feature_set" transaction_id="4" feature="extended_properties" success="1">
   </response>

And continuation commands:

<- step_into -i 9
-> <response
       xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug"
       command="step_into" transaction_id="9"
       status="break" reason="ok">
           <xdebug:message filename="file:///home/httpd/www.xdebug.org/html/router.php" lineno="3">
           </xdebug:message>
   </response>

You can read about DBGP — A common debugger protocol specification at its dedicated documation page.

The xdebug.log_level setting controls how much information is
logged.

Many Linux distributions now use systemd, which
implements private tmp directories. This means that when PHP
is run through a web server or as PHP-FPM, the /tmp directory is
prefixed with something akin to:

/tmp/systemd-private-ea3cfa882b4e478993e1994033fc5feb-apache.service-FfWZRg

This setting can additionally be configured through the
XDEBUG_CONFIG
environment variable.


integer xdebug.log_level = 7 #

Configures which logging messages should be added to the log file.

The log file is configured with the xdebug.log setting.

The following levels are supported:

Level Name Example
0 Criticals Errors in the configuration
1 Errors Connection errors
3 Warnings Connection warnings
5 Communication Protocol messages
7 Information Information while connecting
10 Debug Breakpoint resolving information

Criticals, errors, and warnings always show up in the
diagnostics log that you can view by calling xdebug_info().

Criticals and errors are additionally logged through
PHP’s internal logging mechanism (configured with error_log
in php.ini).

This setting can additionally be configured through the
XDEBUG_CONFIG
environment variable.


string xdebug.mode = develop #

This setting controls which Xdebug features are enabled.

This setting can only be set in php.ini or
files like 99-xdebug.ini that are read when a PHP process starts
(directly, or through php-fpm), but not in .htaccess and
.user.ini files, which are read per-request.

The following values are accepted:

off
Nothing is enabled. Xdebug does no work besides checking whether
functionality is enabled. Use this setting if you want close to 0
overhead.
develop
Enables Development Helpers including the overloaded var_dump().
coverage
Enables Code Coverage Analysis to generate code coverage reports, mainly in
combination with
PHPUnit.
debug
Enables Step Debugging. This can be used to step through your code while it
is running, and analyse values of variables.
gcstats
Enables Garbage Collection Statistics to collect statistics about PHP’s Garbage
Collection Mechanism.
profile
Enables Profiling, with which you can analyse performance bottlenecks
with tools like KCacheGrind.
trace
Enables the Function Trace feature, which allows you record every function
call, including arguments, variable assignment, and return value that is made
during a request to a file.

You can enable multiple modes at the same time by comma separating their
identifiers as value to xdebug.mode: xdebug.mode=develop,trace.

XDEBUG_MODE environment variable

You can also set Xdebug’s mode by setting the XDEBUG_MODE
environment variable on the command-line; this will take precedence over the
xdebug.mode setting, but will not change the value of the xdebug.mode
setting.

Some web servers have a configuration option to
prevent environment variables from being propagated to PHP and Xdebug.

For example, PHP-FPM has a clear_env
configuration setting that is on by default, which you will
need to turn off if you want to use XDEBUG_MODE.

Make sure that your web server does not clean the environment, or specifically
allows the XDEBUG_MODE environment variable to be passed on.

Functions #


xdebug_info( string $category = null )
: mixed
#

Show and retrieve diagnostic information

This function presents APIs to retrieve information about Xdebug itself. Which
information gets returned, or displayed, depends on which arguments, or none at
all, are given.

$category =

Without arguments, this function returns an HTML page which shows diagnostic
information. It is analogous to PHP’s phpinfo() function.

The HTML output includes which mode is active, what the settings are, and
diagnostic information in case there are problems with debugging connections,
opening of files, etc.

Each warning and error in the diagnostics log also links through to the
Description of errors documentation page.

$category = 'mode' (New in Xdebug 3.1)

The function returns an array of all the
enabled modes, whether through xdebug.mode or the
XDEBUG_MODE environment variable.

Example:


<?php
var_dump
xdebug_info'mode' ) );
?>

Returns:

array(3) {
  [0] =>
  string(5) "debug"
  [1] =>
  string(7) "develop"
  [2] =>
  string(5) "trace"
}

$category = 'extension-flags' (New in Xdebug 3.1)

The function returns an array of all the compile flags that were enabled when
running ./configure as part of Xdebug’s compilation process.

The only flag that is available, is the compression flag. If this
flag is enabled, then the xdebug.use_compression setting is available, and enabled by default.

Profiling and Function Trace will create GZip compressed files if the
xdebug.use_compression setting is turned on (the default).

Example:


<?php
var_dump
xdebug_info'extension-flags' ) );
?>

Returns:

array(1) {
  [0] =>
  string(11) "compression"
}

Setting up Xdebug

Last modified on Fri 01 Jul 2022

Xdebug is an indispensible tool when working on PHP projects. It’s a very powerful debugger which can be used for code coverage when running tests as well.

Assuming you have installed the latest stable PHP version using Homebrew, you should use pecl to install the Xdebug. Pecl is a repository for PHP extensions. First, make sure you have it installed (even though it comes with the Homebrew PHP version).

which pecl

/usr/local/bin/pecl

Try to install Xdebug:

That can be done in two ways: your installation passes, and you get a message like this:

Successful installation

...

Build process completed successfully
Installing '/usr/local/Cellar/php@7.4/7.4.16/pecl/20200930/xdebug.so'
install ok: channel://pecl.php.net/xdebug-3.0.4
Extension xdebug enabled in php.ini

In this case, all you need to check is whether PHP has linked the module correctly.

php -v

PHP 7.4.16 (cli) (built: Mar  4 2021 20:52:51) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.16, Copyright (c), by Zend Technologies
    with Xdebug v3.0.4, Copyright (c) 2002-2021, by Derick Rethans

If you get an error message, you’ll need to find your php.ini file.

php --ini

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

Go to /usr/local/etc/php/7.4/php.ini and edit it by adding

[xdebug]
zend_extension="xdebug.so"
xdebug.mode=debug,develop
xdebug.client_port=9003

at the end of the php.ini file.

That’s it, you’re ready to go.

Unsuccessful installation

When installing Xdebug, you might get the following error:

Build process completed successfully
Installing '/usr/local/Cellar/php@7.4/7.4.16/pecl/20200930/xdebug.so'

Warning: mkdir(): File exists in System.php on line 294
PHP Warning:  mkdir(): File exists in /usr/local/Cellar/php/7.4.16/share/php/pear/System.php on line 294

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

Go to your PHP installation folder (/usr/local/Cellar/php/7.4.16/, for instance) and type

ls -all

total 168
-rw-r--r--   1 infinum-denis  staff   3.1K Aug  7 10:10 INSTALL_RECEIPT.json
-rw-r--r--   1 infinum-denis  staff   3.1K Jul  3 13:30 LICENSE
-rw-r--r--   1 infinum-denis  staff    64K Jul  3 13:30 NEWS
-rw-r--r--   1 infinum-denis  staff   1.6K Jul  3 13:30 README.md
drwxr-xr-x  12 infinum-denis  staff   384B Aug  7 10:10 bin
-rw-r--r--   1 infinum-denis  staff   628B Aug  7 10:10 homebrew.mxcl.php.plist
drwxr-xr-x   3 infinum-denis  staff    96B Jul  3 13:30 include
drwxr-xr-x   4 infinum-denis  staff   128B Jul  3 13:30 lib
lrwxr-xr-x   1 infinum-denis  staff    23B Aug  7 10:10 pecl -> /usr/local/lib/php/pecl
drwxr-xr-x   3 infinum-denis  staff    96B Jul  3 13:30 sbin
drwxr-xr-x   4 infinum-denis  staff   128B Jul  3 13:30 share

You can see that pecl is symlinked to /usr/local/lib/php/pecl, but which pecl specified /usr/local/bin/pecl, which is itself a symlink to /usr/local/Cellar/php/7.4.16/bin/pecl. Therefore, you need to remove the symlink.

Now you can install Xdebug again, and it should work as described in the previous case (follow the steps described above to add it correctly into your php.ini).

Possible side effects

A possible side effect of running Xdebug, especially if you enable profiler output in Xdebug settings in php.ini, is that the file can grow very large. To prevent this, just make sure you delete it every once in a while, or simply don’t enable logging.

Using Xdebug

You can use Xdebug to debug your CLI scripts (tests for instance), or debug your web application.

In order to debug the web application, you’ll need a browser extension. In Chrome it’s Xdebug helper, in FF it’s Xdebug helper for Firefox.

If you are using PhpStorm, setting up Xdebug is straightforward. In VSCode you’ll need to install the PHP Debug extension, configre it, and then you should be able to set breakpoints in your code.

Be sure to enable the helper and listener in your IDE.

Debugging CLI scripts

When you want to debug the CLI scripts, such as automated tests or custom commands, you need to add a manual trigger:

XDEBUG_TRIGGER=yes CLI SCRIPT

This will instruct Xdebug to be triggered on the script run.

WSL2 issues

Windows Subsystem for Linux (WSL) works differently than MacOS system, because you need to set the correct external IP address for Xdebug to be able to ‘listen’ to the requests.

To quickly find the external IP of your WSL you can type

ip route show default | awk '{print }'

in your WSL terminal. Then you need to add this IP address as your xdebug.client_host in your php.ini or xdebug.ini settings.

After that make sure you restart your PHP server. You should be able to use XDebug normally.

In order to debug the CLI scripts, you’ll need to add additional environment variable

XDEBUG_TRIGGER=yes PHP_IDE_CONFIG=serverName=yourprojectname.test CLI SCRIPT
PhpStorm

For webserver script debugging (e.g. integration test debugging), you can add the URL to your server setup, and correct port mappings in the server settings, and it should work.

In the case of running script debugging that isn’t tied to a specific domain (for instance you want to debug a phpcs sniff), the server name can be localhost, but it’s important to correctly set up path mappings. For instance in the image below

Server settings for PhpStorm

The name of the server is WSL, host is localhost, but the port mappings between the local files and server files are specified (note that the local ones have \wsl$ prefix, while the server ones are the ones you get by typing pwd inside your terminal, like /home/...).

Then running the script as

XDEBUG_TRIGGER=yes PHP_IDE_CONFIG=serverName=WSL CLI SCRIPT

Will correctly trigger a breakpoint and you can debug your script as before.

That is because from the PhpStorm’s point of view, the WSL distribution is a server, so it needs to have the correct port mappings available so that it can connect the dots.

Visual Studio Code

Install the PHP Debug extension published by Xdebug. The PHP Debug extension can also be found in VSCode’s Extensions tab by searching for it.

PHP Debug Extension

Once installed click on the Run tab and select «Add configuration…». Now, you’ll need to pick the PHP environment. A new launch.json file will be added to the root directory by VSCode. By default it will contain 3 configurations. The one you need is the «Listen for Xdebug».

Example of the «Listen for Xdebug» configuration:

{
    "name": "Listen for Xdebug",
    "type": "php",
    "request": "launch",
    "port": 9003
}

Start debugging by opening the debug mode tab. In the dropdown select «Listen for Xdebug» and click the green debug button next to the dropdown.

If the process started successfully you will now see several options in the window, via which you can pick what logs Xdebugger will show like:

  • Notices
  • Warnings
  • Errors
  • Exceptions
  • Everything

And you will see a small floating bar where you can Pause/Stop the debugger or step trough the steps when debugging breakpoints.

While the debugger is running you can run unit tests or run your website (chrome php debug extension needed) and debugger will listen for anything you selected and show you the data in the VS Code debug view.

Using Xdebug in Postman

There are some instances where you’d like to debug the logic for your API calls.

In this case you’ll need to add a query parameter to your endpoint URL:

https://yoururl.test/wp-json/wp/v2/posts?XDEBUG_SESSION_START=PHPSTORM

The query parameter value can be changed according to your IDE.

In the last post, I was finally back up and running with my IDE after an update to Serenata. Or maybe not…

Turns out, another update broke something. MacOS Catalina was released recently and introduced a new version of PHP (7.3.8 in my case). This change means XDebug is now referencing outdated Zend API, which throws an error when running pretty much anything. Oops, beause no XDebug egals no PHPUnit code coverage report.

On MacOS Mojave, getting XDebug was a matter of installing Pear, setting up some Xcode SDK Headers file, installing XDebug from source using Pear and enabling XDebug in PHP configuration files. Sounds easy, should be the same for Catalina…

Spoiler alert, Xcode 11 comes with a massive breaking change.

An alternative installation method is to use homebrew to install PHP, Pecl and XDebug. I didn’t test this method, as I prefer the long method which was simple to setup on Mojave. Plus, solving this issue might prove useful for other situations.

Installing XDebug

Assuming Pear, Autoconf, and Xcode is installed on your computer, installing XDebug should be easy as :

sudo pecl install xdebug

But now, I’m getting the following error. This is because the compiler requires some header files, which are provided by the MacOS SDK bundled with Xcode. Not a surprise, as it was the same error with previous version of MacOS, aka Mojave :

/private/tmp/pear/install/xdebug/xdebug.c:25:10: fatal error: 'php.h' file not found
#include "php.h"
         ^~~~~~~
1 error generated.
make: *** [xdebug.lo] Error 1
ERROR: `make' failed

The Mojave Solution

On Mojave, the following step was necessary to install the missing header files. Don’t actually run this command on Catalina, as it will fail.

sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

The problem is the SDK headers package was removed starting with Xcode 11.0. And we can’t just change 10.14 to 10.15 to make it work…

The Catalina Issue

After a lot of digging, I’ve found the actual files are actually stored somewhere :

$ sudo find /Library -name php.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/php/main/php.h
/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/php/main/php.h

And if you look closely,

$ sudo pecl install xdebug
downloading xdebug-2.7.2.tgz ...
Starting to download xdebug-2.7.2.tgz (230,987 bytes)
.................................................done: 230,987 bytes
69 source files, building
running: phpize
grep: /usr/include/php/main/php.h: No such file or directory
grep: /usr/include/php/Zend/zend_modules.h: No such file or directory
grep: /usr/include/php/Zend/zend_extensions.h: No such file or directory

See the error returned by phpize claiming /usr/include/php/main/php.h doesn’t exist? Turns out, /usr/include doesn’t actually exist on my system:

$ ls /usr/include
ls: /usr/include: No such file or directory

If you try to symlink one into the other, even using sudo, that won’t work, thanks to SIP :

$ sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include /usr/include
ln: /usr/include: Operation not permitted

The reason is Apple has deprecated having a /usr/include distinct from the SDK. This has been completely removed in Catalina so different SDK and Xcode version could be run together.

So now the issue is, in order to compile XDebug, we need to either tell the compiler to use the headers from a different location, or actually put the required files in /usr/include

Until this issue is resolved, either on Apple side or XDebug side, not much can be done other than use a VM to run tests locally…

References for later

  • Can’t compile a C program on a Mac after upgrading to Catalina 10.15
  • Where are the C headers in MacOS Mojave?
  • Can’t compile C program on a Mac after upgrade to Mojave
  • /usr/include missing on macOS Catalina (with Xcode 11)
  • Installation of Xdebug on MacOS Catalina 10.15

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
/usr/local/bin/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,
/usr/local/etc/php/7.2/conf.d/php-memory-limits.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.

Screen-Shot-2018-05-03-at-12.57.24

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:

;XDebug
zend_extension="/usr/local/Cellar/php/7.2.5/pecl/20170718/xdebug.so"
xdebug.remote_autostart=1
xdebug.remote_port=9000
xdebug.remote_enable=1
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/Users/javorszky/xdebugtmp/"

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,
/usr/local/etc/php/7.2/conf.d/php-memory-limits.ini,
/usr/local/etc/php/7.2/conf.d/xdebug.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.

Image-2018-05-03-at-1.20.34-pm

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

Image-2018-05-03-at-1.26.52-pm

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.

Screen-Shot-2018-05-03-at-12.15.59

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:

Screen-Shot-2018-05-03-at-13.48.32

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

Screen-Shot-2018-05-03-at-13.47.38

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:

Screen-Shot-2018-05-03-at-13.52.32

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

Screen-Shot-2018-05-03-at-13.56.15

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

Инструкция по настройке xdebug в PhpStorm на Mac OS.

Все следующее будет справедливо при установленном Homebrew и настроенным веб-сервером на Mac OS.

xdebug настраивать не всегда просто. Надо прописывать и указывать много всего разного. В данном труде будет описан один из возможных вариантов настройки с установленными у меня на тот момент версиями PHP. Соответственно нужно не тупо копировать ссылки на директории, а смотреть где всё находится это у вас и делать под себя. Также описаны ошибки, которые встречались у меня при настройке.

Установка

Заходим в консоль и запускаем команду установки xdebug

Ошибка 1

Если возникла ошибка такого типа: Ошибка ERROR: failed to mkdir /usr/local/Cellar/php/7.3.9_1/pecl/

running: find «/private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2» | xargs ls -dils
8803261274 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2
8803261823 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr
8803261824 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local
8803261825 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local/Cellar
8803261826 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local/Cellar/php
8803261827 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local/Cellar/php/7.3.9_1
8803261828 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local/Cellar/php/7.3.9_1/pecl
8803261829 0 drwxr-xr-x 3 Dream wheel 96 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local/Cellar/php/7.3.9_1/pecl/20180731
8803261830 576 -rwxr-xr-x 1 Dream wheel 294068 Oct 19 02:56 /private/tmp/pear/temp/pear-build-DreamjT4nWU/install-xdebug-2.7.2/usr/local/Cellar/php/7.3.9_1/pecl/20180731/xdebug.so

Build process completed successfully
Installing ‘/usr/local/Cellar/php/7.3.9_1/pecl/20180731/xdebug.so’

Warning: mkdir(): File exists in System.php on line 294
PHP Warning: mkdir(): File exists in /usr/local/Cellar/php/7.3.9_1/share/php/pear/System.php on line 294

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

То для решения, нас интересует последняя строка:

ERROR: failed to mkdir /usr/local/Cellar/php/7.3.9_1/pecl/20180731

Заходим и удаляем там файл pecl. После этого снова запускам установку xdebug.

Ошибка 2

Как-то раз возникла такая ошибка:

Notice: Trying to access array offset on value of type bool in REST.php on line 181
PHP Notice: Trying to access array offset on value of type bool in /usr/local/Cellar/php/7.4.2/share/php/pear/PEAR/REST.php on line 181

Notice: Trying to access array offset on value of type bool in /usr/local/Cellar/php/7.4.2/share/php/pear/PEAR/REST.php on line 181
No releases available for package «pecl.php.net/xdebug»
install failed

При повторном запуске команды установки, она исчезла сама по себе:

Если всё пройдет успешно, появится сообщение:

Build process completed successfully
Installing ‘/usr/local/Cellar/php/7.3.9_1/pecl/20180731/xdebug.so’
install ok: channel://pecl.php.net/xdebug-2.7.2
Extension xdebug enabled in php.ini

Перезагружаем сервисы PHP

brew services restart php

Если вдруг PHP не перезагружается, смотрим логи:

/usr/local/var/log/php-fpm.log

Например, у меня была такая ошибка:

PHP: syntax error, unexpected BOOL_FALSE in /usr/local/etc/php/7.3/php.ini on line 1053
[19-Oct-2019 03:27:22] NOTICE: PHP message: PHP Warning: Failed loading Zend extension ‘xdebug.so’ (tried: /usr/local/lib/php/pecl/20180731/xdebug.so (dlopen(/usr/local/lib/php/pecl/20180731/xdebug.so, 9): image not found), /usr/local/lib/php/pecl/20180731/xdebug.so.so (dlopen(/usr/local/lib/php/pecl/20180731/xdebug.so.so, 9): image not found)) in Unknown on line 0
Failed loading /usr/local/Cellar/php/7.3.9_1/pecl/20180731/xdebug.so”

Failed loading /usr/local/Cellar/php/7.3.9_1/pecl/20180731/xdebug.so

Как исправить. Заходим в файл

/usr/local/etc/php/7.4/conf.d/xdebug.ini

или в ту версию, которая у вас текущая. Внутри исправляем путь до файла xdebug.so.

Его искать по адресу:

или (версия php может быть другой)

Failed loading /usr/local/Cellar/php/7.4/pecl/

Настраиваем файл php.ini

Создаём файл xdebug.ini по такому пути (ну или к той версии php которая у вас текущая):

/usr/local/etc/php/7.3/conf.d/xdebug.ini

Внутри пишем конфиг такого типа:

[XDebug]
zend_extension=»/usr/local/Cellar/php/7.3.9_1/pecl/20180731/xdebug.so»
xdebug.remote_autostart=1
xdebug.remote_port=9001
xdebug.remote_enable=1
; xdebug.profiler_enable=1
; xdebug.profiler_output_dir=»/Users/Dream/Sites/_xdebug-profiler/»

xdebug.remote_host=localhost
xdebug.idekey=PHPstorm

Сохраняем, перезагружаем PHP:

brew services restart php

Смотрим что показывает команда:

Если всё хорошо, должно показываться так:

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

Настраиваем CLI Interpretator в PhpStorm

Теперь заходим в настройки Шторма и там где CLI Interpreter нажимаем три точки.

Видим, что показывается PHP, которая стоит по умолчанию в системе Mac OS.

В моем случае это не подходит. Кроме стандартного маковского PHP у меня установлен php от Homebrew. А там он находится по иному пути.

Поэтому ставим другой путь (для которого мы указывали настройки).

Зависит от версии, например:

/usr/local/Cellar/php/7.3.9_1/bin

или

/usr/local/Cellar/php/7.4.2/bin

и после этого получаем такую красивую картинку, где все заполнено:

Через терминал можно проверить загруженные модули:

Сочетание xdebug должен встречаться 2 раза в списке. Один из которых под заголовком [Zend Modules].

Настраиваем PHP -> Servers

Прописываем для нашего сайта настройки таким образом:

Изменим порт на 9001

Здесь:

Добавим конфиг для дебага:

Теперь можем запускать дебаг из меню run настроек шторма:

По идее должны увидеть следующее:

Дело в том, что шторм использует php и конфиг тот который существует в системе Mac OS, а не тот что мы указали. Тем не менее он копирует конфиг нашего PHP внутрь текущего в Mac OS. Хоть на этом, спасибо!

Теперь чтобы всё заработало надо перезагрузить обычный апач:

Также перезайдите в проект шторма, иначе может не заработать.

И теперь наконец всё работает!

Кстати, если мы запустим php файл с функцией phpinfo() то рядом с Zend Engine увидим наш дебаг:

В шторме должно быть все зелененькое:

В браузере должно быть установлено расширение для дебага (в хроме Xdebug helper) и тоже включено:

В проекте PhpStorm должны быть проставлены breakpoint. Затем при перезагрузки страницы и с включенными настройками выше, откроется дебаг в шторме.

Теперь включаем трубку. А если она была включена, сначала выключить, потом включить. Перезагрузить страницу, не забыв поставить брейкпоинты. Если при загрузке страницы код попадет в брейкпоинт, то откроется программа phpStorm с такой табличкой:

Выбираем как на скрине выше и нажимаем сохранить. Эта табличка возникает только в первый раз.

На этом все. Наслаждаемся дебаггером.

Профилирование

Профилирование такая штука, которая показывает весь путь и все происходящие события при загрузки страницы.

Одновременно с установленным дебагом, мы также настроили профилирование. Оно жрет очень много памяти и ресурсов и его можно отключить в настройках php.ini.

У меня выше в настройках он был закомментирован, но если хотите запустить его, уберите точки с запятой:

; xdebug.profiler_enable=1
; xdebug.profiler_output_dir=»/Users/Dream/Sites/_xdebug-profiler/»

Во второй строке указан путь куда будут сохраняться файлы профилирования, которые можно посмотреть через шторм, вкладка Tools.

Открываем файл с профилированием:

И потом наслаждаемся переплетением функций, событий и что там у вас будет еще.

Понравилась статья? Поделить с друзьями:
  • Pecl error make failed
  • Pea dow error 997 fix exe
  • Pdr region does not exist как исправить
  • Pdr region does not exist error 25
  • Pdoexception sqlstate hy000 general error 2006 mysql server has gone away