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.
Curso PHP - Testes unitários com PHPUnit
Conhecer o cursoO 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, inclusive você pode aprender aqui no blog como instalar e configurar o Xdebug. 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 no PHP.
Vamos ver algumas funções do próprio PHP para ajudar no processo de debug:
Formação Desenvolvedor PHP
Conhecer a formaçãoBacktrace
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.