If you want to speed up Xdebug PHP development, keep on reading.

Xdebug

What's the problem?

Locally we develop in a Docker environment. Standard we use custom optimized NGINX, PHP & MySQL containers. This is usually extended with specific containers depending on the project.

The use of Xdebug is very useful in development. All our local PHP containers have this module on by default.
The big disadvantage is that it is very resource-heavy and therefore slows down the loading time of your page, even if you don't have the debugger enabled in PHPStorm, which is most of the time.

How can we optimize this?

In an ideal scenario, we only load the Xdebug module when we need it, not for all other requests.

A solution for this is to use 2 PHP containers. 1 with and 1 without the Xdebug module enabled. This way we can use the 'faster' php container if we don't need Xdebug and switch to the PHP Xdebug container if we want to debug effectively.

By using a cookie we can use NGINX to indicate which PHP container we want to use.

Use two PHP containers

In addition to our standard PHP container called php, we are creating a new container called php-dev. Both containers load different Docker images, namely:

  • php container uses a PHP Docker image without Xdebug
  • php-dev container uses a PHP Docker image with the Xdebug module enabled

Example

services:
  php:
    image: some.docker.hub/php:7.3-fpm
  php-dev:
    image: some.docker.hub/php:7.3-fpm-dev

 

NGINX configuration

The magic takes place in NGINX. In our configuration we listen to whether or not a cookie has been placed.
If this is the case, we can address our php-dev container, otherwise we send the request to our default php container without Xdebug.

Next snippet is placed at the top of your nginx configuration file. This sets a $domainService variable with default php, this is also the hostname of our PHP container. As soon as a cookie with value XDEBUG_ is found, $domainService will get the value php-dev, the hostname of our Xdebug PHP container.

map $http_cookie $domainService {
  default php;
  "~*XDEBUG_" php-dev;
}

In our previous configurations we gave a standard address for our FastCGI server, namely php (the hostname of our container).

fastcgi_pass php:9000;

In the new situation we change this by our $domainService variable.

fastcgi_pass $domainService:9000;

 

What about Apache?

If for some reason you have an application that uses Apache (requirements, Shibboleth, ...) this solution is also a possibility.

Within your <VirtualHost> tag, add the following

<FilesMatch \.php$>
    # Redirect to php-dev container with Xdebug loaded
    <If "%{HTTP_COOKIE} =~ /XDEBUG_/">
        SetHandler proxy:fcgi://php-dev:9000
    </If>
    <Else>
        SetHandler proxy:fcgi://php:9000
    </Else>
</FilesMatch>

 

Xdebug helper browser plugin

Browser plugin

First install the Xdebug helper plugin in Chrome and/or Firefox.

Via the plugin settings you add a custom ide key, in our case "XDEBUG_".

Don't forget

If you switch between debugging and non-debugging in your browser, you will also get a different session each time you use a different container.

So if you need to debug behind authentication, you first need to enable the xdebug helper in the browser. Now you have a new session in which you can log in.

Conclusion

By using this implementation, our pages load more than twice as fast when we are not debugging, which saves a considerable amount of time. We have the best of both worlds, Xdebug when needed and fast response times during development.

Looking for PHP experts? We are Belgium's finest.