Como você depura scripts PHP?[fechado]
Pergunta
Como você depura PHP roteiros?
Estou ciente da depuração básica, como usar o Relatório de Erros.A depuração do ponto de interrupção em PHPEclipse também é bastante útil.
O que é melhor (em termos de maneira rápida e fácil) de depurar no phpStorm ou qualquer outro IDE?
Solução
Tentar Eclipse PDT para configurar um ambiente Eclipse que possua recursos de depuração como você mencionou.A capacidade de entrar no código é uma maneira muito melhor de depurar o método antigo de var_dump e imprimir em vários pontos para ver onde seu fluxo está errado.Quando tudo mais falha e tudo que tenho é SSH e vim, ainda var_dump()
/die()
para descobrir onde o código vai para o sul.
Outras dicas
Você pode usar o Firephp, um complemento do firebug para depurar o php no mesmo ambiente do javascript.
Eu também uso Xdebug mencionado anteriormente para criar perfis de php.
Este é meu pequeno ambiente de depuração:
error_reporting(-1);
assert_options(ASSERT_ACTIVE, 1);
assert_options(ASSERT_WARNING, 0);
assert_options(ASSERT_BAIL, 0);
assert_options(ASSERT_QUIET_EVAL, 0);
assert_options(ASSERT_CALLBACK, 'assert_callcack');
set_error_handler('error_handler');
set_exception_handler('exception_handler');
register_shutdown_function('shutdown_handler');
function assert_callcack($file, $line, $message) {
throw new Customizable_Exception($message, null, $file, $line);
}
function error_handler($errno, $error, $file, $line, $vars) {
if ($errno === 0 || ($errno & error_reporting()) === 0) {
return;
}
throw new Customizable_Exception($error, $errno, $file, $line);
}
function exception_handler(Exception $e) {
// Do what ever!
echo '<pre>', print_r($e, true), '</pre>';
exit;
}
function shutdown_handler() {
try {
if (null !== $error = error_get_last()) {
throw new Customizable_Exception($error['message'], $error['type'], $error['file'], $error['line']);
}
} catch (Exception $e) {
exception_handler($e);
}
}
class Customizable_Exception extends Exception {
public function __construct($message = null, $code = null, $file = null, $line = null) {
if ($code === null) {
parent::__construct($message);
} else {
parent::__construct($message, $code);
}
if ($file !== null) {
$this->file = $file;
}
if ($line !== null) {
$this->line = $line;
}
}
}
Xdebug e o plugin DBGp para Notepad++ para caça a bugs pesados, FirePHP para coisas leves.Rapido e sujo?Nada supera dBug.
XDebug é essencial para o desenvolvimento.Eu instalo antes de qualquer outra extensão.Fornece rastreamentos de pilha em qualquer erro e você pode ativar a criação de perfil facilmente.
Para uma visão rápida de uma estrutura de dados, use var_dump()
.Não use print_r()
porque você terá que cercá-lo com <pre>
e imprime apenas uma var por vez.
<?php var_dump(__FILE__, __LINE__, $_REQUEST); ?>
Para um ambiente de depuração real, o melhor que encontrei é KomodoIDE mas custa $$.
PhpEd é muito bom.Você pode entrar/passar/sair das funções.Você pode executar código ad-hoc, inspecionar variáveis, alterar variáveis.É maravilhoso.
1) Eu uso print_r().No TextMate, tenho um trecho para 'pre' que se expande para isto:
echo "<pre>";
print_r();
echo "</pre>";
2) Eu uso o Xdebug, mas não consegui fazer a GUI funcionar corretamente no meu Mac.Pelo menos imprime uma versão legível do rastreamento de pilha.
Eu usei o Estúdio Zend (5.5), junto com Plataforma Zend.Isso fornece depuração adequada, pontos de interrupção/revisão do código, etc., embora tenha um preço.
Com toda a honestidade, uma combinação de print e print_r() para imprimir as variáveis.Sei que muitos preferem usar outros métodos mais avançados, mas acho este o mais fácil de usar.
Direi que não apreciei isso totalmente até fazer alguma programação de microprocessador na Uni e não conseguir usar nem isso.
Xdebug, de Derick Rethans, é muito bom.Usei-o há algum tempo e descobri que não era tão fácil de instalar.Quando terminar, você não entenderá como conseguiu sem ele :-)
Há um bom artigo sobre Zona de desenvolvedores Zend (instalar no Linux não parece mais fácil) e até um Plug-in do Firefox, que nunca usei.
Eu uso o Netbeans com XDebug.Confira em seu site a documentação sobre como configurá-lo.http://php.netbeans.org/
Eu uso o Netbeans com XDebug e o Complemento Easy XDebug FireFox
O complemento é essencial ao depurar projetos MVC, porque a forma normal de execução do XDebug no Netbeans é registrar a sessão dbug por meio da url.Com o complemento instalado no FireFox, você definiria as propriedades do seu projeto Netbeans -> Executar configuração -> Avançado e selecionaria "Não abrir o navegador da Web". Agora você pode definir seus pontos de interrupção e iniciar a sessão de depuração com Ctrl-F5 como de costume .Abra o FireFox e clique com o botão direito no ícone Add-on no canto inferior direito para iniciar o monitoramento de pontos de interrupção.Quando o código atingir o ponto de interrupção, ele será interrompido e você poderá inspecionar os estados das variáveis e a pilha de chamadas.
O buffer de saída é muito útil se você não quiser atrapalhar sua saída.Eu faço isso em uma linha que posso comentar/descomentar à vontade
ob_start();var_dump(); user_error(ob_get_contents()); ob_get_clean();
O PhpEdit possui um depurador integrado, mas geralmente acabo usando echo();e print_r();à moda antiga!!
Para os problemas realmente difíceis que consumiriam muito tempo para usar print_r/echo para descobrir, eu uso o recurso de depuração do meu IDE (PhpEd).Ao contrário de outros IDEs que usei, o PhpEd praticamente não requer configuração.a única razão pela qual não o uso para quaisquer problemas que encontro é que é dolorosamente lento.Não tenho certeza se a lentidão é específica do PhpEd ou de qualquer depurador de php.O PhpEd não é gratuito, mas acredito que ele use um dos depuradores de código aberto (como o XDebug mencionado anteriormente).O benefício do PhpEd, novamente, é que ele não requer nenhuma configuração que eu achei muito tediosa no passado.
A depuração manual geralmente é mais rápida para mim - var_dump()
e debug_print_backtrace()
são todas as ferramentas que você precisa para armar sua lógica.
Bem, até certo ponto, depende de onde as coisas estão indo para o sul.Essa é a primeira coisa que tento isolar e depois usarei echo/print_r() conforme necessário.
Observação:Vocês sabem que podem passar true como segundo argumento para print_r() e ele retornará a saída em vez de imprimi-la?Por exemplo.:
echo "<pre>".print_r($var, true)."</pre>";
Costumo usar o CakePHP quando o Rails não é possível.Para depurar erros eu costumo encontrar o error.log
na pasta tmp e siga-o no terminal com o comando...
tail -f app/tmp/logs/error.log
Ele permite que você execute uma caixa de diálogo sobre o que está acontecendo, o que é muito útil, se você quiser gerar algo no meio do código que você pode usar.
$this->log('xxxx');
Isso geralmente pode lhe dar uma boa ideia do que está acontecendo/errado.
print_r(debug_backtrace());
ou algo assim :-)
O Komodo IDE funciona bem com o xdebug, mesmo para depuração remota.Precisa de uma quantidade mínima de configuração.Tudo que você precisa é de uma versão do php que o Komodo possa usar localmente para percorrer o código em um ponto de interrupção.Se você tiver o script importado para o projeto komodo, poderá definir pontos de interrupção com um clique do mouse, exatamente como o configuraria dentro do Eclipse para depurar um programa Java.A depuração remota é obviamente mais complicada para que funcione corretamente (talvez você precise mapear o URL remoto com um script php em seu espaço de trabalho) do que uma configuração de depuração local que é muito fácil de configurar se você estiver em um desktop MAC ou Linux .
Nusphere também é um bom depurador para phpnusfera
Existem muitas técnicas de depuração de PHP que podem economizar inúmeras horas de codificação.Uma técnica de depuração eficaz, mas básica, é simplesmente ativar o relatório de erros.Outra técnica um pouco mais avançada envolve o uso de instruções de impressão, que podem ajudar a identificar bugs mais elusivos, exibindo o que realmente está acontecendo na tela.PHPeclipse é um plug-in do Eclipse que pode destacar erros comuns de sintaxe e pode ser usado em conjunto com um depurador para definir pontos de interrupção.
display_errors = Off
error_reporting = E_ALL
display_errors = On
e também usado
error_log();
console_log();
Em um ambiente de produção, registro dados relevantes no log de erros do servidor com error_log().
eu uso o zend studio para Eclipse com o depurador integrado.Ainda é lento em comparação com a depuração com eclipse pdt com xdebug.Esperançosamente, eles resolverão esses problemas, a velocidade melhorou em relação aos lançamentos recentes, mas ainda assim, ultrapassar as coisas leva de 2 a 3 segundos.A barra de ferramentas do Zend Firefox realmente facilita as coisas (depurar a próxima página, a página atual, etc.).Também fornece um criador de perfil que irá avaliar seu código e fornecer gráficos de pizza, tempo de execução, etc.
A maioria dos bugs pode ser encontrada facilmente simplesmente var_dump
algumas das principais variáveis, mas obviamente depende do tipo de aplicativo que você desenvolve.
Para algoritmos mais complexos, as funções step/breakpoint/watch são muito úteis (se não forem necessárias)
PHP DBG
O Interactive Stepthrough PHP Debugger implementado como um módulo SAPI que pode fornecer controle total sobre o ambiente sem afetar a funcionalidade ou o desempenho do seu código.Seu objetivo é ser uma plataforma de depuração leve, poderosa e fácil de usar para PHP 5.4+ e vem pronta para uso com PHP 5.6.
Os recursos incluem:
- Depuração passo a passo
- Pontos de interrupção flexíveis (método de classe, função, arquivo: linha, endereço, código de operação)
- Fácil acesso ao PHP com eval() integrado
- Fácil acesso ao código em execução atualmente
- API de usuário
- SAPI Agnóstico - Facilmente Integrado
- Suporte a arquivo de configuração PHP
- JIT Super Globals - Defina o seu próprio!!
- Suporte readline opcional - Operação confortável do terminal
- Suporte para depuração remota - GUI Java incluído
- Operação fácil
Veja as capturas de tela:
Pagina inicial: http://phpdbg.com/
Erro PHP - Melhor relatório de erros para PHP
Esta é uma biblioteca muito fácil de usar (na verdade, um arquivo) para depurar seus scripts PHP.
A única coisa que você precisa fazer é incluir um arquivo conforme abaixo (no início do seu código):
require('php_error.php');
\php_error\reportErrors();
Então, todos os erros fornecerão informações como backtrace, contexto de código, argumentos de função, variáveis de servidor, etc.Por exemplo:
Características incluem:
- trivial de usar, é apenas um arquivo
- erros exibidos no navegador para solicitações normais e ajaxy
- As solicitações AJAX são pausadas, permitindo que você as execute novamente automaticamente
- torna os erros o mais rigorosos possível (incentiva a qualidade do código e tende a melhorar o desempenho)
- trechos de código em todo o rastreamento de pilha
- fornece mais informações (como assinaturas completas de funções)
- corrige algumas mensagens de erro que estão simplesmente erradas
- realce de sintaxe
- parece bonito!
- costumização
- ligue e desligue manualmente
- execute seções específicas sem relatar erros
- ignore arquivos, permitindo evitar o destaque de código em seu rastreamento de pilha
- arquivos de aplicativos;eles são priorizados quando ocorre um erro!
Pagina inicial: http://phperror.net/
Github: https://github.com/JosephLenton/PHP-Error
Meu fork (com correções extras): https://github.com/kenorb-contrib/PHP-Error
DTrace
Se o seu sistema suportar Rastreamento dinâmico do DTrace (instalado por padrão no OS X) e seu PHP é compilado com os testes DTrace habilitados (--enable-dtrace
) que deveria ser o padrão, este comando pode ajudá-lo a depurar scripts PHP rapidamente:
sudo dtrace -qn 'php*:::function-entry { printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }'
Então, dado que o seguinte alias foi adicionado ao seu RC arquivos (por ex. ~/.bashrc
, ~/.bash_aliases
):
alias trace-php='sudo dtrace -qn "php*:::function-entry { printf(\"%Y: PHP function-entry:\t%s%s%s() in %s:%d\n\", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2); }"'
você pode rastrear seu script com um alias fácil de lembrar: trace-php
.
Aqui está um script dtrace mais avançado, basta salvá-lo em dtruss-php.d
, torne-o executável (chmod +x dtruss-php.d
) e corra:
#!/usr/sbin/dtrace -Zs
# See: https://github.com/kenorb/dtruss-lamp/blob/master/dtruss-php.d
#pragma D option quiet
php*:::compile-file-entry
{
printf("%Y: PHP compile-file-entry:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1));
}
php*:::compile-file-return
{
printf("%Y: PHP compile-file-return:\t%s (%s)\n", walltimestamp, basename(copyinstr(arg0)), basename(copyinstr(arg1)));
}
php*:::error
{
printf("%Y: PHP error message:\t%s in %s:%d\n", walltimestamp, copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::exception-caught
{
printf("%Y: PHP exception-caught:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::exception-thrown
{
printf("%Y: PHP exception-thrown:\t%s\n", walltimestamp, copyinstr(arg0));
}
php*:::execute-entry
{
printf("%Y: PHP execute-entry:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::execute-return
{
printf("%Y: PHP execute-return:\t%s:%d\n", walltimestamp, basename(copyinstr(arg0)), (int)arg1);
}
php*:::function-entry
{
printf("%Y: PHP function-entry:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::function-return
{
printf("%Y: PHP function-return:\t%s%s%s() in %s:%d\n", walltimestamp, copyinstr(arg3), copyinstr(arg4), copyinstr(arg0), basename(copyinstr(arg1)), (int)arg2);
}
php*:::request-shutdown
{
printf("%Y: PHP request-shutdown:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
php*:::request-startup
{
printf("%Y, PHP request-startup:\t%s at %s via %s\n", walltimestamp, basename(copyinstr(arg0)), copyinstr(arg1), copyinstr(arg2));
}
Pagina inicial: lâmpada de treliça no GitHub
Aqui está um uso simples:
- Correr:
sudo dtruss-php.d
. - Em outra execução de terminal:
php -r "phpinfo();"
.
Para testar isso, você pode acessar qualquer docroot com index.php
e execute o servidor PHP integrado:
php -S localhost:8080
Depois disso você pode acessar o site em http://localhost:8080/ (ou escolha qualquer porta que seja conveniente para você).A partir daí acesse algumas páginas para ver a saída do trace.
Observação:O Dtrace está disponível no OS X por padrão, no Linux você provavelmente precisará dtrace4linux ou verifique se há algum outro alternativas.
Ver: Usando PHP e DTrace em php.net
SystemTap
Como alternativa, verifique o rastreamento do SystemTap instalando o pacote de desenvolvimento SystemTap SDT (por exemplo, yum install systemtap-sdt-devel
).
Aqui está um exemplo de script (all_probes.stp
) para rastrear todos os principais pontos de investigação estática do PHP durante a execução de um script PHP em execução com SystemTap:
probe process("sapi/cli/php").provider("php").mark("compile__file__entry") {
printf("Probe compile__file__entry\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("compile__file__return") {
printf("Probe compile__file__return\n");
printf(" compile_file %s\n", user_string($arg1));
printf(" compile_file_translated %s\n", user_string($arg2));
}
probe process("sapi/cli/php").provider("php").mark("error") {
printf("Probe error\n");
printf(" errormsg %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
}
probe process("sapi/cli/php").provider("php").mark("exception__caught") {
printf("Probe exception__caught\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("exception__thrown") {
printf("Probe exception__thrown\n");
printf(" classname %s\n", user_string($arg1));
}
probe process("sapi/cli/php").provider("php").mark("execute__entry") {
printf("Probe execute__entry\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("execute__return") {
printf("Probe execute__return\n");
printf(" request_file %s\n", user_string($arg1));
printf(" lineno %d\n", $arg2);
}
probe process("sapi/cli/php").provider("php").mark("function__entry") {
printf("Probe function__entry\n");
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("function__return") {
printf("Probe function__return: %s\n", user_string($arg1));
printf(" function_name %s\n", user_string($arg1));
printf(" request_file %s\n", user_string($arg2));
printf(" lineno %d\n", $arg3);
printf(" classname %s\n", user_string($arg4));
printf(" scope %s\n", user_string($arg5));
}
probe process("sapi/cli/php").provider("php").mark("request__shutdown") {
printf("Probe request__shutdown\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
probe process("sapi/cli/php").provider("php").mark("request__startup") {
printf("Probe request__startup\n");
printf(" file %s\n", user_string($arg1));
printf(" request_uri %s\n", user_string($arg2));
printf(" request_method %s\n", user_string($arg3));
}
Uso:
stap -c 'sapi/cli/php test.php' all_probes.stp
Ver: Usando SystemTap com testes estáticos do PHP DTrace em php.net
+1 para print_r().Use-o para despejar o conteúdo de um objeto ou variável.Para torná-lo mais legível, faça-o com uma pré-tag para que você não precise visualizar a fonte.
echo '<pre>';
print_r($arrayOrObject);
Também var_dump($thing) - isso é muito útil para ver o tipo de subcoisas
Dependendo do problema, gosto de uma combinação de error_reporting(E_ALL) misturado com testes de eco (para encontrar a linha/arquivo incorreto em que o erro ocorreu inicialmente;você SABE que nem sempre é a linha/arquivo que o php informa, certo?), correspondência de chaves IDE (para resolver "Erro de análise:erro de sintaxe, problemas inesperados de $end") e print_r();saída;dumps (programadores reais veem a fonte; p).
Você também não pode vencer o phpdebug (checar a fonte do fortalecimento) com "memória_get_usage ();" e "memória_get_peak_usage ();" para encontrar as áreas problemáticas.
Os depuradores integrados, onde você pode observar os valores das alterações das variáveis à medida que avança no código, são muito legais.No entanto, eles exigem configuração de software no servidor e uma certa quantidade de configuração no cliente.Ambos requerem manutenção periódica para se manterem em boas condições de funcionamento.
Um print_r é fácil de escrever e funciona com certeza em qualquer configuração.
Normalmente encontro a criação de uma função de log personalizada capaz de salvar em arquivo, armazenar informações de depuração e, eventualmente, reimprimir em um rodapé comum.
Você também pode substituir a classe Exception comum, para que esse tipo de depuração seja semiautomático.