PHP DO BÁSICO AO AVANÇADO – AULA 24 – Debug Interativo e Outras Modificadoras do PHP

Tempo de Leitura: 13 Minutos

Como toda linguagem de programação, a escrita do código por parte do programador está sujeita a erros não só a erros de sintaxe ou tipos de parâmetros passados, ou mesmo um erro de grafia de um nome de uma função, método, variável que são facilmente identificados pelo analisador léxico da linguagem ou pelo parser da linguagem, porém, existem erros de lógica que são mais difíceis de serem localizados ou rastreados, para mitigar esses erros as linguagens de programação possuem um recurso chamado DEBUG que tem a finalidade de “tirar instantâneos” em momentos pré-determinados, essas ferramentas ajudam por exemplo a identificar vazamentos de memória, estouros de pilha, alterações de valores, estados e uma infinidade de outros processos, e podem ser de grande valia para o programador e sobre essas funções que vamos abordar hoje.

O PHP possui um mecanismo interno de DEBUG que acompanha ele, conhecido como phpdbg, que veremos mais detalhadamente, porém, outras extensões de terceiros podem ser acrescentadas e servirem como outros mecanismos próprios de debug, entre elas, vamos destacar 4 ferramentas que são livres e possuem suporte nativo pela equipe do PHP, e que podem ser mais ou menos adequadas para determinadas situações ou integrações com ambientes de desenvolvimento IDEs.

PHP-Debugger (DBG)

DBG é um depurador php completo, interativo e que ajuda você a depurar scripts. Funciona em um servidor WEB de desenvolvimento e permite depurar seus scripts local ou remotamente, a partir de um IDE ou console, pode ser obtido em http://www.php-debugger.com/ e funciona de forma transparente, sem necessidade de modificações de script nem de mecanismos do PHP. É parte do servidor (um módulo dbg) e roda em todas as plataformas onde o próprio PHP roda. Suporta back-trace, por exemplo e exibe uma lista de todos os procedimentos com suas variáveis ​​locais, a partir da posição de execução atual alcançada. Em outras palavras, você pode observar variáveis ​​locais ou parâmetros de função em todos os escopos ativos e aninhados.

Permite avaliar qualquer expressão php válida ou inspecionar arrays, classes e variáveis ​​simples, modificando seus valores em tempo real e até criando novas variáveis. É compativel com as IDEs PHPEd, PHP Edit e PHP Coder, além de possuir uma interface PHP-CLI para uso direto na console.

Uma das suas desvantagens, é que parte do projeto hoje é de código fechado e a parte aberta está sem atualização a longo período.

APD (Extensão PECL – profiler/debugger)

É um mecanismo de depuração completo, que pode ser carregado diretamente como uma extensão ZEND, infelizmente não é mais mantido pelo PECL desde 2004, porém éo único debugger que funciona nas versões da série do PHP4, por isto foi citado aqui.

ZEND Studio Debugger

Depurador Web Zend Studio é uma extensão PHP que deve ser instalada em seu servidor web para realizar depuração remota e criação de perfil ideais usando o Zend Studio. Pode ser baixado em https://www.zend.com/downloads/zend-studio-web-debugger e é o depurador usado no software Zend Studio, que é um (IDE) ou ambiente de desenvolvimento de nível profissional que inclui edição de código PHP, depuração, criação de perfil, teste de unidade, diagnóstico entre outros.

O depurador permite que você controle a execução de seu programa usando uma variedade de opções, incluindo definir pontos de interrupção, percorrer seu código e inspecionar suas variáveis ​​e parâmetros. Ele permite que você depure aplicativos inteiros, incluindo qualquer entrada de usuário interativa necessária. Permite inserir um URL para depurar um aplicativo em um servidor. Somente os arquivos do servidor serão depurados, portanto, os arquivos não precisam existir localmente em seu espaço de trabalho.

Seus contras, é que para uso total da ferramente e do framework de desenvolvimento, é necessário que tanto o IDE quanto os servidores e o debugger sejam da própria ZEND e que são comerciais, o uso do debug tradicional tanto no servidor como local pode ser feito com a IDE Zend Studio, como com outras IDEs e a Zend Studio também permite uso de outros depuradores, porém com funções mais limitadas, já o uso do debug por exemplo com VS-CODE ou PHPStorm ou Visual Studio ou Eclipse é totalmente funcional.

XDebug For PHP

Xdebug é uma extensão para PHP e fornece uma variedade de recursos para melhorar a experiência de desenvolvimento em PHP, sem dúvida é um poderoso aliado do programador por muitos motivos. Depuração de etapas, possui uma maneira de percorrer seu código em seu IDE ou editor enquanto o script está em execução, e é compativelcom TODOS os IDEs do mercado, pois usa um protocolo conhecido como dbgd.

Implementa melhorias no relatório de erros nativo do PHP, além de uma função var_dump() aprimorada, rastreamentos de pilha para avisos, avisos (warnings), erros e exceções. Destaca o caminho do código até atingir o erro, grava cada chamada de função, com argumentos e local de invocação. Opcionalmente, também inclui cada atribuição de variável e valor de retorno para cada função. Permite, com a ajuda de ferramentas de visualização, analisar o desempenho de sua aplicação PHP e encontrar gargalos e realiza uma análise de cobertura de código para mostrar quais partes de sua base de código são executadas ao executar testes de unidade com PHP Unit.

Possui uma ampla documentação disponível na internet, é totalmente gratuito, possui integração e diversos níveis de interação, o simples fato de habilita-lo em seu servidor de desenvolvimento, já possibilita ao programador o uso de funções nativas usadas para percorrer e interromper os scripts trazerem informações de erros muito mais detalhadas que as nativas do PHP, por isso pode ser usado por diversos níveis de programadores, desde os iniciantes que não vão utilizar todos os recursos de depuração e preferem percorrer código em busca de falhas, como programadores mais experientes que podem utilizar recursos como analises de cobertura de testes, injeção de valores de variáveis e muito mais.

Pode ser obtida em https://xdebug.org/ onde também é possível ler e ter acesso a uma ampla documentação sobre o seu uso. Em outra aula, podemos estudar a fundo sua instalação, configuração, configuração de uma IDE para trabalhar com ela, e outros exemplos de uso e de aprimoramentos.

Interactive PHP Debugger (phpdbg) – O Nativo

Implementado como um módulo SAPI, o phpdbg pode exercer controle total sobre o ambiente sem afetar a funcionalidade ou o desempenho do seu código. Ele pretende ser uma plataforma de depuração leve, poderosa e fácil de usar para PHP oferecendo recursos de 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() embutido API do usuário SAPI Agnostic – Facilmente Integrado ao Suporte a arquivos de configuração PHP JIT Super Globals, Suporte de linha de leitura opcional, Operação de terminal confortável e integração com todas as IDEs do mercado.

Para sua utilização, bastam algumas configurações no php.ini como apresentado aqui:

phpdbg.eol – Determina o tipo de FIM DE LINHA ou seja, o caractere de controle que faz a quebra de linha, os possíveis valores são 0 (zero) é utilizado um CR e um LF e é o padrão usado no Windows. 1 (um) utiliza somente o LF (line Feed) e é o padrão usado pelos sistemas Linux, Unix e a maioria dos sistemas POSIX. 2 (dois) utiliza o CR (Carrige Return) e é o padrão do Mac e de Sistemas baseados em BSD como o FreeBSD.

phpdbf.path – Determina o caminho do arquivo de saída, onde todo o extrato do debug sera gravado.

Funções do PHPDebugger

phpdbg_break_file(string $fileint $line) – Insira um ponto de interrupção na linha fornecida no arquivo fornecido

phpdbg_break_function(string $function) – Insere um brakpoint para a chamada dessa função (na entrada desta).

phpdbg_break_method(string $classstring $method) – Insere um brakpoint para a entrada do método informado, na classe informada.

phpdbg_break_next() – Insere um brakpoint para a proxima instrução (para execução passo a passo).

phpdbg_clear() – Limpe todos os pontos de interrupção que foram definidos, seja por meio de uma das funções phpdbg_break_ ou diretamente na console pela execução de phpdbg

phpdbg_color(int $elementstring $color) – Defina a cor do elemento fornecido. Onde, element é uma das constantes definidas pela extensão e a $color é um dos valores literais para a cor, que podem ou não serem acrescidos de um sufixo para dar enfase, por exemplo whiteredgreenyellowbluepurplecyan, black para as cores, e os sufixos podem ser -bold para o negrito ou -underline para um sublinhado, formando por exemplo red-bold ou green-underline ou qualquer outra combinação possível.

phpdbg_prompt(string $string) – Defina o prompt de comando para a string fornecida.

Runkit7 – Modificadores em Tempo de Execução

A extensão runkit7 fornece meios para modificar constantes, funções definidas pelo usuário e classes definidas pelo usuário (programador). Ele também fornece variáveis ​​superglobais personalizadas, como outros métodos tipo $_PUT por exemplo.

runkit.superglobal – Lista separada por vírgulas de nomes de variáveis ​​a serem tratadas como superglobais. Este valor deve ser definido no arquivo php.ini de todo o sistema, e todas as variáveis escritas quando aparecerem no Script, são tratadas como SUPERGLOBAIS.

runkit.internal_override – Esta diretriz, quando habilitada, permite que funções internas sejam modificadas/renomeadas/removidas o padrão é Off

As constantes abaixo são definidas por esta extensão e somente estarão disponíveis quando a extensão foi compilada carregada dinamicamente durante a execução:
RUNKIT7_IMPORT_FUNCTIONS – indica que as funções normais devem ser importadas do arquivo especificado
RUNKIT7_IMPORT_CLASS_METHODS – indica que os métodos de classe devem ser importados do arquivo especificado
RUNKIT7_IMPORT_CLASS_CONSTS – indica que as constantes de classe devem ser importadas do arquivo especificado
RUNKIT7_IMPORT_CLASS_PROPS – indica que as propriedades padrão da classe devem ser importadas do arquivo especificado
RUNKIT7_IMPORT_CLASS_STATIC_PROPS – indica que as propriedades estáticas de classe devem ser importadas do arquivo especificado
RUNKIT7_IMPORT_CLASSES – representando um OR bit a bit das constantes RUNKIT7_IMPORT_CLASS_*
RUNKIT7_IMPORT_OVERRIDE – sinaliza que se alguma das funções, métodos, constantes ou propriedades importadas já existir, elas devem ser substituídas pelas novas definições. Se este sinalizador não estiver definido, todas as definições importadas que já existirem serão descartadas
RUNKIT7_ACC_RETURN_REFERENCE – Inclua este sinalizador para fazer com que a função ou método que está sendo criado ou redeclarado retorne uma referência
RUNKIT7_ACC_PUBLIC – Sinaliza para runkit7_method_add() e runkit7_method_redefine() para tornar o método público
RUNKIT7_ACC_PROTECTED – Sinaliza para runkit7_method_add() e runkit7_method_redefine() para tornar o método protegido
RUNKIT7_ACC_PRIVATE – Sinaliza para runkit7_method_add() e runkit7_method_redefine() para tornar o método privado
RUNKIT7_ACC_STATIC – Sinalize para runkit7_method_add() e runkit7_method_redefine() para tornar o método estático
RUNKIT7_FEATURE_MANIPULATION – Igual a 1 se a manipulação de tempo de execução estiver habilitada e 0 caso contrário
RUNKIT7_FEATURE_SUPERGLOBALS – Igual a 1 se as superglobais personalizadas estiverem habilitadas e 0 caso contrário
RUNKIT7_FEATURE_SANDBOX – Sempre 0, é impraticável implementar o recurso sandbox no php 7, somente a partir do PHP8 este modo esta sendo criado, porém ainda não definido ou disponível.

Funções do Runkit7

runkit7_constant_add(‘constant_name’, $value, $Visibility) – Similar a define(), esta função declara uma CONSTANTE, porém, $Visibility pode ser um dos valores RUNKIT7_ACC_* que a torna uma constante pública, protegida, privativa ou estática e o padão é pública caso não seja definido.

runkit7_constant_redefine(‘constant_name’, $value, $Visibility) – Esta função REDECLARA uma constante, ou seja, pode tanto alterar seu conteúdo como sua visibilidade, o que é impossivel sem o uso dessa extensão.

runkit7_constant_remove(‘constant_name’) – Remove uma constante declarada, pode ser também nome de uma constante classname::constname indicando uma constante de classe

runkit7_function_add($function_name, $argument_list, $code, $return_by_reference, $doc_comment, $return_type, $is_strict ) – Declara uma função, de maneira similar a create_function(), onde os argumentos são o nome da função, a lista de argumentos separado por vírgula como na codificação com os valores padrão ou nulos etc, o $code é uma string com o código da função em PHP, o retorno por referência, um comentário ou documentário, o tipo de retorno (integer, string, etc), e um valor true/false se a função é ou não estrita.

runkit7_function_copy($source_name, $target_name) – Copia uma função, podendo ser uma função nativa ou não.

runkit7_function_rename($source_name, $target_name) – Renomeia uma função, que pode ser ou não uma função do usuário

runkit7_function_remove($function_name) – Remove uma função, podendo ser ou não uma função nativa.

runkit7_function_redefine($function_name, $argument_list, $code, $return_by_reference, $doc_comment, $return_type, $is_strict ) – Redefine uma função, substituindo seu código pelo novo informado no argumento.

Por padrão somente funções do usuário podem ser removidos, renomeadas ou modificadas, para sobrescrever funções internas, você precisa ativar a configuração runkit.internal_override.

runkit7_import($filename, $flags) – Similar a função include(), processe uma importação de arquivo PHP e definições de classe, substituindo quando apropriado. Este recurso foi removido da versão 4 em diante da runkit7. qualquer código que resida fora de uma função ou classe é simplesmente ignorado. Além disso, dependendo do valor dos sinalizadores, quaisquer funções ou classes que já existam no ambiente em execução no momento podem ser substituídas automaticamente por suas novas definições. FLAGS pode ser qualquer uma das constantes RUNKIT7_IMPORT_* para definir o escopo.

runkit7_method_add( $class_name, $method_name, $argument_list, $code, $flags = RUNKIT7_ACC_*, $doc_comment, $return_type, $is_strict ) – Define um método de maneira dinâmica, e seus argumentos são o nome da classe, o nome do método a ser criado, a lista de argumentos como um código php, o código do método em formato de string, a flag de escopo do método, um documentário para a função, o tipo de retorno, e um valor true/false para determinar se é ou não estrita.

runkit7_method_copy($destination_class, $destination_method_name, $source_class, $source_method_name) – Copia um método de dentro de uma classe para outra, ou para a propria classe em questão.

runkit7_method_redefine($class_name, $method_name, $argument_list, $code, $flags = RUNKIT7_ACC_*, $doc_comment, $return_type, $is_strict ) – Redefine o método dentro da classe substituindo-o pelo novo código.

runkit7_method_remove($class_name, $method_name) – Remove o método de dentro da classe especificada.

runkit7_method_rename($class_name, $source_method_name, $target_method_name) – Renomeia o método dentro da classe definida, esta função não pode ser utilizada para manipular um método ativo ou encadeado.

runkit7_object_id($obj) – Retorna o identificador de objeto inteiro para determinado objeto, o ID do objeto é exclusivo para o tempo de vida do objeto. Uma vez que o objeto é destruído, seu id pode ser reutilizado para outros objetos. Esse comportamento é semelhante ao spl_object_hash().

runkit7_superglobals() – Retorna um array, com os valores indexados das super globais registradas e existentes.

runkit7_zval_inspect($value) – Retorna informações sobre o valor passado com tipos de dados, contagens de referência, entre outros.

XHProf – Informações de perfil hierárquico

XHProf é um perfilador baseado em instrumentação hierárquica leve,ou seja,durante a fase de coleta de dados, ele acompanha as contagens de chamadas e métricas inclusivas para arcos no gráfico de chamadas dinâmico de um programa. Ele calcula métricas exclusivas na fase de relatório/pós-processamento, como tempo de decorrido, tempo de CPU e uso de memória. Um perfil de funções pode ser dividido por chamadores ou receptores.

O XHProf lida com funções recursivas detectando ciclos no gráfico de chamada no próprio tempo de coleta de dados e evitando os ciclos fornecendo nomes qualificados de profundidade exclusivos para as invocações recursivas. XHProf inclui uma interface de usuário simples baseada em HTML e escrita em PHP. A interface do usuário baseada em navegador para visualizar os resultados do criador de perfil e facilita a visualização dos resultados ou o compartilhamento dos resultados com colegas.

Uma visualização de imagem de callgraph também é suportada, e os relatórios XHProf geralmente podem ser úteis para entender a estrutura do código que está sendo executado. A natureza hierárquica dos relatórios pode ser usada para determinar, por exemplo, qual cadeia de chamadas levou à chamada de uma função específica. O XHProf suporta comparar duas execuções, também conhecidos como relatórios “diff”,  ou agregar dados de várias execuções. Os relatórios de diferenças e agregados, assim como os relatórios de execução única, oferecem visualizações “planas” e “hierárquicas” do perfil. Embora não seja obrigatório, o xhprof inclui uma interface escrita em PHP que é usada para salvar e exibir os dados do perfil de forma utilizável, onde a visualização é feita por meio de um navegador da web, sendo requerido um configurado para utilizar o recurso.

Essa extensão também é fornecida via PECL e para sua utilização o módulo correspondente deve estar disponível e habilitado no servidor onde seráusado.

No PHP.INI é necessário indicar a diretriz xhprof.output_dir que indica o diretório usado pela implementação padrão da interface iXHProfRuns, ou seja, a classe XHProfRuns_Default para armazenar execuções de XHProf. A instalação dessa extensão, define as seguintes constantes:
XHPROF_FLAGS_NO_BUILTINS – Usado para pular todas as funções internas (internas).
XHPROF_FLAGS_CPU – Usado para adicionar informações de perfil da CPU à saída.
XHPROF_FLAGS_MEMORY – Usado para adicionar informações de perfil de memória à saída.

Asfunções para uso dessa extensão são simples,e sua descrição segue:

xhprof_disable() – Interrompe o criador de perfil e retorna os dados xhprof da execução, retornando um array com os dados coletados.

xhprof_enable($ flags = 0, $ opções = ?) – Inicia a criação de perfil do xhprof. Parâmetros $FLAGS são as constantes sinalizadoras opcionais para adicionar informações extras à criação de perfil,apresentadas acima.

xhprof_sample_disable() – Interrompe o perfilador de amostrasdo XHProf

xhprof_sample_enable() – Inicia a criação de perfil XHProf no modo de amostragem, o intervalo de amostragem é de 0,1 segundos e as amostras registram a pilha de chamadas de função completa. O principal caso de uso é quando uma sobrecarga menor é necessária ao fazer o monitoramento e o diagnóstico de desempenho.

Um exemplo de uso

Xhprof com a GUI opcional, neste exemplo inicia e para o criador de perfil e, em seguida, usa a interface GUI incluída para salvar e analisar os resultados. Em outras palavras, o código da própria extensão termina na chamada para xhprof_disable()

?php
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);

for ($i = 0; $i <= 1000; $i++) {
    $a = $i * $i;
}

$xhprof_data = xhprof_disable();

$XHPROF_ROOT = "/tools/xhprof/";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";

$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "xhprof_testing");

echo "http://localhost/xhprof/xhprof_html/index.php?run={$run_id}&source=xhprof_testing\n";

?>

Este exemplo,supondo-se que o endereço de saída do XHProf é o caminho do rais do web server,e as subpastas xhprof/xhprof_html/ então ele vai imprimir o endereço para ser aberto e visualizado o relatório gráfico coletado.

Esta extensão tem muita utilidade em ambiente de homologação ou sandbox para avaliar consumo e desempenho, ou para analises de ambiente de produção em tempo real.