Desativando xdebug ao executar composer

98

Ao executar composer diagnose, recebo o seguinte erro:

A extensão xdebug está carregada, o que pode tornar o Composer um pouco mais lento. Desativá-lo ao usar o Composer é recomendado.

Como posso desabilitar o xdebug apenas quando estou executando o Composer?

greg0ire
fonte

Respostas:

81

Atualização : O problema foi corrigido no Composer 1.3 . Atualize o composer para a versão mais recente executando composer self-update, em vez de tentar a seguinte solução alternativa.


Aqui está minha modificação do código de @ ezzatron. Eu atualizei o script para detectar arquivos ini da saída do phpinfo.

#!/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
fonte
3
Esta é de longe a solução mais elegante para o problema, IMHO. Obrigado Joyce!
Thomas Hansen
2
Melhor. Roteiro. Ever
Maciej Paprocki
1
Tive que ajustar o shebang para em bin/bashvez de /bin/sh, pois este último não gostou da functionpalavra - chave (Ubuntu 14.04 LTS).
ashnazg
Eu atualizei o código e removi a palavra-chave de função, para melhor compatibilidade.
Joyce Babu
1
Você pode confirmar que está executando a versão mais recente executandocomposer self-update
Joyce Babu
77

Este comando desabilitará o módulo PHP5 Xdebug para CLI (e, portanto, composer):

sudo php5dismod -s cli xdebug

Ele remove o link simbólico xdebug.ini de/etc/php5/cli/conf.d/

Isso foi sugerido em http://blog.lorenzbausch.de/2015/02/10/php-disable-xdebug-for-cli/

Observe que para o Ubuntu 16.04 você provavelmente precisará executá-lo desta forma:

sudo phpdismod -s cli xdebug
regra
fonte
4
Eu adicionei os dois aliases alias xdebug-on='sudo php5enmod -s cli xdebug'e alias xdebug-off='sudo php5dismod -s cli xdebug', então agora é fácil habilitar xdebug-one desabilitar o xdebug-offxdebug.
Daniel Mecke
Não é portátil. Provavelmente apenas Linux.
Diti
Funciona muito bem na caixa Laravel Homestead (Ubuntu / Debian). Uma descrição mais longa de como funciona: laracasts.com/discuss/channels/forge/disable-xdebug
Justin
2
obrigado por isso :) mas eu tenho ubuntu 16.04 e se alguém precisar usar isso, basta executar sudo phpdismod -s cli xdebug
Angel M.
Que tal php7 no ubuntu? Preciso apenas remover o link simbólico? /etc/php/7.0/cli/conf.d
gastonnina
40

Não acho que haja uma opção para configurar o PHP para que ele possa carregar configurações diferentes de acordo com o script de destino. Pelo menos, não sem duplicar arquivos .ini ...

No entanto, você pode adicionar essas opções ao executar o composer com php:

php -n -d extension=needed_ext.so composer.phar

-nirá dizer ao PHP para ignorar qualquer php.ini. Isso evitará que o xdebug carregue para este comando.

-doptions permite que você adicione qualquer opção que desejar (por exemplo, ative needed_ext.so). Você pode usar várias -dopções. Claro, isso é opcional, você pode não precisar dele.

Depois, você pode criar um alias para torná-lo adocicado novamente.

Uma solução típica (porque o compositor precisa do json):

php -n -d extension=json.so composer.phar

greg0ire> minha solução, com base nisso:

#!/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

Parece feio (tentei e não consegui fazer isso com xargs), mas funciona ... Tive que desabilitar algumas extensões, caso contrário, recebo os seguintes avisos:

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
fonte
Tentei -nontem e tive um problema porque estava faltando a pharextensão. Vou tentar adicionar mais e mais extensões até funcionar, acho que é uma boa solução. De acordo com o alias, já tenho alguns aliases zsh que não mantenho. Talvez eu tente substituir o binário por um script bash ou ver se consigo configurar os aliases.
greg0ire
O problema com esta abordagem de lista branca, porém, é que a lista branca pode crescer dependendo do que as pessoas exigem em seu composer.json, por exemplo "ext-ldap": "*", ou simplesmente dependendo do que é necessário para fazer as tarefas pós-instalação funcionarem corretamente … Se ao menos houvesse uma maneira de colocar uma extensão na lista negra…
greg0ire
1
Vou tentar fazer algo com a saída dephp -m
greg0ire
Vem à minha mente, mas presumo que você use xdebug em um ambiente de desenvolvimento. O compositor é tão lento que precisa desse ajuste?
Gui-Don
Ah, não, acabei de ver isso na saída de diagnosee, como estou construindo contêineres docker de desenvolvimento para minha equipe, a menor melhoria na velocidade poderia beneficiar todos eles
greg0ire
14

Ao criar um alias, você suprimirá essa composer xdebugmensagem de erro.

Basta adicionar essa linha ao ~/.bash_aliasesseu sistema e ela deve funcionar perfeitamente.

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

Recarregue o shell para disponibilizar o novo alias composer.

source ~/.bash_profile

USO:

$ composer --version

NOTA:
Você não precisa necessariamente usar nenhum outro parâmetro.
Dependendo do seu sistema, você pode ter um em .bashrcvez de .bash_profile.

ATUALIZAR:

Como @AlexanderKachkaev mencionou nos comentários, não vale a pena adicionar o memory_limit da seguinte forma para evitar travar em algumas situações:

alias composer="php -d memory_limit=-1 -n /usr/local/bin/composer"
Adriano Rosa
fonte
3
Isso não funcionará muito bem assim que uma das extensões for necessária nos scripts de pós-instalação ou pós-atualização ... pode ser uma boa solução em projetos simples.
greg0ire de
1
A -nopção desativa a Pharextensão para que ele possa falhar ao executar a partir decomposer.phar
brzuchal 06/10/2016
1
Isso funcionou para mim. Além disso, desativei o limite de memória para evitar travamentos:alias composer="php -d memory_limit=-1 -n /usr/local/bin/composer"
Alexander Kachkaev
Esta solução é bastante simples e viável para minha situação. A sugestão de limite de memória de @AlexanderKachkaev é obrigatória. Seja bom editar a resposta.
Henry,
12

Eu encontrei uma resposta que funciona muito bem para OSX e provavelmente poderia ser adaptada para qualquer versão do PHP que carregue suas extensões usando arquivos .ini individuais no "diretório ini adicional":

#!/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"
ezatron
fonte
Ótimo! Eu criei um script de uso geral baseado nisso para Ubuntu 14.04-15.10 gist.github.com/perk11/816c4e64023ea26976cf
Konstantin Pereiaslov
Fantástico, funciona bem no Mac OS, no brew instalado no php 7.1. TY!
Antonio Carlos Ribeiro
7

Normalmente crio um script de shell por projeto, já que cada projeto tem outra versão do PHP. Ele está em um /bin/diretório próximo a composer.phare composer.jsone eu o executo como ./bin/composerno diretório do meu projeto.

É assim (para 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 "$@"

As -dopções desabilitam efetivamente o xdebug. A COMPOSER_DISABLE_XDEBUG_WARN=1parte desativa os problemas do compositor de aviso.

É preferível desativar a extensão xdebug (consulte a solução de problemas do compositor ), mas eu pessoalmente gosto do script mais simples.

Alguns intervalos na minha máquina: 2 Executar com xdebug e ini habilitado: 1m33

Executar com xdebug mas ini-disabled: 0m19

Executar sem xdebug: 0m10

Joost
fonte
Eu acho que já que você está desabilitando o XDebug, você não precisa COMPOSER_DISABLE_XDEBUG_WARN=1: se você receber um aviso, isso significa apenas que seu scrit não funciona. Definir xdebug.remote_autostartparece inútil se a depuração remota estiver desativada.
greg0ire
Você está certo sobre xdebug.remote_autostart. Sobre a eficácia dos scripts: o Composer verifica se a extensão xdebug está carregada, e não se está realmente fazendo algo, olhe o código aqui . As opções ini funcionam bem em scripts php "normais", mas novamente: eu não fiz testes de desempenho ...
Joost
(Finalmente) encontrei a parte relevante no manual do compositor sobre esta solução de problemas: impacto do xdebug no compositor . Isso explica que desabilitar todas as opções xdebug por meio de sinalizadores ini não é suficiente para mitigar os problemas de desempenho. Portanto, meu script não funcionará. Que pena!
Joost
Eu fiz algum tempo (no Mac OS X) e devo dizer que estou muito feliz com as melhorias de desempenho usando meu script! Com as opções xdebug habilitadas , leva 1m33 , com as opções desabilitadas , leva 0m19 . Sem a extensão xdebug leva 0m10 .
Joost
Ok, então há uma melhoria de qualquer maneira. Não é a melhor melhoria disponível, mas uma grande melhoria, no entanto (pelo menos no OS X)
greg0ire
6

Se você usar o PHPStorm, a versão mais recente (2016.2) vem com um recurso para habilitar o XDebug para scripts CLI sob demanda, o que significa que você pode simplesmente desligar o XDebug globalmente em sua máquina de desenvolvimento. O IDE o habilitará rapidamente quando for necessário para o código dentro de seus projetos.

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

PhpStorm 2016.2 introduz o modo Xdebug On Demand onde você pode desabilitar o Xdebug para sua instalação PHP global, e PhpStorm só o habilitará quando for necessário - quando você estiver depurando seus scripts, ou quando precisar de relatórios de cobertura de código.

Você precisa editar suas preferências de intérpretes PHP para incluir o caminho para o XDebug, conforme descrito no artigo vinculado.

Para mim, esta parece ser a solução perfeita, já que normalmente só quero o XDebug enquanto estou no IDE.

No entanto, o XDebug tem outros usos potenciais quando você está "offline", por exemplo, despejos de pilha estendidos em logs de erro, que você perderia desligando-o globalmente. É claro que você não deve ter o XDebug habilitado na produção, portanto, isso seria limitado a casos de uso como testes beta ou scripts CLI de teste automatizado em desenvolvimento.

cipiloto
fonte
5

Em vez de se confundir com a ativação ou desativação temporária do módulo PHP, quando você pode ter processos simultâneos usando PHP (por exemplo, como parte de um pipeline de CI), você pode dizer ao PHP para apontar para um diretório de carregamento de módulo diferente.

Embora seja semelhante a algumas das soluções mencionadas acima, isso resolve alguns casos extremos, o que é muito útil quando usado pelo Jenkins ou outro executor de CI que executa testes na mesma máquina simultaneamente.

A maneira mais fácil de fazer isso é usar a variável de ambiente PHP_INI_SCAN_DIR

Usar isso em um script ou tarefa de construção é fácil:

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

Claro que você gostaria de preparar /etc/php.d.noxdebug primeiro, fazendo algo como:

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

Isso significa que você tem um ambiente semelhante ao antigo ambiente php, com apenas um módulo faltando. Significa que você não precisa se preocupar em carregar os módulos phar / json como faria com a solução php -n.

KHobbits
fonte
Eu usaria links simbólicos em vez de apenas copiar arquivos ini.
greg0ire,
1
Evitei usar links simbólicos porque dá a impressão de que as pastas estão sincronizadas, enquanto os novos módulos não seriam incluídos automaticamente na pasta 'noxdebug'.
KHobbits
4

Eu vim com uma solução para o instalador do Composer baseado no Windows - ele deve funcionar para qualquer instalação do Composer, ele basicamente faz uma cópia do arquivo INI carregado e comenta a extensão zend do xdebug, então carrega o arquivo de configuração quando executa o composer .

Abri um problema para ver se eles gostariam de integrar essa mudança:

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

Você pode encontrar minhas instruções e código lá.

mindplay.dk
fonte
Simples e eficaz :) Você precisa aplicar isso novamente depois de atualizar o compositor por meio de autoatualização?
marcovtwout
4

Conforme observado na resposta de Joyce , esse problema não existe mais na versão mais recente do Composer.

A documentação do Composer foi atualizada para observar isso . Ele detalha como você pode habilitar o xdebug com o Composer (se necessário).

Você pode atualizar sua versão do Composer utilizando a atualização automática .

No meu Mac, tive que fazer: sudo php /opt/local/bin/composer self-update

Mais detalhes sobre isso no contexto de uma instalação do Homebrew PHP podem ser encontrados nesta edição .

Thomas Clowes
fonte
Isso é ótimo! Você sabe onde está o PR para essa mudança? Eu preciso disso em outro aplicativo CLI
Tomáš Votruba
3

Manipulação direta da configuração do PHP

Aqui está minha contribuição com base em uma instalação do PHP instalado no Homebrew no Mac OS X.

É um wrapper de script de shell, projetado para ser salvo como um arquivo executável em /usr/local/bin/composer , com o binário do Composer em /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

Teoria de Operação

O script de wrapper:

  • usa sed para modificar temporariamente o arquivo de configuração, desabilitando o Xdebug (linha 2)
  • executa o Composer, passando por args para o comando (linha 3)
  • usa sed para restaurar o arquivo de configuração, reativando o Xdebug (linha 4)

O script é acoplado a uma instalação OS X / Homebrew do PHP 5.5. Os caminhos devem ser ajustados para funcionar com outras versões do PHP e layouts de diretório de outros sistemas operacionais e gerenciadores de pacotes. Observe também que algumas versões do sed não precisam do argumento de string vazia após o-i opção.

Caveat Utilitor

O script é simples, pois funciona diretamente nos principais arquivos de configuração do PHP, no entanto isso também é uma desvantagem: o Xdebug também será desabilitado para quaisquer scripts que sejam executados simultaneamente com este script.

Em meu ambiente de desenvolvimento, essa é uma compensação aceitável, visto que o Composer é executado manualmente e apenas ocasionalmente; entretanto, você pode não querer usar esta técnica se estiver executando o Composer como parte de um processo de implantação automatizado.

j13k
fonte
Não tenho certeza se isso faria diferença em como os erros são tratados pelo Composer - você tem um exemplo ou preocupação específica? O script pretende ser uma solução rápida para o problema e não foi totalmente testado em batalha. Dito isto, desde que o utilizei, funcionou sem problemas.
j13k
1
Minha preocupação é que a última linha do script pode não ser executada.
greg0ire
2

Na maioria dos casos, você não precisa do xdebug no modo CLI. Se isso for aceitável para você, você pode configurar cli e cgi de forma diferente.

Portanto, se você criar php-cli.ini e conf-cli.d perto de sair do arquivo php.ini, poderá configurar cli e cgi de forma diferente (para cgi seriam php.ini e conf.d ). Apenas não coloque xdebug.ini em conf-cli.d.

Vazgen Manukyan
fonte
2

Se você instalar o composer usando o brew no OS X, você pode usar este alias:

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

Minha solução rápida para uma instalação macports, com várias versões do PHP, foi escrever este invólucro de shell simples para o 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

Em seguida, execute quaisquer comandos do compositor como:

sudo composer-nodebug.sh update

Desvantagens:

  • requer sudo (a menos que você use chmod para os arquivos INI)
  • se você matá-lo no meio do caminho, os arquivos INI são modificados
  • exigirá a adição de futuras versões do PHP.
  • enquanto está sendo executado, outros processos PHP são afetados

Não é elegante, mas simples.

cipiloto
fonte
Acho que existe um atalho que você pode usar em vez de $1…$7... talvez seja $@ou algo parecido, você terá que procurar.
greg0ire
> se você eliminá-lo no meio do caminho, os arquivos INI são modificados, você pode consertar isso ao capturar o sinal de eliminação> exigirá a adição de futuras versões do PHP. você também pode consertar isso com um loop simples
greg0ire
1

Criação de um alias para o composer para desativar o xdebug e evitar erros de memória:

Adicione esta linha ao seu ~ / .bash_profile

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

Reinicie o terminal para disponibilizar o novo alias.

Matthias Schobner
fonte
-3

Aqui está minha solução rápida para me livrar do aviso do Xdebug na versão PHP5-cli. Removi o suporte do Xdebug para PHP5-cli no Ubuntu 14.04.

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

sudo rm 20-xdebug.ini

Agora não há mais aviso Xdebug no PHP5-cli.

Milin Mestry
fonte
2
sudo phpdismod xdebugseria o método preferido para bruterm
Jeff Puckett