115

When running composer diagnose, I get the following error :

The xdebug extension is loaded, this can slow down Composer a little. Disabling it when using Composer is recommended.

How can I disable xdebug only when I'm running Composer?

leek
  • 11,803
  • 8
  • 45
  • 61
greg0ire
  • 22,714
  • 16
  • 72
  • 101

18 Answers18

104

Update: For Xdebug 3+:

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 $@
Joyce Babu
  • 19,602
  • 13
  • 62
  • 97
  • 3
    This is by far the most elegant solution to the problem, IMHO. Thanks Joyce! – Thomas Hansen Jun 13 '16 at 08:08
  • 2
    Best. Script. Ever – Maciej Paprocki Jul 25 '16 at 10:39
  • 1
    I had to adjust the shebang to `bin/bash` rather than `/bin/sh`, as the latter did not like the `function` keyword (Ubuntu 14.04 LTS). – ashnazg Dec 18 '16 at 15:27
  • 1
    I have updated the code and removed the function keyword, for better compatibility. – Joyce Babu Dec 19 '16 at 06:44
  • at my ubuntu distribution it for some reason didn't work and there stayed some xdebug occurences, so I add after main long awk line this `sed -i '/xdebug/d' .$temporaryPath` having it then exactly as supposed to, thank you – FantomX1 Mar 06 '18 at 16:44
  • you imply in newest composer version it is performing better along xdebug? I think I have the newest composer, I had very strong feeling testing it, maybe placebo, that using this your script was even faster then than commenting xdebug myself, normally I was waiting like 20 minutes, with your script it was finished under 30 seconds – FantomX1 Mar 07 '18 at 07:33
  • 1
    You can confirm that you are running the latest version by running `composer self-update` – Joyce Babu Mar 07 '18 at 07:36
  • 1
    New composer version definitely still has this issue, at least in my docker container it does – Shardj Nov 07 '18 at 17:29
80

This command will disable the PHP5 Xdebug module for CLI (and thus composer) :

sudo php5dismod -s cli xdebug

It removes the xdebug.ini symlink from /etc/php5/cli/conf.d/

This was suggested on http://blog.lorenzbausch.de/2015/02/10/php-disable-xdebug-for-cli/

Note that for Ubuntu 16.04 you probably need to run it like this:

sudo phpdismod -s cli xdebug
kleinfreund
  • 6,546
  • 4
  • 30
  • 60
ruleant
  • 950
  • 1
  • 6
  • 4
  • 4
    I've added the two aliases `alias xdebug-on='sudo php5enmod -s cli xdebug'` and `alias xdebug-off='sudo php5dismod -s cli xdebug'`, so it's now easy to enable `xdebug-on` and disable `xdebug-off` xdebug. – Daniel Mecke Feb 28 '16 at 09:23
  • Not portable. Probably Linux-only. – Diti Feb 28 '16 at 12:52
  • Works great on Laravel Homestead box (Ubuntu/Debian). A longer description of how it works: https://laracasts.com/discuss/channels/forge/disable-xdebug – Justin Apr 12 '16 at 15:29
  • 2
    thanks for this :) but I have ubuntu 16.04 and if someone will need to use this just run sudo phpdismod -s cli xdebug – Angel M. May 20 '16 at 17:54
  • How about php7 in ubuntu? Do I only need to remove the symlink ? /etc/php/7.0/cli/conf.d – gastonnina Sep 10 '16 at 03:32
  • Not portable beyond standard deployments of some debian/ubuntu releases. Even on these releases, using an alternate version like the Ondrej Sury PPA will need other commands. Other Linux like CentOS/Readhat don't have it either, nor macOS or Windows. – FGM Sep 16 '16 at 09:02
  • If you have multiple php versions use sudo phpdismod -v 7.xx -s cli xdebug (change xx to your subversion i.e. 7.4) – Omar Alahmed Mar 15 '21 at 20:03
41

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
Gui-Don
  • 1,366
  • 11
  • 25
  • I tried `-n` yesterday and had a problem because I was missing the `phar` extension. I'll try adding more and more extension until it works, I think this is a good solution. As per the alias, I have already some zsh aliases that I don't maintain. Maybe I'll try to replace the binary with a bash script, or see if I can configure the aliases. – greg0ire Jun 27 '15 at 09:58
  • The problem with this whitelist approach, though, is that the whitelist might grown depending on what people require in their `composer.json`, for instance "ext-ldap" : "*", or simply depending on what is needed to make the post install tasks run properly… If only there were a way to blacklist an extension… – greg0ire Jun 27 '15 at 10:25
  • 1
    I'll try to do something with the output of `php -m` – greg0ire Jun 27 '15 at 10:27
  • It comes to my mind, but, I assume you use xdebug in a development environment. Is composer so slow that it needs this tweak? – Gui-Don Jun 27 '15 at 13:11
  • Oh no, I just saw this from the output of `diagnose`, and since I'm building [development docker containers](https://github.com/greg0ire/dockerony) for my team, the smallest speed improvement could benefit to all of them – greg0ire Jun 27 '15 at 13:39
  • The difference is noticeable BTW. On a random project, I get 23.29s vs 37.65s . – greg0ire Jun 27 '15 at 13:43
  • I see. Unloading an extension at runtime would be great, but [it seems to be impossible](https://stackoverflow.com/questions/10715925/unloading-php-extensions-reverse-dl). Given the challenge, I think another solution is to create a lightweight .ini file with the strictly needed extensions and options, then load it explicitly with `--php-ini`. It’s a pain, but maybe better than maintaining this bash script. – Gui-Don Jun 27 '15 at 14:21
  • Yeah I thought of this other solution, could be indeed more robust, but also more likely to change and grow with all the extensions you install. In both cases, nothing really satisfying though… – greg0ire Jun 27 '15 at 15:07
  • on some distributions, there also is `phpenmod` / `phpdismod`. If I have that in my containers, I can easily write a wrapper for composer that takes care of xdebug. – greg0ire Jun 27 '15 at 15:14
  • Right but be careful, this is system-wide commands. If your PHP system is concurrent, other users running stuffs during the composer script execution could stumble on bad surprises... Although it’s not likely to happen, doing this sort a of tweaks a dozen times could make your server unstable for a user perspective. – Gui-Don Jun 27 '15 at 17:04
  • Indeed. In my case, it is for development purposes, so I don't think it can become that bad. – greg0ire Jun 27 '15 at 18:53
  • Warning: This will change the default memory_limit from -1 to 1024MB. I recommend adding -d memory_limit=-1 to php params – gadelat Jun 10 '16 at 11:54
19

You can disable Xdebug setting an environment variable:

XDEBUG_MODE=off composer install

It's available using XDebug 3.

greg0ire
  • 22,714
  • 16
  • 72
  • 101
xserrat
  • 1,429
  • 1
  • 13
  • 12
15

By creating an alias you'll suppress that composer xdebug error message.

Just add this line to your ~/.bash_aliases within your system and it should work flawlessly.

alias composer="php -n /usr/local/bin/composer"

Reload the shell to make the new alias composer available.

source ~/.bash_profile

USAGE:

$ composer --version

NOTE:
You don't necessarily need to use any other parameter.
Depending on your system you might have a .bashrc instead of .bash_profile.

UPDATE:

As @AlexanderKachkaev mention in the comments it's worth nothing to add the memory_limit as follows to avoid crashing im some situations:

alias composer="php -d memory_limit=-1 -n /usr/local/bin/composer"
Adriano Rosa
  • 8,303
  • 1
  • 25
  • 25
  • 3
    This won't play very nicely as soon as one of the extensions is needed in post install or post update scripts… might be a good solution on simple projects though. – greg0ire Feb 15 '16 at 10:00
  • 1
    The `-n` option disables `Phar` extension so it may fail to run from `composer.phar` – brzuchal Oct 06 '16 at 11:23
  • 1
    This worked for me. In addition, I disabled memory limit to avoid crashing: `alias composer="php -d memory_limit=-1 -n /usr/local/bin/composer"` – Alexander Kachkaev Oct 18 '16 at 21:36
  • This solution is pretty simple and workable for my situation. The memory limit suggestion from @AlexanderKachkaev is a must. Be good to edit the answer. – Henry Oct 31 '16 at 02:44
12

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":

#!/bin/sh

function php-no-xdebug {
    local temporaryPath="$(mktemp -t php-no-debug)"

    find /opt/local/etc/$1/php.ini /opt/local/var/db/$1/*.ini ! -name xdebug.ini | xargs cat > "$temporaryPath"
    php -n -c "$temporaryPath" "${@:2}"
    rm -f "$temporaryPath"
}

alias composer="php-no-xdebug php56 ~/bin/composer"
ezzatron
  • 779
  • 6
  • 15
9

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.

It looks like this (for php56)

#!/bin/sh
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

COMPOSER_DISABLE_XDEBUG_WARN=1 /opt/local/bin/php56 \
    -d xdebug.remote_enable=0 -d xdebug.profiler_enable=0 \
    -d xdebug.default_enable=0 $DIR/../composer.phar "$@"

The -d options effectively disable xdebug. The COMPOSER_DISABLE_XDEBUG_WARN=1 part disables the warning composer issues.

Disabling the xdebug extension is preferred (see composer troubleshooting), but I personally like the simpler script.

Some timings on my machine: 2 Run with xdebug and ini-enabled: 1m33

Run with xdebug but ini-disabled: 0m19

Run without xdebug: 0m10

Joost
  • 464
  • 4
  • 5
  • I think since you are disabling XDebug, you do not need the `COMPOSER_DISABLE_XDEBUG_WARN=1` : if you get a warning, it just means your scrit does not work. Defining `xdebug.remote_autostart` seems useless if remote debugging is disabled. – greg0ire Jan 12 '16 at 16:43
  • You're right about `xdebug.remote_autostart`. About the scripts effectiveness: Composer checks if the xdebug extension is loaded, not if it's actually doing anything [look at the code here](https://github.com/composer/composer/blob/master/src/Composer/Console/Application.php#L125). The ini options work fine in "regular" php scripts but again: I've done no performance tests... – Joost Jan 13 '16 at 19:27
  • (Finally) found the relevant part in the composer manual about this [troubleshooting: xdebug impact on composer](https://getcomposer.org/doc/articles/troubleshooting.md#xdebug-impact-on-composer). It explains that disabling all xdebug options through ini flags isn't enough to mitigate the performance issues. So my script won't work. Too bad! – Joost Jan 13 '16 at 19:52
  • I did some timing (on Mac OS X) and I must say I'm quite happy with the performance improvements using my script! With xdebug options **enabled** it takes _1m33_, with the options **disabled** it takes _0m19_. Without the xdebug extension it takes _0m10_. – Joost Jan 13 '16 at 22:07
  • Ok so there is an improvement anyway. Not the best available improvement, but a huge improvement nonetheless (at least on OS X) – greg0ire Jan 14 '16 at 09:18
7

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.

https://blog.jetbrains.com/phpstorm/2016/06/xdebug-on-demand-for-cli-php-scripts-in-phpstorm-2016-2-eap/

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.

scipilot
  • 6,681
  • 1
  • 46
  • 65
5

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

Using this in a script or build task is easy:

export PHP_INI_SCAN_DIR=/etc/php.d.noxdebug php composer install

Of course you would want to prepare /etc/php.d.noxdebug first, doing something like:

mkdir /etc/php.d.noxdebug cp /etc/php.d/* /etc/php.d.noxdebug rm /etc/php.d.noxdebug/xdebug.ini

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.

KHobbits
  • 506
  • 5
  • 7
  • I would use symlinks instead of just copying ini files. – greg0ire Oct 11 '16 at 19:39
  • 1
    I shied away from using symlinks because it gives the impression the folders are in sync, while new modules would not be automatically included in the 'noxdebug' folder. – KHobbits Oct 11 '16 at 20:07
4

Direct manipulation of PHP config

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.

j13k
  • 61
  • 5
  • I'm not sure that it would make a difference to how errors are handled by Composer—do you have a specific example or concern? The script is intended as a quick solution to the problem and hasn't been thoroughly battle-tested. Having said that, in the time I have been using it, it has worked without any problems. – j13k Feb 18 '16 at 22:29
  • 1
    My concern is that the last line of the script might not be run. – greg0ire Feb 19 '16 at 16:13
4

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:

https://github.com/composer/windows-setup/issues/58

You can find my instructions and code there.

mindplay.dk
  • 7,085
  • 3
  • 44
  • 54
4

As noted in Joyce's answer, this issue no longer exists in the latest version of Composer.

The Composer documentation has been updated to note this. It details how you can enable xdebug with Composer (if required).

You can update your version of Composer by utilising self-update.

On my Mac I had to do: sudo php /opt/local/bin/composer self-update

Further details about this in the context of a Homebrew PHP install can be found in this issue.

Community
  • 1
  • 1
Thomas Clowes
  • 4,529
  • 8
  • 41
  • 73
3

Creating an alias for composer to disable xdebug and prevent memory errors:

Add this line to your ~/.bash_profile

alias composer='php -d xdebug.profiler_enable=0 -d memory_limit=-1 /usr/local/bin/composer'

Restart the terminal to make the new alias available.

Matthias
  • 1,130
  • 10
  • 8
2

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.

Vazgen Manukyan
  • 1,410
  • 1
  • 12
  • 17
2

If you install composer using brew on OS X You can use this alias:

alias composer="php -n $(cat $(which composer) | grep composer.phar | awk '{print $7}')"
Bukashk0zzz
  • 343
  • 3
  • 13
1

My quick solution for a macports installation, with multiple versions of PHP was to write this simple shell wrapper for Composer:

/user/local/bin/composer-nodebug.sh

#!/bin/bash

sudo mv /opt/local/var/db/php53/xdebug.ini /opt/local/var/db/php53/xdebug.NOT
sudo mv /opt/local/var/db/php54/xdebug.ini /opt/local/var/db/php54/xdebug.NOT
sudo mv /opt/local/var/db/php55/xdebug.ini /opt/local/var/db/php55/xdebug.NOT
composer $1 $2 $3 $4 $5 $6 $7
sudo mv /opt/local/var/db/php53/xdebug.NOT /opt/local/var/db/php53/xdebug.ini
sudo mv /opt/local/var/db/php54/xdebug.NOT /opt/local/var/db/php54/xdebug.ini
sudo mv /opt/local/var/db/php55/xdebug.NOT /opt/local/var/db/php55/xdebug.ini

Then run any composer commands like so:

sudo composer-nodebug.sh update

Drawbacks:

  • requires sudo (unless you chmod the INI files)
  • if you kill it mid-way the INI files are modified
  • will require future PHP versions added.
  • while it's running other PHP processes are affected

Not elegant, but simple.

scipilot
  • 6,681
  • 1
  • 46
  • 65
  • I think there is shortcut you can use instead of `$1…$7`… maybe it's `$@` or something like that, you'll have to look. – greg0ire Jun 29 '16 at 21:57
  • > if you kill it mid-way the INI files are modified you kind fix that by trapping the kill signal > will require future PHP versions added. you can also fix that with a simple loop – greg0ire Jun 29 '16 at 21:57
0

(Windows)

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.

hejdav
  • 1,267
  • 15
  • 19
  • What makes you think that this is an issue? Since years, there's documentation about this: "To improve performance when the Xdebug extension is enabled, Composer automatically restarts PHP without it." (source: https://getcomposer.org/doc/articles/troubleshooting.md#xdebug-impact-on-composer) – Nico Haase Nov 04 '20 at 15:29
  • Yes, I read that the issue with composer & xdebug should already be solved, but in my case what I see is obvious. `composer install` with xdebug enabled takes forever, on the other hand same command with xdebug disabled works fine (I **have** latest composer). I tried to play with `COMPOSER_ALLOW_XDEBUG` but no effect. Maybe I am not solving the cause (of course if I knew the cause I would definitly focus on it), but the benefit is there and I believe it can help somebody. – hejdav Nov 04 '20 at 16:07
-3

Here is my quick solution to get rid off the Xdebug warning on PHP5-cli version. I have removed the support of Xdebug for PHP5-cli on Ubuntu 14.04.

cd /etc/php5/cli/conf.d/

sudo rm 20-xdebug.ini

Now no more Xdebug warning on PHP5-cli.

Community
  • 1
  • 1