The problem: XDebug doesn't work for Composer scripts
PhpStorm is quite convenient to debug scripts with XDebug (do you support Derick for giving us XDebug ?): just add a "Run/Debug configuration", choosing the "PHP Script" type, give a few parameters, and you can start debugging your PHP CLI scripts, using breakpoints, evaluations, etc.
Wonderful. So now, let's define such a configuration to debug a Composer script, say a Behat configuration generator from site settings for some current Drupal 8 project. Apply the configuration, run it in debug mode, and ....
...PhpStorm doesn't stop, the script runs and ends, and all breakpoints were ignored. How to actually use breakpoints in the IDE ?
The diagnostic
Let's see how Composer actually starts:Now, we can step through this, and notice the Composer script actually runs during the $xdebug->check();
line. What's going on ?
Here's the crux of the problem: in order to alleviate the extreme slowdown caused by XDebug when running Composer commands, any time Composer is run, it checks for the presence of Xdebug in the running PHP configuration, and if it finds it (the needsRestart()
check), it rebuilds a command line with a different PHP configuration ($command = $this->getCommand();
), which does not include the xdebug extension, and runs it in the $this->restart($command);
call, which actually runs the new command using the passthru
mechanism.
Now, since this command no longer runs with Xdebug, there is no way a debugging tool can use it. So how does one fix the problem ?
The solution
Let's go back to the beginning of this check()
method:
So the call to needsRestart($args[0]
does actually depend on the value of the XdebugHandler::ENV_ALLOW
constant, i.e. COMPOSER_ALLOW_XDEBUG
. Let's see.
So, if COMPOSER_ALLOW_XDEBUG
is not empty, needsRestart($allow)
will return FALSE
. In which case, as shown above, it won't cause the new command to be built, and Composer will just proceed with our script and allow our debugging to work.
In practice, this means all we need it to pass a COMPOSER_ALLOW_XDEBUG
environment variable with a non-empty value in the PhpStorm run configuration, like this.
Problem solved_! BTW, did you notice this was explained in the Composer vendor/composer/composer/doc/articles/troubleshooting.md
documentation ?
[...snip...] ## Xdebug impact on Composer To improve performance when the xdebug extension is enabled, Composer automatically restarts PHP without it. You can override this behavior by using an environment variable: `COMPOSER_ALLOW_XDEBUG=1`. [...more...]
Yeah, me neither, until I solved the problem as described. So let's all just keep in mind to RTFM.