Skip to content

PHP 8.3 JSON Validation — Complete Guide to json_validate and JSON Features

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about PHP 8.3 JSON Validation. We cover key concepts, practical examples, and best practices to help you master this topic.

PHP 8.3 introduces json_validate() for validating JSON strings without Parsing, improving performance and memory usage for large payloads that only need validation.

What You'll Learn

By the end of this tutorial, you'll use json_validate to check JSON validity, handle validation errors, combine validation with decoding, and implement secure JSON processing.

Why JSON Validation Matters

Invalid JSON causes crashes when decoded. json_validate checks format without allocating memory for the decoded data, making it ideal for filtering large JSON payloads.

Real-World Use

An API Gateway validates incoming JSON payloads with json_validate before routing. Invalid payloads are rejected early without consuming memory for full decoding.

JSON Validation Path

flowchart LR
  A[Readonly Classes] --> B[JSON Validation]
  B --> C[Property Hooks]
  C --> D[PHP Features]
  D --> E[PSR Standards]
  B --> F{You Are Here}
  style F fill:#f90,color:#fff

json_validate Basics

json_validate returns true if the string is valid JSON, without decoding it.

<?php
$validJson = '{"name": "Alice", "age": 30}';
$invalidJson = '{name: "Alice", age: 30}';
var_dump(json_validate($validJson));
var_dump(json_validate($invalidJson));
if (json_validate($requestBody)) {
    $data = json_decode($requestBody, true);
} else {
    http_response_code(400);
    echo "Invalid JSON";
}

Depth Validation

json_validate accepts a maximum depth parameter to prevent deep nesting attacks.

<?php
$deepJson = '{"a": {"b": {"c": {"d": "value"}}}}';
var_dump(json_validate($deepJson, 3));
var_dump(json_validate($deepJson, 10));
function validateWithDepth(string $json, int $maxDepth = 20): bool {
    if (!json_validate($json, $maxDepth)) {
        throw new \InvalidArgumentException("JSON exceeds maximum depth of {$maxDepth}");
    }
    return true;
}

Error Handling with json_last_error

After validation failure, get specific error details.

<?php
function validateJson(string $json): array {
    if (!json_validate($json)) {
        return [
            "valid" => false,
            "error" => json_last_error_msg(),
            "code" => json_last_error(),
        ];
    }
    $data = json_decode($json, true);
    return [
        "valid" => true,
        "data" => $data,
    ];
}
$result = validateJson('{"name": "Alice", age: 30}');
echo $result["error"];

JSON_THROW_ON_ERROR

Use JSON_THROW_ON_ERROR flag with json_decode for exception-based error handling.

<?php
function parseJson(string $json): array {
    if (!json_validate($json)) {
        throw new \JsonException(json_last_error_msg());
    }
    try {
        return json_decode($json, true, flags: JSON_THROW_ON_ERROR | JSON_OBJECT_AS_ARRAY);
    } catch (\JsonException $e) {
        throw new \RuntimeException("Failed to decode JSON: " . $e->getMessage());
    }
}
try {
    $data = parseJson('{"valid": true}');
} catch (\RuntimeException $e) {
    echo $e->getMessage();
}

Batch JSON Validation

Validate multiple JSON strings in a loop for batch processing.

<?php
function validateBatch(array $jsonStrings): array {
    $results = [];
    foreach ($jsonStrings as $key => $json) {
        $results[$key] = [
            "valid" => json_validate($json),
            "size" => strlen($json),
        ];
    }
    return $results;
}
$batch = [
    '{"id": 1, "name": "Alice"}',
    '{"id": 2, name: "Bob"}',
    '{"id": 3, "name": "Charlie"}',
];
print_r(validateBatch($batch));

Common Mistakes

1. Forgetting json_validate Returns Boolean

json_validate returns true/false. It does not return the decoded data. Use json_decode after validation.

2. Not Setting Depth Limit

Without depth limits, deeply nested JSON can exhaust memory during validation.

3. Relying Only on json_validate for Security

Validation only checks format. Sanitize decoded data separately for XSS, injection, and type safety.

4. Ignoring json_last_error After Decode

decode can fail even if validate passes. Always check for decode errors.

5. Confusing json_validate with json_decode

json_validate is faster but only validates. json_decode validates and decodes. Use validate for large payloads where only validity is needed.

Practice Questions

1. What does json_validate return?

Returns true if the string is valid JSON, false otherwise.

2. What is the difference between json_validate and json_decode?

json_validate only checks format without decoding. json_decode validates and returns PHP data.

3. Why would you use json_validate before json_decode?

To reject invalid JSON early without allocating memory for decoding. Useful for large payloads.

4. How do you limit JSON nesting depth?

Pass the depth parameter to json_validate or json_decode. Default is 512.

5. Challenge: Create a middleware that validates incoming JSON request bodies.

<?php
function jsonBodyMiddleware(callable $handler): callable {
    return function ($request) use ($handler) {
        $body = (string) $request->getBody();
        if ($body !== "" && !json_validate($body)) {
            return new \Psr\Http\Message\ResponseInterface(400, [], "Invalid JSON");
        }
        return $handler($request);
    };
}

FAQ

Is json_validate faster than json_decode?

Yes, significantly for large payloads. json_validate does not allocate memory for the decoded data.

What flags does json_validate support?

Currently none. Depth is a parameter, not a flag.

Does json_validate check for duplicate keys?

No. Duplicate keys are valid JSON per spec. json_decode uses the last value.

Can I use json_validate on partial JSON?

No. Only complete valid JSON strings pass validation.

What PHP version introduced json_validate?

PHP 8.3. Use function_exists for backward compatibility.

Mini Project: JSON Request Validator

Build a request validation utility using PHP 8.3 features.

<?php
class JsonRequestValidator {
    public static function validate(string $rawBody): array {
        if (empty($rawBody)) {
            throw new \InvalidArgumentException("Request body is empty");
        }
        if (!json_validate($rawBody, 32)) {
            throw new \JsonException("Invalid JSON: " . json_last_error_msg());
        }
        $data = json_decode($rawBody, true, 32, JSON_THROW_ON_ERROR);
        return $data;
    }
    public static function validateBatch(array $bodies): array {
        return array_map(fn($body) => self::validate($body), $bodies);
    }
}

What's Next

PHP 8.4 Property Hooks PHP PSR Standards PHP JSON Handling

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro