PHP var_dump e print_r

Programar é, em boa parte, descobrir por que o programa não fez o que você esperava. E a primeira pergunta é sempre: o que tem dentro desta variável agora? O echo não serve para isso: ele esconde o tipo, não mostra false nem null e não sabe mostrar arrays. Nesta aula você conhece as quatro "lupas" do PHP (var_dump, print_r, var_export e json_encode) e vê, lado a lado, como cada uma mostra o mesmo valor.

Você vai aprender
  • A ler a saída do var_dump, a lupa mais completa.
  • Quando o print_r é mais confortável, e o truque print_r($x, true).
  • O que o var_export e o json_encode fazem de diferente.
  • Como cada um mostra textos, números, booleanos, null e arrays dentro de arrays.
  • Por que, no navegador, a saída fica numa linha só, e como resolver com <pre>.

Os programas desta aula rodaram com o PHP 8.5 na máquina fictícia da Ana, na pasta ~/site. Os arrays aparecem aqui só como "coisa para inspecionar"; você vai aprender a criá-los em Arrays Indexados e Arrays Associativos.


A ideia: quatro jeitos de fotografar uma caixa

Imagine que você precisa mostrar para alguém o que tem numa caixa de mudança. Dá para fazer de vários jeitos:

JeitoEquivalente em PHPPara quem
Uma lista técnica com etiqueta, peso e tamanho de cada itemvar_dumpVocê, investigando um problema
Uma lista simples, fácil de lerprint_rVocê, olhando arrays grandes
Uma "receita" para montar a caixa de novovar_exportOutro programa PHP
Um formulário padrão, que qualquer transportadora entendejson_encodeOutros sistemas (JavaScript, APIs)

1. var_dump: tipo, tamanho e valor

var_dump (de variable dump, "despejar a variável") é a lupa mais completa. Ela mostra tudo: o tipo, o tamanho (para strings e arrays) e o valor, e aceita vários valores de uma vez, separados por vírgula:

<?php
var_dump("Ana", 29, 1.65, true, null);
$ php dump.php
string(3) "Ana"
int(29)
float(1.65)
bool(true)
NULL

Com um array (uma lista de valores com etiquetas), o var_dump mostra a estrutura inteira, com recuo para o que está dentro:

<?php
$cliente = [
    "nome" => "Ana",
    "idade" => 29,
    "ativa" => true,
    "compras" => ["pão", "café"],
];
var_dump($cliente);
$ php cliente.php
array(4) {
  ["nome"]=>
  string(3) "Ana"
  ["idade"]=>
  int(29)
  ["ativa"]=>
  bool(true)
  ["compras"]=>
  array(2) {
    [0]=>
    string(4) "pão"
    [1]=>
    string(5) "café"
  }
}
array(4) {
Um array com 4 itens. Tudo até a } correspondente está dentro dele.
["nome"]=>
A chave (a etiqueta do item). Na linha de baixo, o valor dessa chave.
string(3) "Ana"
O valor: string de 3 bytes.
["compras"]=> array(2) {
Um array dentro do array (aninhado), com mais recuo.
[0]=>
Chaves numéricas aparecem sem aspas. A contagem começa no 0.
string(4) "pão"
4, e não 3: o ã ocupa 2 bytes (veja Strings).

O var_dump escreve direto na saída e não devolve nada. Se você tentar guardar o resultado numa variável, ela recebe null. Para ter o texto numa variável, use as outras lupas com true (abaixo).


2. print_r: a leitura confortável

print_r (de print readable, "imprimir legível") mostra só as chaves e os valores, sem tipos nem tamanhos:

<?php
$cliente = [
    "nome" => "Ana",
    "idade" => 29,
    "ativa" => true,
    "compras" => ["pão", "café"],
];
print_r($cliente);
$ php legivel.php
Array
(
    [nome] => Ana
    [idade] => 29
    [ativa] => 1             « true aparece como 1
    [compras] => Array
        (
            [0] => pão
            [1] => café
        )

)

É bem mais fácil de ler num array grande. O preço: o print_r mostra os valores como o echo mostraria. true vira 1, e false, null e "" viram… nada. Também não dá para saber se 29 é o número ou o texto "29". Quando o tipo importa, volte para o var_dump.

print_r($x, true): o texto numa variável

Passando true como segundo argumento, o print_r não mostra nada: ele devolve o texto, para você guardar numa variável, juntar com outra string ou gravar num arquivo de registro (log):

<?php
$compras = ["pão", "café"];
$texto = print_r($compras, true);
echo "A lista tem " . strlen($texto) . " bytes de texto:\n";
echo $texto;
$ php retorno.php
A lista tem 43 bytes de texto:
Array
(
    [0] => pão
    [1] => café
)

Um uso muito comum na web é error_log(print_r($dados, true));: grava o conteúdo no registro de erros do servidor, sem aparecer para o visitante (veja Depurar).

Missão: o programa tenta juntar o texto "Dados do pedido: " com o conteúdo do array, mas o print_r escreve o array antes da frase, e a frase termina com um 1 perdido (Dados do pedido: 1). Use print_r($pedido, true) para que a saída comece com Dados do pedido: Array.

<?php
$pedido = ["produto" => "caderno", "quantidade" => 3];
echo "Dados do pedido: " . print_r($pedido) . "\n";
<?php
$pedido = ["produto" => "caderno", "quantidade" => 3];
echo "Dados do pedido: " . print_r($pedido, true) . "\n";

3. var_export: o valor como código PHP

var_export ("exportar a variável") mostra o valor escrito do jeito que você escreveria no código. Dá para copiar a saída e colar num programa PHP:

<?php
$cliente = [
    "nome" => "Ana",
    "idade" => 29,
    "ativa" => true,
    "compras" => ["pão", "café"],
];
var_export($cliente);
echo "\n";
$ php exportar.php
array (
  'nome' => 'Ana',
  'idade' => 29,
  'ativa' => true,                « a palavra true, sem ambiguidade
  'compras' =>
  array (
    0 => 'pão',
    1 => 'café',
  ),
)

Strings aparecem entre aspas simples, números sem aspas, e true, false e NULL por extenso. É ótimo para booleanos e null, que o print_r esconde. Repare que o var_export não pula linha no fim (por isso o echo "\n"). Ele também aceita true no segundo argumento para devolver o texto: var_export($x, true).


4. json_encode: o formato que todo mundo entende

JSON é um formato de texto para trocar dados entre sistemas, usado em toda a web (aula JSON). json_encode transforma um valor do PHP em JSON. Não é uma ferramenta de depuração, mas é útil para ver dados como o navegador ou uma API vão recebê-los:

<?php
$cliente = [
    "nome" => "Ana",
    "idade" => 29,
    "ativa" => true,
    "compras" => ["pão", "café"],
];
echo json_encode($cliente), "\n";
echo json_encode($cliente, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), "\n";
$ php json.php
{"nome":"Ana","idade":29,"ativa":true,"compras":["pão","café"]}
{
    "nome": "Ana",
    "idade": 29,
    "ativa": true,
    "compras": [
        "pão",
        "café"
    ]
}
json_encode($x)
Tudo numa linha, e os acentos viram códigos (ã é o ã). Continua correto: qualquer programa que lê JSON entende.
JSON_PRETTY_PRINT
"Impressão bonita": quebra as linhas e recua.
JSON_UNESCAPED_UNICODE
"Unicode sem escape": mantém ã e é como letras.
|
Junta as duas opções (detalhes em JSON).

5. Lado a lado

O mesmo valor, nas quatro lupas. Todas as saídas abaixo são reais:

Valorvar_dumpprint_rvar_exportjson_encode
"Ana"string(3) "Ana"Ana'Ana'"Ana"
29int(29)292929
1.65float(1.65)1.651.651.65
0.1 + 0.2float(0.30000000000000004)0.30.300000000000000040.30000000000000004
truebool(true)1truetrue
falsebool(false)(nada)falsefalse
nullNULL(nada)NULLnull
arraytipos e tamanhosArray ( [0] => … )array ( 0 => … )["…"] ou {"…":…}
objetoobject(stdClass)#1 (2) {…}stdClass Object ( … )(object) array( … ){"nome":"Ana",…}
Devolve texto?NãoCom trueCom trueSempre

Repare na linha do 0.1 + 0.2: o print_r arredonda como o echo e esconde a imprecisão do float (aula int e float). Mais um motivo para investigar com var_dump.

Experimente: rode e compare as quatro saídas. Depois troque "ativa" => false e acrescente "telefone" => null: em qual das lupas eles "somem"?

<?php
$produto = ["nome" => "caderno", "preco" => 12.9, "ativa" => true];
var_dump($produto);
print_r($produto);
var_export($produto);
echo "\n", json_encode($produto), "\n";

6. No navegador: use <pre>

Quando o PHP gera uma página web, a saída do var_dump vai para o meio do HTML. O navegador junta espaços e quebras de linha, e tudo aparece numa linha só, difícil de ler. A tag HTML <pre> ("pré-formatado") manda o navegador respeitar os espaços:

<?php
$compras = ["pão", "café"];
var_dump($compras);
echo "<pre>";
var_dump($compras);
echo "</pre>";

O código-fonte gerado é o mesmo texto nos dois casos, mas o navegador só respeita as quebras de linha do segundo (o que está dentro do <pre>). Rode no editor abaixo e compare a aba Resultado com a aba Código-fonte HTML:

Experimente: o primeiro var_dump sai embolado numa linha; o segundo, dentro de <pre>, fica organizado. Troque por print_r e veja a diferença.

<?php
$compras = ["pão", "café", "maçã"];
echo "<h3>Sem pre</h3>";
var_dump($compras);
echo "<h3>Com pre</h3><pre>";
var_dump($compras);
echo "</pre>";
Não deixe var_dump no site publicado

Essas lupas são para você, durante o desenvolvimento. Num site no ar, elas podem mostrar dados internos (senhas, caminhos de arquivos) para qualquer visitante. Remova antes de publicar, ou use error_log(print_r($x, true)), que grava no registro do servidor.


7. E o echo de um array?

O echo só sabe mostrar textos e números. Com um array, ele desiste, avisa e mostra a palavra Array:

<?php
$compras = ["pão", "café"];
echo $compras;
echo "\n";
$ php echo-array.php

Warning: Array to string conversion in /home/ana/site/echo-array.php on line 3
Array

Array to string conversion = "conversão de array para string". Para mostrar um array, use uma das lupas, ou junte os itens num texto com implode(", ", $compras) (aula Funções de Array).


Qual usar?

Você quer…Use
Descobrir o que há numa variável, com certeza do tipovar_dump
Olhar a estrutura de um array grandeprint_r
O conteúdo num texto (para log, e-mail, juntar com outra string)print_r($x, true) ou var_export($x, true)
Ver booleanos e null sem ambiguidade, num formato curtovar_export
Copiar o valor para dentro de um programa PHPvar_export
Ver como os dados vão para o JavaScript ou uma APIjson_encode
Mostrar algo para o visitanteecho com htmlspecialchars (nenhuma das lupas!)

Quando dá errado

Warning: Array to string conversion

O que significa: você usou um array onde o PHP esperava texto: num echo, dentro de "…" ou com o ponto (.).

Como consertar: para investigar, troque por print_r ou var_dump; para mostrar ao usuário, percorra o array com foreach ou use implode.

Sobrou um 1 no fim do texto

O que significa: você juntou print_r($x) (sem true) com uma string. O print_r escreveu o array na hora e devolveu true, que o ponto transformou em "1".

Como consertar: print_r($x, true).

No navegador, tudo saiu numa linha só

O que significa: o HTML ignora quebras de linha e espaços repetidos.

Como consertar: coloque echo "<pre>"; antes e echo "</pre>"; depois.

O print_r não mostrou um valor

O que significa: o valor é false, null ou ""; o print_r mostra os três como nada.

Como consertar: use var_dump ou var_export.


Referência rápida

FunçãoMostraDevolve
var_dump($a, $b, …)Tipo, tamanho e valor de cada umnada (null)
print_r($x)Valor legíveltrue
print_r($x, true)NadaO texto
var_export($x)Valor como código PHPnull
var_export($x, true)NadaO texto
json_encode($x, opções)NadaO texto em JSON

Exercícios

1. A lupa completa

Complete para ver o tipo e o valor de $preco:

($preco);

2. Texto numa variável

Complete para guardar o conteúdo de $lista como texto:

$texto = print_r($lista, );

3. O que print_r(false); mostra?

4. Qual destas saídas veio do var_export?

5. Por que var_dump é melhor que print_r para investigar $idade?

Missão final: JSON com acentos

Missão: o programa mostra a lista de compras em JSON, mas os acentos viram códigos como ã. Acrescente a opção certa no json_encode para a saída ser exatamente ["pão","café","maçã"] (numa linha só).

<?php
$compras = ["pão", "café", "maçã"];
echo json_encode($compras), "\n";
<?php
$compras = ["pão", "café", "maçã"];
echo json_encode($compras, JSON_UNESCAPED_UNICODE), "\n";

Resumo

  • var_dump: tipo, tamanho e valor. A lupa para investigar. Não devolve nada.
  • print_r: legível, mas esconde tipos e mostra true como 1 e false/null como nada. Com true, devolve o texto.
  • var_export: o valor como código PHP; ótimo para booleanos e null.
  • json_encode: o valor em JSON; JSON_PRETTY_PRINT e JSON_UNESCAPED_UNICODE deixam legível.
  • No navegador, envolva com <pre>. Não deixe lupas no site publicado.
  • echo de um array dá Warning: Array to string conversion.