← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

json_validate() — Native JSON Validation (PHP 8.3)

PHP PHP 8.3+ Beginner
debt(d7/e1/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7). The detection_hints.tools list is not specified, so no automated tool is cited from metadata. The misuse pattern — calling json_validate() then json_decode() incorrectly, or using it as a schema validator — is a logic-level mistake that won't surface as a syntax or lint error. It requires code review to spot the wrong branch (decoding on false) or a functional test to catch silent failures from missing JSON_THROW_ON_ERROR. No compiler or default linter catches this.

e1 Effort Remediation debt — work required to fix once spotted

Closest to 'one-line patch or single-call swap' (e1). The quick_fix explicitly describes replacing the old json_decode()+json_last_error() validation pattern with a single 'if (!json_validate($s))' guard clause. This is a straightforward, localised one-line replacement at each call site — no structural refactor required.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). The choice applies to web, cli, and queue-worker contexts per applies_to, but each usage is an independent call-site guard clause. It does not impose cross-cutting architectural obligations. The main ongoing tax is remembering to pair it correctly with json_decode(), which is a per-developer, per-call-site awareness cost rather than a system-wide burden.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field explicitly states the canonical trap: developers assume json_validate() replaces json_decode() and then omit the decode entirely, or decode in the wrong branch. This is a documented, well-known gotcha (it only checks validity, not usability), and several common_mistakes reinforce it — especially the error of decoding on the false branch and missing JSON_THROW_ON_ERROR. It's a trap most developers hit once, placing it squarely at t5.

About DEBT scoring →

Also Known As

json_validate PHP 8.3 JSON JSON validation PHP

TL;DR

PHP 8.3 added json_validate() — a dedicated function that checks whether a string is valid JSON without decoding it, making validation faster and cheaper than json_decode() + error checking.

Explanation

Before PHP 8.3, the only way to validate JSON was to call json_decode() and check json_last_error() — which allocated memory to build the decoded value even though you only wanted to know if the string was valid. json_validate() parses the JSON structure without building a PHP data structure, making it significantly faster and less memory-intensive for large payloads. It returns true/false. It accepts the same optional depth and flags arguments as json_decode(). This is ideal for webhook handlers, API input validation, and message queue consumers that need to validate incoming JSON before forwarding to a decoder.

Common Misconception

json_validate() replaces json_decode(). It doesn't — it only tells you whether the string is valid JSON. You still need json_decode() to actually use the data. json_validate() is for the guard clause before decoding.

Why It Matters

For high-throughput APIs or queue workers that receive many JSON payloads, using json_decode() purely for validation wastes significant memory and CPU. json_validate() is a zero-allocation check — it scans the JSON structure and returns immediately. On a service processing thousands of messages per second, this can meaningfully reduce memory pressure.

Common Mistakes

  • Calling json_validate() and then immediately calling json_decode() on failure — json_validate() returns false on invalid JSON, so the decode should only happen in the true branch.
  • Using json_validate() as a substitute for schema validation — it only checks JSON syntax, not whether the structure matches your expected schema.
  • Not specifying a depth limit for untrusted input — deeply nested JSON can cause stack overflows; json_validate($input, depth: 10) is safer for external data.
  • Forgetting JSON_THROW_ON_ERROR on json_decode() after validation — json_decode() can still return null for valid JSON ('null' is valid JSON), so throw-on-error prevents silent failures.

Code Examples

✗ Vulnerable
<?php
// ❌ Using json_decode() purely for validation — wasteful
function handleWebhook(string $body): void
{
    $data = json_decode($body, true); // Allocates full PHP array
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new InvalidArgumentException('Invalid JSON');
    }
    // Now decode again (or use $data — but you allocated it twice if validating first)
    processPayload($data);
}
✓ Fixed
<?php
// ✅ PHP 8.3 — validate cheaply, decode only once
function handleWebhook(string $body): void
{
    if (!json_validate($body)) {
        throw new InvalidArgumentException('Invalid JSON payload');
    }
    // Decode only after confirming validity
    $data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
    processPayload($data);
}

// With depth limit for untrusted input
if (!json_validate($untrustedInput, depth: 5)) {
    return false;
}

Added 23 Mar 2026
Views 44
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 2 pings W 1 ping T 1 ping F 0 pings S 0 pings S 2 pings M 1 ping T 0 pings W 0 pings T 1 ping F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 1 ping W
SEMrush 1
No pings yesterday
Amazonbot 10 Scrapy 6 ChatGPT 4 Ahrefs 3 Perplexity 2 Google 2 Claude 1 Bing 1 Meta AI 1 Majestic 1 PetalBot 1 SEMrush 1
crawler 30 crawler_json 3
DEV INTEL Tools & Severity
⚙ Fix effort: Low
⚡ Quick Fix
Replace 'json_decode($s); if (json_last_error() !== JSON_ERROR_NONE)' validation patterns with 'if (!json_validate($s))' — then only call json_decode() when you actually need the data.
📦 Applies To
PHP 8.3+ web cli queue-worker


✓ schema.org compliant