Como formatar e validar JSON em JavaScript, Python e PHP
Formatar JSON é ler o texto e escrevê-lo de novo com quebras de linha e recuo. Validar é tentar ler e tratar o erro. Este guia mostra as duas coisas em JavaScript, Python e PHP, lista os erros que mais quebram um JSON e explica as diferenças que pegam de surpresa, como acentos escapados no PHP e NaN aceito no Python.
Os erros que mais quebram um JSON
- Vírgula sobrando depois do último item:
{"a": 1,}. - Aspas simples em vez de duplas:
{'a': 1}. O JSON só aceita aspas duplas. - Chaves sem aspas:
{a: 1}. Isso é objeto de JavaScript, não JSON. - Valores que o JSON não tem:
undefined,NaN,Infinity, comentários e datas sem aspas.
O validador de JSON aponta a linha e a coluna do erro, e o formatador de JSON deixa o texto legível. Em código, o caminho é o mesmo: ler, tratar o erro e escrever de novo.
Em JavaScript
O terceiro argumento de JSON.stringify define o recuo. A mensagem de erro do JSON.parse muda entre navegadores e versões do Node.js, então use-a para mostrar ao usuário, não para tomar decisões no código.
function formatarJSON(texto, espacos = 2) {
return JSON.stringify(JSON.parse(texto), null, espacos);
}
function validarJSON(texto) {
try {
JSON.parse(texto);
return { valido: true };
} catch (erro) {
return { valido: false, mensagem: erro.message };
}
} Em Python
O json.loads aceita NaN e Infinity, que não são JSON: o parse_constant recusa esses valores. Sem ensure_ascii=False, o json.dumps escreve \u00e7 no lugar de ç. O erro traz a linha e a coluna.
import json
def _recusar(nome):
raise ValueError(f"{nome} não é JSON válido")
def formatar_json(texto: str, espacos: int = 2) -> str:
# parse_constant: o Python aceitaria NaN e Infinity, que o JSON não permite
dados = json.loads(texto, parse_constant=_recusar)
return json.dumps(dados, indent=espacos, ensure_ascii=False)
def validar_json(texto: str) -> dict:
try:
json.loads(texto, parse_constant=_recusar)
return {"valido": True}
except json.JSONDecodeError as e:
return {"valido": False, "mensagem": e.msg, "linha": e.lineno, "coluna": e.colno}
except ValueError as e:
return {"valido": False, "mensagem": str(e)} Em PHP
Com JSON_THROW_ON_ERROR, o json_decode lança uma exceção em vez de devolver null em silêncio, o que evita confundir um JSON inválido com o valor null. O JSON_PRETTY_PRINT usa quatro espaços. No PHP 8.3 ou mais novo, json_validate confere sem montar os dados.
<?php
function formatarJson(string $texto): string
{
$dados = json_decode($texto, false, 512, JSON_THROW_ON_ERROR);
// Sem as duas últimas opções, o PHP escreveria \u00e7 no lugar de ç
// e \/ no lugar de /
return json_encode(
$dados,
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
);
}
function validarJson(string $texto): array
{
try {
json_decode($texto, false, 512, JSON_THROW_ON_ERROR);
return ['valido' => true];
} catch (JsonException $e) {
return ['valido' => false, 'mensagem' => $e->getMessage()];
}
} Diferenças entre as linguagens
- Números: o JavaScript escreve
1.0como1, e o Python mantém1.0. Os dois são o mesmo número em JSON. - Números grandes: no JavaScript, inteiros acima de 9007199254740991 perdem precisão no
JSON.parse. IDs grandes devem trafegar como texto. - Objeto vazio no PHP: com
json_decode($texto, true), o{}vira array vazio e volta como[]. Por isso o exemplo usa objetos (false). - Ordem das chaves: as três linguagens mantêm a ordem do texto, mas o JSON não garante ordem. Não dependa dela.
Achou um erro neste guia? Avise por e-mail.
Perguntas frequentes
Como formatar JSON em JavaScript?
Use JSON.stringify(JSON.parse(texto), null, 2). O último argumento é o número de espaços do recuo. Se o texto não for JSON válido, o JSON.parse lança um erro.
JSON aceita comentários?
Não. Comentários, vírgula sobrando e aspas simples tornam o texto inválido. Alguns formatos derivados, como o JSONC usado em arquivos de configuração, aceitam comentários, mas não são JSON puro.
Por que o PHP escreve \u00e7 no lugar de ç no JSON?
Por padrão, o json_encode escapa caracteres fora do ASCII. A opção JSON_UNESCAPED_UNICODE mantém os acentos. O resultado é equivalente, mas fica mais legível e menor.
Como achar o erro em um JSON grande?
Use uma ferramenta que mostre a linha e a coluna, como o validador de JSON do PraDev, ou o json.loads do Python, que traz essas informações no erro.