Depuração de código PHP

Como fazer a depuração de código PHP? Essa é uma dúvida recorrente do pessoal que está vindo de outras linguagens ou que está começando a escrever projetos um pouco mais complexos.

Não vamos aqui utilizar IDE’s e criar breakpoints etc, mas você verá que isso é possível. A ideia é passar uma abordagem geral do que é e qual o suporte disso no PHP.

PHP - Testes unitários com PHPUnit
Curso de PHP - Testes unitários com PHPUnit
CONHEÇA O CURSO

O que é depuração?

Depuração, debug ou debugging, é o processo onde o desenvolvedor utiliza ferramentas para encontrar um problema no código do software, a ideia é encontrá-los antes mesmo que eles cheguem ao conhecimento do usuário final.

Um pouco do histórico

Você deve estar pensando: OK, eu já sei o que é debug, mas o que tem de diferente em degubar código PHP em relação a outras linguagens? Antes de chegar nesse ponto, vamos a mais um pouco mais de “história”.

Os programadores que abriram caminho para nossa turma usavam (e ainda usam) linguagens de baixo nível para desenvolver. Nessas linguagens eles precisavam verificar, além do código, elementos como alocação de memória e instruções que tocavam diretamente o hardware. Com isso, depurar um código era extremamente difícil, trabalhoso e envolvia ferramentas complexas.

Com o tempo as linguagens ficaram mais simples de trabalhar, as IDE’s foram se desenvolvendo e a depuração passou a ser algo mais simples de se usar. Em linguagens como Java e Delphi as ferramentas de debug são praticamente parte das IDE’s utilizadas para se desenvolver nessas linguagens, sendo que o programador não precisa configurar basicamente nada para utilizar recursos como: breakpoint, monitoramento de valores de variáveis, pilha de execução, execução linha a linha e outros recursos.

Com a popularização da web outras linguagens de programação foram surgindo, entre elas, muitas linguagens que são interpretadas (como é o caso do PHP, em essência), ao invés de compiladas. Inicialmente essas linguagens não possuíam muitas ferramentas, além disso a maioria delas não possui uma IDE específica, podendo ser utilizadas em um editor de código simples. Nesses ambientes, os desenvolvedores se acostumaram a usar comandos da própria linguagem para saber o valor de uma variável ou valores das propriedades de um objeto, além da necessidade de saber se um método foi executado, se está retornando o valor esperado, entre outras coisas.

No caso do PHP, ele possui uma poderosa ferramenta de debug chamada Xdebug que pode ser usada em conjunto com diversas IDEs. Essa ferramenta provê recursos para utilizar a maioria dos elementos que falamos anteriormente (breakpoint, histórico de execução, alocação de memória e outros), porém, eles não são utilizados pela maioria dos desenvolvedores. Geralmente o Xdebug é instalado para melhorar a saída de erros, colorir a saída do var_dump ou para outros recursos como, por exemplo, para gerar relatórios de cobertura de teste.

Vamos ver algumas funções do próprio PHP para ajudar no processo de debug:

Backtrace

O PHP possui duas funções que retornam o histórico de chamada de funções, inclusão de arquivos e execução de código com eval(). A primeira função, debug_backtrace() retorna essas informações para um array e a segunda debug_print_backtrace() imprime diretamente na tela o histórico. Veja um exemplo:

Arquivo index.php

<?php

include('exemp.php');

Arquivo exemp.php

<?php

function a() {
    b();
}

function b() {
    c();
}

function c(){
    echo '<pre >'; //usamos a tag pre para a saída ficar mais amigável
    debug_print_backtrace();
    echo '</pre>';
}

a();

Ao executar teremos o caminho até chegar dentro da função c:

#0  c() called at [C:\xampp\htdocs\exemp.php:8]
#1  b() called at [C:\xampp\htdocs\exemp.php:4]
#2  a() called at [C:\xampp\htdocs\exemp.php:17]
#3  include(C:\xampp\htdocs\exemp.php) called at [C:\xampp\htdocs\index.php:3]

Imprimir variáveis

Agora veremos três opções para mostrar valores de variáveis.

var_export

Essa função imprime o valor de uma variável usando uma sintaxe de saída válida para o PHP:

$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x', 'y', 'z'));

echo '<pre >'; 
var_export($a);
echo '</pre>';

Ao executar teremos:

array (
  'a' => 'apple',
  'b' => 'banana',
  'c' => 
  array (
    0 => 'x',
    1 => 'y',
    2 => 'z',
  ),
)

print_r

Essa função tenta imprimir a variável com a saída mais legível possível:

$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x', 'y', 'z'));

echo '<pre >';
print_r ($a);
echo '</pre>';

A saída será algo como:

Array
(
    [a] => apple
    [b] => banana
    [c] => Array
        (
            [0] => x
            [1] => y
            [2] => z
        )

)

var_dump

Com certeza essa é a função mais popular para debugar o valor de variáveis. Ela mostra o tipo e tamanho de cada valor, aceita N variáveis como entrada e se o Xdebug estiver configurado, ela mostra o resultado formatado e colorido (que facilita a compreensão). Veja um exemplo abaixo:

$a = array ('a' => 'apple', 'b' => 'banana', 'c' => array ('x', 'y', 'z'));
$b = array (1, 2, array ("a", "b", "c"));

echo '<pre >';
var_dump($a, $b);
echo '</pre>';

O resultado:

array(3) {
  ["a"]=>
  string(5) "apple"
  ["b"]=>
  string(6) "banana"
  ["c"]=>
  array(3) {
    [0]=>
    string(1) "x"
    [1]=>
    string(1) "y"
    [2]=>
    string(1) "z"
  }
}
array(3) {
  [0]=>
  int(1)
  [1]=>
  int(2)
  [2]=>
  array(3) {
    [0]=>
    string(1) "a"
    [1]=>
    string(1) "b"
    [2]=>
    string(1) "c"
  }
}

Funções de ajuda

É possível desenvolver pequenas funções para ajudar nesse processo, por exemplo:

function imprimir($variavel) {
    echo "<pre >";
    var_dump($variavel);
    echo "</pre>";          

    die();
}

Outro exemplo seria uma função que para o script e exibe o local onde teve a chamada e os valores de POST e GET:

function parar() {
        $debug_arr = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
        $line = $debug_arr[0]['line'];
        $file = $debug_arr[0]['file'];

        header('Content-Type: text/plain');

        echo "linha: $line\n";
        echo "arquivo: $file\n\n";
        print_r(array('GET' => $_GET, 'POST' => $_POST));
        exit;
}

Conclusão

Para os desenvolvedores de outras linguagens, mais acostumados com ferramentas de debug clássicas, é possível usar o Xdebug em conjunto com uma IDE (como o Netbeans, Eclipse, PHPStorm) para fazer o uso dos recursos mais avançados de debugging.

PHP - Testes unitários com PHPUnit
Curso de PHP - Testes unitários com PHPUnit
CONHEÇA O CURSO
Deixe seu comentário

Desenvolvedor, autor e instrutor. Apaixonado por desenvolvimento de software e tudo ligado a área de tecnologia. É autor de cursos em diversos temas, como, desenvolvimento back-end, cloud computing e CMSs. Nas horas vagas adora estudar sobre o mercado financeiro, cozinhar e brincar com pequeno Daniel de 1 ano.