JSON (JavaScript Object Notation) é um formato leve de intercâmbio de dados, amplamente utilizado em APIs e comunicação entre sistemas. No PHP, trabalhar com JSON é simples graças às funções nativas json_encode e json_decode. Nesta aula, exploraremos essas funções em detalhes, incluindo flags para controle de saída, a diferença entre objetos e arrays associativos, e como lidar com erros de forma robusta.

O domínio do JSON é essencial para qualquer desenvolvedor PHP, pois é o formato padrão em muitas aplicações modernas, como serviços RESTful, armazenamento de configurações e troca de dados com JavaScript.

json_encode e json_decode

A função json_encode converte um valor PHP (como arrays ou objetos) em uma string JSON. Já json_decode faz o inverso: converte uma string JSON em um valor PHP. Vamos ver exemplos básicos.

<?php
$data = ["nome" => "João", "idade" => 30, "ativo" => true];
$json = json_encode($data);
echo $json; // {"nome":"João","idade":30,"ativo":true}

$jsonString = '{"nome":"Maria","idade":25}';
$array = json_decode($jsonString, true); // segundo parâmetro true retorna array associativo
print_r($array);
/*
Array
(
    [nome] => Maria
    [idade] => 25
)
*/
?>

O segundo parâmetro de json_decode controla o tipo de retorno: true para array associativo, false (padrão) para objeto stdClass. Sempre que possível, use true para facilitar o acesso aos dados.

Flags

As funções json_encode e json_decode aceitam flags que modificam seu comportamento. As principais flags para json_encode são:

  • JSON_PRETTY_PRINT: formata o JSON com indentação para legibilidade.
  • JSON_UNESCAPED_UNICODE: não escapa caracteres Unicode (útil para acentos).
  • JSON_UNESCAPED_SLASHES: não escapa barras /.
  • JSON_NUMERIC_CHECK: converte strings numéricas em números.
  • JSON_FORCE_OBJECT: força a saída como objeto mesmo para arrays vazios.

Exemplo com JSON_PRETTY_PRINT e JSON_UNESCAPED_UNICODE:

<?php
$data = ["nome" => "João", "cidade" => "São Paulo"];
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
/*
{
    "nome": "João",
    "cidade": "São Paulo"
}
*/
?>

Para json_decode, a flag JSON_OBJECT_AS_ARRAY é equivalente a passar true como segundo parâmetro. Outra flag útil é JSON_BIGINT_AS_STRING, que evita perda de precisão em números inteiros grandes.

Objetos vs arrays associativos

Ao decodificar JSON, você pode escolher entre obter objetos da classe stdClass ou arrays associativos. A diferença é sutil: objetos usam sintaxe de propriedade (->), arrays usam colchetes ([]). Para arrays aninhados, objetos podem ser mais confusos. Exemplo:

<?php
$json = '{"nome":"Ana","endereco":{"rua":"Rua A","numero":123}}';
$obj = json_decode($json); // objeto
echo $obj->nome; // Ana
echo $obj->endereco->rua; // Rua A

$arr = json_decode($json, true); // array
echo $arr['nome']; // Ana
echo $arr['endereco']['rua']; // Rua A
?>

Recomenda-se usar arrays associativos (true) para consistência e facilidade de acesso, especialmente em dados complexos.

Tratamento de erros

As funções JSON retornam false em caso de erro. Para obter detalhes, use json_last_error() e json_last_error_msg(). Exemplo:

<?php
$json = '{nome:"João"}'; // JSON inválido (faltam aspas na chave)
$data = json_decode($json);
if (json_last_error() !== JSON_ERROR_NONE) {
    echo "Erro: " . json_last_error_msg(); // Erro: Syntax error
}
?>

Lista de erros comuns:

  • JSON_ERROR_DEPTH: profundidade máxima excedida.
  • JSON_ERROR_STATE_MISMATCH: erro de estado.
  • JSON_ERROR_CTRL_CHAR: caractere de controle encontrado.
  • JSON_ERROR_SYNTAX: erro de sintaxe.
  • JSON_ERROR_UTF8: caracteres UTF-8 malformados.
  • JSON_ERROR_RECURSION: recursão infinita.

Sempre verifique erros ao decodificar JSON de fontes externas para evitar falhas inesperadas.

Boas práticas

  • Sempre use JSON_UNESCAPED_UNICODE ao codificar strings com acentos.
  • Em APIs, considere usar JSON_PRETTY_PRINT apenas em desenvolvimento; em produção, minimize o JSON.
  • Valide o JSON recebido antes de processar, usando json_last_error().
  • Prefira arrays associativos para manipulação de dados.

Referências

Exercícios

  1. Crie um array associativo com informações de um livro (título, autor, ano) e codifique-o em JSON com pretty print e sem escapar Unicode.

    ✓ Resposta:
    <?php
    $livro = [
        "titulo" => "Dom Casmurro",
        "autor" => "Machado de Assis",
        "ano" => 1899
    ];
    echo json_encode($livro, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    ?>
  2. Decodifique a string JSON '{"nome":"Carlos","idade":"30"}' em um array associativo e exiba a idade como inteiro.

    ✓ Resposta:
    <?php
    $json = '{"nome":"Carlos","idade":"30"}';
    $arr = json_decode($json, true);
    echo (int)$arr['idade']; // 30
    ?>
  3. Codifique um array vazio como objeto JSON (use flag).

    ✓ Resposta:
    <?php
    echo json_encode([], JSON_FORCE_OBJECT); // {}
    ?>
  4. Decodifique um JSON inválido e capture o erro, exibindo a mensagem.

    ✓ Resposta:
    <?php
    $json = '{invalido}';
    $data = json_decode($json);
    if (json_last_error() !== JSON_ERROR_NONE) {
        echo "Erro: " . json_last_error_msg();
    }
    ?>
  5. Crie uma função que receba um array e retorne uma string JSON com indentação, sem escapar barras e sem escapar Unicode.

    ✓ Resposta:
    <?php
    function arrayParaJson($arr) {
        return json_encode($arr, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
    }
    echo arrayParaJson(["url" => "https://exemplo.com/api", "nome" => "João"]);
    ?>