Como você depura scripts PHP? [fechadas]


403

Como você depura scripts PHP ?

Estou ciente da depuração básica, como usar o Relatório de Erros. A depuração do ponto de interrupção no PHPEclipse também é bastante útil.

Qual é a melhor maneira (rápida e fácil) de depurar no phpStorm ou em qualquer outro IDE?




40
Eu acredito que esta é uma ótima pergunta! Quando você não sabe como abordar a depuração do PHP, nem sabe como formular sua pergunta, não sabe como ser mais preciso do que isso. Portanto, pode não obedecer às regras do Stack, mas certamente nos ajuda, iniciantes, muito!
precisa

11
a partir do php5.4, introduziu um novo depurador de interface de linha de comando chamado phpdbg ( phpdbg.com ). O PHP5.6 virá com o phpdbg padrão.
Ganesh Patil

11
Já ouviu falar do XDebug? :)
Pratik

Respostas:


145

Experimente o Eclipse PDT para configurar um ambiente Eclipse que possui recursos de depuração como você mencionou. A capacidade de entrar no código é uma maneira muito melhor de depurar do que o antigo método var_dump e imprimir em vários pontos para ver onde seu fluxo está errado. No entanto, quando tudo o mais falha e tudo o que tenho é SSH e vim, ainda var_dump()/ die()para descobrir onde o código vai para o sul.


35
Você deve usar esta função: kill ($ data) {die (var_dump ($ data)); } Ele economiza digitação 10 caracteres, melhor função que eu já escrevi tbh :)
AlexMorley-Finch


2
Existe uma maneira de embelezar o "var_dump"?
RPDeshaies

6
@ AlexMorley-Finch Levanto você parakill($data) { echo "<pre>"; var_dump($data); echo "</pre>"; exit; }
Francisco Presencia

2
O link é "recuperável" através do incrível Web Archive , última verificação a partir de 7 de maio de '15.
Gruber


38

Este é o 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;
        }
    }
}

2
Obrigado. Isso salvou o meu dia. (Eu apenas tive que remover esse E_STRICT) #
1155

4
assert_callcackheh
Madbreaks

32

Xdebug e o plug-in DBGp para o Notepad ++ para caça de bugs pesados, FirePHP para coisas leves. Rapido e sujo? Nada supera o dBug .


O plugin DBGp não funciona com a versão atual do bloco de notas ++ / xdebug e não há planos para corrigi-lo. Você pode ver minha discussão com o criador do link aqui
Joe

26

O XDebug é essencial para o desenvolvimento. Eu o instalo antes de qualquer outra extensão. Ele fornece rastreamentos de empilhamento em qualquer erro e você pode ativar a criação de perfil facilmente.

Para uma rápida olhada em uma estrutura de dados, use var_dump(). Não use, print_r()pois você precisará cercá-lo <pre>e ele imprime apenas um var por vez.

<?php var_dump(__FILE__, __LINE__, $_REQUEST); ?>

Para um ambiente de depuração real, o melhor que encontrei é o Komodo IDE, mas custa $$.


19

PhpEd é realmente bom. Você pode entrar / sair / sair de funções. Você pode executar código ad-hoc, inspecionar variáveis, alterar variáveis. É maravilhoso.


4
Eu usei o PhpEd e não tenho palavras gentis para ele quando comparado a um IDE real como o NetBeans ou o Eclipse, nem esse comentário adiciona algo útil à pergunta. -1
siliconrockstar

Tentei a maioria dos IDEs (incluindo Zend, NetBeans e Eclipse) antes de comprar o PhpED Professional, porque era o melhor por uma milha e meia. Isso foi há alguns anos atrás, então os outros podem ter melhorado desde então, mas na época a maioria deles era dolorosamente lenta porque havia sido escrita em Java. Eu não entendo como alguém pode ter "nenhuma palavra gentil para isso" quando (para mim) era claramente a melhor, a decisão era óbvia.
Lm713

17

1) Eu uso print_r (). No TextMate, tenho um trecho para 'pre' que se expande para isso:

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.


Tenho certeza que você quer dizer eco "</pre>"; no final embora.
Altermativ 29/07/09

9
Você também pode passar 'true' para a função para que ela retorne a string. Isso significa que você pode fazer isso:echo '<pre>', print_r($var, true), '</pre>';
DisgruntledGoat


16

Com toda a honestidade, uma combinação de print e print_r () para imprimir as variáveis. Eu sei que muitos preferem usar outros métodos mais avançados, mas acho isso o mais fácil de usar.

Eu direi que não apreciei totalmente isso até fazer alguma programação de microprocessador na Uni e não fui capaz de usar nem isso.


Fico feliz que você tenha mencionado print e print_r, utilizo uma impressão básica para verificar se o código foi executado em um determinado ponto, o que ajuda a isolar o problema.
Brad

Eu uso ambos print e var_dump (). Uso print para exibir mensagens e informações de depuração e var_dump para indicar o estado das variáveis ​​conforme as coisas progridem.
21379 Joshua K

14

Xdebug , de Derick Rethans, é muito bom. Eu o usei há algum tempo e achei que não era tão fácil de instalar. Quando terminar, você não entenderá como gerenciou sem ele :-)

Há um bom artigo sobre o Zend Developer Zone (a instalação no Linux não parece mais fácil) e até um plugin do Firefox , que eu nunca usei.


2
Não é apenas uma instalação frustrante. Configurar o Xdebug para funcionar com o Eclipse pode ser um pesadelo. Eu era capaz de conseguir Xdebug instalado no CentOS 5, mas EclipsePDT + Xdebug não quer cooperar :(
Jahangir


11

Uso o Netbeans com o XDebug e o complemento Easy XDebug FireFox

O complemento é essencial quando você depura projetos MVC, porque a maneira normal de executar o XDebug no Netbeans é registrar a sessão dbug por meio do URL. Com o complemento instalado no FireFox, você definiria as propriedades do projeto Netbeans -> Executar configuração -> Avançado e selecione "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 do mouse no ícone Add-on no canto inferior direito para iniciar o monitoramento de pontos de interrupção. Quando o código atinge o ponto de interrupção, ele para e você pode inspecionar seus estados variáveis ​​e pilha de chamadas.



9

O PhpEdit possui um depurador embutido, mas eu geralmente acabo usando echo (); e print_r (); à moda antiga !!


8

Para os problemas realmente difíceis que seriam muito demorados 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 não requer praticamente nenhuma configuração. a única razão pela qual não o uso para problemas que encontro é que é dolorosamente lento. Não tenho certeza de que a lentidão seja específica para o PhpEd ou qualquer depurador php. O PhpEd não é gratuito, mas acredito que ele use um dos depuradores de código aberto (como o XDebug mencionado anteriormente) de qualquer maneira. O benefício com o PhpEd, novamente, é que ele não requer nenhuma configuração que eu achei realmente muito tediosa no passado.


2
O depurador do PHPEd é realmente escrito pelo mesmo cara que escreveu o PHPEd e tenho certeza de que não é de código aberto. Pelo menos o PHPEd não é fornecido com a fonte, mas compilou .so e .dll.
Artem Russakovskii

4

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.


3

Bem, até certo ponto, depende de onde as coisas estão indo para o sul. Essa é a primeira coisa que tento isolar, e então usarei echo / print_r () conforme necessário.

NB: Vocês sabem que você pode passar true como um 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>";

2
Eu apenas envolvo isso em uma função chamada debug. Então eu posso fazer depuração ($ var);
jdelator

3

Costumo usar o CakePHP quando o Rails não é possível. Para depurar erros, geralmente encontro a error.logpasta tmp e o atuo no terminal com o comando ...

tail -f app/tmp/logs/error.log

Ele fornece a você a caixa de diálogo em execução do bolo do que está acontecendo, o que é bastante útil, se você quiser produzir algo para ele no meio do código, você pode usar.

$this->log('xxxx');

Isso geralmente pode lhe dar uma boa idéia do que está acontecendo / errado.



2

O Komodo IDE funciona bem com o xdebug, mesmo para a depuração remore. Ele precisa de uma quantidade mínima de configuração. Tudo o 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 definiria dentro do eclipse para depurar um programa java. A depuração remota é obviamente mais complicada para que funcione corretamente (talvez seja necessário mapear a URL remota com um script php no 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 .



2

Existem muitas técnicas de depuração do PHP que podem economizar inúmeras horas durante a codificação. Uma técnica de depuração eficaz, porém 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 erros mais esquivos exibindo o que realmente está acontecendo na tela. PHPeclipse é um plug-in do Eclipse que pode destacar erros de sintaxe comuns 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();

1

Em um ambiente de produção, registro dados relevantes no log de erros do servidor com error_log ().


e de tail-f ... funciona muito bem
markus_p

1

eu uso o zend studio para eclipse com o depurador embutido. Ainda é lento comparado à depuração com o eclipse pdt com xdebug. Esperemos que eles resolvam esses problemas, a velocidade melhorou em relação aos lançamentos recentes, mas ainda assim o processo demora 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 fará referência ao seu código e fornecer gráficos de pizza, tempo de execução etc.


1

A maioria dos erros pode ser facilmente encontrada 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 for necessário)


1

DBG do PHP

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. Ele tem como objetivo ser uma plataforma de depuração leve, poderosa e fácil de usar para o PHP 5.4+ e é fornecida de fábrica com o 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
  • Acesso fácil ao código atualmente em execução
  • API do Userland
  • SAPI Agnóstico - Facilmente Integrado
  • Suporte ao arquivo de configuração PHP
  • Super Globals de JIT - ajuste seus próprios !!
  • Suporte opcional ao readline - Operação confortável do terminal
  • Suporte à depuração remota - GUI Java empacotada
  • Operação fácil

Veja as capturas de tela:

PHP DBG - Depuração passo a passo: captura de tela

PHP DBG - Depuração passo a passo: captura de tela

Página inicial: http://phpdbg.com/

Erro PHP - Melhor relatório de erros para PHP

É muito fácil usar a biblioteca (na verdade um arquivo) para depurar seus scripts PHP.

A única coisa que você precisa fazer é incluir um arquivo como abaixo (no início do seu código):

require('php_error.php');
\php_error\reportErrors();

Todos os erros fornecerão informações como backtrace, contexto de código, argumentos de função, variáveis ​​de servidor etc. Por exemplo:

Erro de PHP |  Melhore o Relatório de Erros para PHP - captura de tela do backtrace Erro de PHP |  Melhore o Relatório de Erros para PHP - captura de tela do backtrace Erro de PHP |  Melhore o Relatório de Erros para PHP - captura de tela do backtrace

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
  • comete 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 de função completa)
  • corrige algumas mensagens de erro que estão completamente erradas
  • realce de sintaxe
  • parece bonito!
  • costumização
  • manualmente ligar e desligar
  • executar seções específicas sem relatar erros
  • ignore arquivos, permitindo evitar o código de destaque no rastreamento de pilha
  • arquivos de aplicativos; estes são priorizados quando ocorre um erro!

Página 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 o rastreamento dinâmico do DTrace (instalado por padrão no OS X) e o seu PHP for compilado com as sondas do DTrace ativadas ( --enable-dtrace), que devem ser por padrão, este comando poderá ajudá-lo a depurar o script PHP sem tempo:

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); }'

Portanto, dado o seguinte alias foi adicionado aos seus arquivos rc (por exemplo ~/.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 traçar seu roteiro com fácil de lembrar apelido: trace-php.

Aqui está um script dtrace mais avançado, salve-o dtruss-php.d, torne-o executável ( chmod +x dtruss-php.d) e execute:

#!/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));
}

Página inicial: dtruss-lamp no GitHub

Aqui está o uso simples:

  1. Execute: sudo dtruss-php.d.
  2. Em outra corrida terminal: php -r "phpinfo();".

Para testar isso, você pode acessar qualquer docroot index.phpe executar o servidor interno do PHP:

php -S localhost:8080

Depois disso, você pode acessar o site em http: // localhost: 8080 / (ou escolher qualquer porta que for conveniente para você). A partir daí, acesse algumas páginas para ver a saída do rastreio.

Nota: O Dtrace está disponível no OS X por padrão, no Linux você provavelmente precisará do dtrace4linux ou procure outras alternativas .

Veja: Usando PHP e DTrace em php.net


SystemTap

Como alternativa, verifique o rastreio do SystemTap instalando o pacote de desenvolvimento do 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 análise estática do PHP durante toda a duração de um script PHP em execução com o 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

Consulte: Usando o SystemTap com probes estáticos do PHP DTrace em php.net


0

+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 sub-coisas


Uma versão estendida pode ser encontrada aqui devarticles.in/php/useful-function-to-output-debug-data-in-php
Arvind K.


0

Dependendo do problema, eu gosto de uma combinação de error_reporting (E_ALL) misturada com testes de eco (para encontrar a linha / arquivo incorreto no qual o erro ocorreu inicialmente; você SABE que nem sempre a linha / arquivo php diz a você certo?), IDE brace matching (para resolver os problemas "Erro de análise: erro de sintaxe, $ end inesperados") e print_r (); Saída; despejos (programadores reais visualizam a fonte; p).

Você também não pode vencer o phpdebug (verifique o sourceforge) com "memory_get_usage ();" e "memory_get_peak_usage ();" para encontrar as áreas problemáticas.


0

Os depuradores integrados, nos quais você pode observar os valores das variáveis ​​mudarem conforme você percorre o código, são realmente 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 manter o bom funcionamento.

Um print_r é fácil de escrever e é garantido que funcione em qualquer configuração.


0

Normalmente, acho que criar 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 semi-automatizado.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.