I don’t think there is an option to configure PHP so it can load different configurations according to the targeted script. At least, not without duplicating .ini files...
However, you can add thoses options when running composer with php:
php -n -d extension=needed_ext.so composer.phar
-n will tell PHP to ignore any php.ini. This will prevent xdebug from loading for this very command.
-d options permits you to add any option you want (for exemple, activate needed_ext.so). You can use multiple -d options. Of course, this is optional, you might not need it.
Then you can create an alias, to make it sugary again.
A typical solution (because composer needs json):
php -n -d extension=json.so composer.phar
greg0ire > my solution, based on that:
#!/bin/bash
options=$(ls -1 /usr/lib64/php/modules| \
grep --invert-match xdebug| \
# remove problematic extensions
egrep --invert-match 'mysql|wddx|pgsql'| \
sed --expression 's/\(.*\)/ --define extension=\1/'| \
# join everything together back in one big line
tr --delete '\n'
)
# build the final command line
php --no-php-ini $options ~/bin/composer $*
alias composer=/path/to/bash/script.sh
It looks ugly (I tried and failed to do that with xargs), but works… I had to disable some extensions though, otherwise I get the following warnings:
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/mysqli.so' - /usr/lib64/php/modules/mysqli.so: undefined symbol: mysqlnd_connect in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/pdo_mysql.so' - /usr/lib64/php/modules/pdo_mysql.so: undefined symbol: pdo_parse_params in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/pdo_pgsql.so' - /usr/lib64/php/modules/pdo_pgsql.so: undefined symbol: pdo_parse_params in Unknown on line 0
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/wddx.so' - /usr/lib64/php/modules/wddx.so: undefined symbol: php_XML_SetUserData in Unknown on line 0
I came up with an answer that works pretty well for OSX, and could probably be adapted for any PHP version that loads its extensions using individual .ini files in the "additional ini dir":
I usually create a shell script per project, since every project has another PHP version. It's in a /bin/ directory next to composer.phar and composer.json and I run it as ./bin/composer in my project directory.
Here's my contribution based on a Homebrew-installed PHP installation on Mac OS X.
It's a shell-script wrapper, designed to be saved as an executable file at /usr/local/bin/composer, with the Composer binary at /usr/local/bin/composer.phar:
#!/bin/sh
sed -i '' -e 's:zend_extension="/usr/local/opt/php55-xdebug/xdebug.so":;zend_extension="/usr/local/opt/php55-xdebug/xdebug.so":' /usr/local/etc/php/5.5/conf.d/ext-xdebug.ini
/usr/local/bin/php /usr/local/bin/composer.phar "$@"
sed -i '' -e 's:;zend_extension="/usr/local/opt/php55-xdebug/xdebug.so":zend_extension="/usr/local/opt/php55-xdebug/xdebug.so":' /usr/local/etc/php/5.5/conf.d/ext-xdebug.ini
Theory of Operation
The wrapper script:
uses sed to temporarily modify the configuration file, disabling Xdebug (line 2)
executes Composer, passing through args to the command (line 3)
uses sed to restore the configuration file, re-enabling Xdebug (line 4)
The script is coupled to an OS X/Homebrew installation of PHP 5.5. The paths should be adjusted to work with other PHP versions and other operating systems' and package managers' directory layouts. Note also that some versions of sed do not need the empty-string argument following the -i option.
Caveat Utilitor
The script is straightforward, in that it works directly on the main PHP configuration files, however this is also a drawback: Xdebug will also be disabled for any scripts that happen to be executed concurrently with this script.
In my development environment, this is an acceptable trade-off, given that Composer is executed manually and only occasionally; however you may not want to use this technique if executing Composer as part of an automated deployment process.
As of Xdebug 3, it is possible to disable the Xdebug completely by setting the option xdebug.mode to off, or by setting the environment variable XDEBUG_MODE=off.
It is very easy to disable Xdebug just for composer, by aliasing composer.
alias composer='XDEBUG_MODE=off \composer'
OR
alias composer='php -dxdebug.mode=off $(where composer | fgrep -v composer: | head -1)'
You can add the alias to your $HOME/.bashrc to make it permanent.
Update: For Xdebug 1.3 - 3.0.0 :
The issue has been fixed in Composer 1.3. Update composer to the latest version by executing composer self-update, instead of trying the following workaround.
For Xdebug < 1.3
Here is my modification of @ezzatron's code. I have updated the script to detect ini files from phpinfo output.
#!/bin/sh
php_no_xdebug () {
temporaryPath="$(mktemp -t php.XXXX).ini"
# Using awk to ensure that files ending without newlines do not lead to configuration error
php -i | grep "\.ini" | grep -o -e '\(/[a-z0-9._-]\+\)\+\.ini' | grep -v xdebug | xargs awk 'FNR==1{print ""}1' | grep -v xdebug > "$temporaryPath"
php -n -c "$temporaryPath" "$@"
rm -f "$temporaryPath"
}
php_no_xdebug /usr/local/bin/composer.phar $@
# On MacOS with composer installed using brew, comment previous line
# Install jq by executing `brew install jq` and uncomment following line.
# php_no_xdebug /usr/local/Cellar/composer/`brew info --json=v1 composer | jq -r '.[0].installed[0].version'`/libexec/composer.phar $@
In most cases you do not need xdebug on CLI mode. If this is acceptable for you than you can configure cli and cgi differently.
So if you make php-cli.ini and conf-cli.d near exiting php.ini file than you can configure cli and cgi differently (for cgi it would be php.ini and conf.d). Just do not put xdebug.ini into conf-cli.d.
I came up with a solution for the Windows-based Composer installer - it should work for any Composer installation, it just basically makes a copy of the loaded INI file and comments out the xdebug zend extension, then loads that configuration file when it runs composer.
I've opened an issue to see if they'd like to integrate this change:
If you use PHPStorm, the latest release (2016.2) comes with a feature to enable XDebug for CLI scripts on-demand, which means you can simply turn off XDebug globally on your development machine. The IDE will enable it on the fly when it is needed by code inside your projects.
PhpStorm 2016.2 introduces Xdebug On Demand mode where you can disable Xdebug for your global PHP install, and PhpStorm will only enable it when it needs to — when you’re debugging your scripts, or when you need code coverage reports.
You need to edit your PHP Interpreters preferences to include the path to XDebug, as described in the linked article.
To me this seems like the perfect solution, as I only usually want XDebug while I'm in the IDE.
However XDebug does have other potential uses when you are "offline" e.g. extended stack dumps in error logs, which you would lose by turning it off globally. Of course you shouldn't have XDebug enabled on production, so this would be limited to use cases like beta-testing or automated-testing CLI scripts in development.
Rather than muddle with temporarily enabling or disabling the PHP module, when you might have concurrent processes using PHP (for example as part of a CI pipeline), you can tell PHP to point at a different module loading directory.
While this is similar to some of the solutions mentioned above, this solves a few edge cases, which is very useful when being used by Jenkins or other CI runner which runs tests on the same machine concurrently.
The easiest way to do this is to use the environment variable PHP_INI_SCAN_DIR
This means you have an environment similar to the old php environment, with only one module missing. Meaning you don't need to worry about needing to load the phar/json modules as you would with the php -n solution.
Based on documentation I use environment variable PHPRC, so I can choose which INI file shloud be loaded, thus I can choose whether I want to enable or disable Xdebug before executing a command (like composer install).
I have two INI files, one with Xdebug enabled (php-xdebug.ini) and one with Xdebug disabled (php.ini - it's also default one).
I use some batches (placed in location which is included in PATH environment variable, so it can be executed from anywhere):
To enable Xdebug I call xon.bat:
@ECHO OFF
set PHPRC=C:/path-to-php/php-xdebug.ini
To disable Xdebug I call xoff.bat:
@ECHO OFF
set PHPRC=
By calling php --ini I can check which INI file was loaded.
Alternatively you can use environment variable PHP_INI_SCAN_DIR in which you set a path to directory from where additional INI files will be loaded. Advantage is that you can load multiple INI files.