PHP 8

json_validate no PHP 8.3: conferir se o JSON é válido sem decodificar

No PHP 8.3 dá para saber se uma string é JSON válido sem decodificar nada: json_validate($corpo) devolve true ou false e, quando falha, o motivo fica em json_last_error_msg(). Como não monta array nem objeto, a função gasta menos memória que o json_decode quando você só precisa aceitar ou recusar o conteúdo.

Quando usar json_validate em vez de json_decode?

Uso a json_validate onde o PHP recebe e repassa sem ler: webhook que vai para uma fila, payload que entra numa coluna JSON. Ali eu só quero recusar lixo cedo, com HTTP 400.

<?php
$corpo = file_get_contents('php://input');

if (!json_validate($corpo)) {
    http_response_code(400);
    error_log('Webhook com JSON inválido: ' . json_last_error_msg());
    exit;
}

// válido: grava cru na fila e responde rápido
file_put_contents('/var/spool/webhooks/' . uniqid('', true) . '.json', $corpo);
http_response_code(202);

Corpo vazio também cai no 400 sem if separado: json_validate('') volta false com “Syntax error”, e uma vírgula sobrando no fim do objeto dá o mesmo resultado.

Qual é a armadilha de validar e decodificar em seguida?

Chamar json_validate e logo depois json_decode na mesma string faz o PHP ler o JSON duas vezes, e o próprio manual do PHP avisa disso na página da função. Se você vai usar os dados na mesma requisição, decodifique direto e trate o erro como exceção:

try {
    $dados = json_decode($corpo, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
    http_response_code(400);
    exit('JSON inválido: ' . $e->getMessage());
}

O que muda nos parâmetros e no PHP 8.2?

A assinatura é json_validate(string $json, int $depth = 512, int $flags = 0): bool. Em $flags, só JSON_INVALID_UTF8_IGNORE é aceito; outra flag ou profundidade zero dispara ValueError. E, se a validação passou, o json_decode com a mesma profundidade e as mesmas flags também passa.

No PHP 8.2 a função não existe e o resultado é Call to undefined function json_validate(). Para código que roda nas duas versões, o pacote symfony/polyfill-php83 traz a função.

Post Recentes

Prompt injection em campo de usuário: isole a observação do pedido

A observação do pedido chegou com ordem embutida para gerar cupom. Delimite o texto do cliente e trate a resposta…

9 horas atrás

Preço promocional em massa no WooCommerce: agendar a Black Friday pelo WP-CLI

Um CSV com SKU e preço, um wp eval-file que agenda início e fim da promoção guardando o estado anterior,…

15 horas atrás

Too many connections no MySQL: achar quem segura as conexões antes de subir o limite

O erro 1040 aparece quando todas as conexões estão ocupadas. Antes de subir o max_connections, veja quem está segurando cada…

1 dia atrás

WP_MEMORY_LIMIT no WordPress: resolver memória esgotada no PHP 8.3

Allowed memory size exhausted no painel: qual das duas constantes do wp-config.php mexer, onde conferir o valor real e por…

2 dias atrás

Converter data dd/mm/aaaa para o MySQL com DateTime::createFromFormat

strtotime com data brasileira devolve false e o INSERT quebra no MySQL 8. Use createFromFormat com getLastErrors antes de mandar…

4 dias atrás

Erro 500 no Magento 2: achar o relatório em var/report pelo ID da tela

O hash que o Magento mostra junto do erro é o nome de um arquivo em var/report. Veja como abrir,…

5 dias atrás