laminas / laminas-cli

Console command runner, exposing commands written in Laminas MVC and Mezzio components and applications
https://docs.laminas.dev/laminas-cli
BSD 3-Clause "New" or "Revised" License
55 stars 23 forks source link

Disable xdebug extension before executing any command #40

Closed boesing closed 4 years ago

boesing commented 4 years ago

Feature Request

Q A
New Feature yes
RFC yes
BC Break no

Summary

I am using laminas-cli to parse some files with nikic/php-parser and ran into xdebug errors due to reaching the maximum nesting level which is per-default 256. As a quickfix, I'd run laminas-cli with php -n to avoid loading any extension, but I dont really want to use this in the commands description.

There are libs like composer/xdebug-handler which are used by composer aswell.

I'd like to propose this library to be implemented in laminas-cli directly.

Ocramius commented 4 years ago

I don't think the library should mess with the execution environment at all

geerteltink commented 4 years ago

I agree, xdebug shouldn't be disabled by this component. Can't you configure xdebug in such way that it doesn't start automatically from cli, only when setting a env var?

boesing commented 4 years ago

I don't think the library should mess with the execution environment at all

I know that messing with executing environment is not recommended, but I dont see a better way in having this problem solved. 🤷‍♂️

Can't you configure xdebug in such way that it doesn't start automatically from cli, only when setting a env var?

If xdebug extension is added to php.ini, there is no way to remove it in runtime or enable/disable it with an environment variable. Even in other SAPIs you can only trigger debugging itself with an environment variable. All xdebug.max_* settings and their consumers are registered even without that environment stuff...

Disabling xdebug makes a huge difference in performance when executing a command with nikic/php-parser.

However, there is a reason why composer added it to its binary. I can change the xdebug.max_nesting_level ini setting in my command but that will still keep xdebug enabled and thus the command consuming more CPU and memory than it should.

I know, there were performance improvements in xdebug lately, so "probably" this wont be an issue in the future.

with xdebug enabled

→ time php vendor/bin/laminas migration:phpstorm-extended-meta vendor/ .phpstorm.meta.php/laminas-migration.meta.php
Using /usr/local/opt/php@7.3/bin/php

real    0m16.493s
user    0m15.980s
sys     0m0.393s

with xdebug disabled

→ time php -n vendor/bin/laminas migration:phpstorm-extended-meta vendor/ .phpstorm.meta.php/laminas-migration.meta.php
Using /usr/local/opt/php@7.3/bin/php

real    0m2.685s
user    0m2.423s
sys     0m0.270s
boesing commented 4 years ago

Psalm uses the composer xdebug handler aswell (and extending it with some own stuff).

https://github.com/vimeo/psalm/blob/master/src/psalm.php#L425 https://github.com/vimeo/psalm/blob/master/src/Psalm/Internal/Fork/PsalmRestarter.php

weierophinney commented 4 years ago

@Ocramius and @geerteltink —

I didn't understand what the reference to composer/xdebug-handler was about, and so decided to look into the package.

Essentially, it grabs the current INI configuration, determines if XDebug is enabled, and, if so, toggles it off and dumps the INI to a temp file, which it then passes to the PHP executable in order to re-run its process.

There's one more bit to it, though: you can use an env variable to keep XDebug enabled if desired (generally named {your app}_ALLOW_XDEBUG).

The majority of what laminas-cli targets will not benefit from XDebug, so having it disabled by default makes a ton of sense. But if you do want it, I like the idea of being able to use an env variable, as that's easily scriptable (e.g., in composer.json, you could do a script as follows: LAMINAS_ALLOW_XDEBUG=1 laminas some:command).

This approach gives us both the performance benefits, and the ability to use XDebug when desired. As such, I'm :+1:.

weierophinney commented 4 years ago

So, based on:

I think we should close this issue, as it will be resolved elsewhere. In the meantime, you can create a wrapper for the laminas binary that disables affected INI settings:

php -d xdebug.max_nesting_level=-1 vendor/bin/laminas "$@"

(or create a command that proxies to vendor/bin/laminas by first using the composer/xdebug-handler functionality)

Ocramius commented 4 years ago

Careful! I only opened this against the 3.x branch of Xdebug (for now)!