Signature
json_validate(string $json, int $depth = 512, int $flags = 0): boolPurpose
json_validate() answers one question: is this string syntactically valid JSON? It returns a boolean and never builds the array or object that the text describes. That makes it useful when you only need a yes or no, such as screening a stored payload, checking a field before saving it, or rejecting malformed input early. Because no decoded structure is created, it needs less memory than json_decode() when you would throw the result away.
The manual lists the function as available from PHP 8.3, so it is present in PHP 8.4.
Signature
Parameters and defaults
$json: the string to check. It must be UTF-8 encoded.$depth: the maximum nesting depth. The default is512. The value must be greater than0and no larger than2147483647.$flags: defaults to0. The only flag accepted at present isJSON_INVALID_UTF8_IGNORE.
Return value and failure cases
The function returns true when the text is valid JSON and false otherwise. A false result is not an exception. To find out why validation failed, call json_last_error() or json_last_error_msg() straight afterwards.
A ValueError is thrown, instead of returning false, when the arguments themselves are unacceptable: a $depth outside the allowed range, or a $flags value that is not a valid flag. Treat these as programming errors, not as bad user input.
If json_validate() returns true, json_decode() will decode the same string successfully, provided you pass the same depth and flags.
Example 1: valid and invalid text
Any JSON value is valid at the top level, not only objects and arrays. Scalars such as numbers, strings and null pass. Trailing commas, single-quoted strings and empty input do not.
$inputs = [
'{"name":"Ada","tags":["php","json"]}',
'[1, 2, 3]',
'"text"',
'42',
'null',
'{"name":"Ada",}',
"{'name':'Ada'}",
'',
];
$results = [];
foreach ($inputs as $input) {
$results[] = json_validate($input);
}
echo json_encode($results), "\n";[true,true,true,true,true,false,false,false]
Example 2: limiting depth
The depth limit applies to the parser stack, so do not assume that counting visible brackets gives a sufficient limit. In PHP 8.4, [1] needs a limit of at least 2, [[1]] needs at least 3, and the three-level object below needs at least 4. A well-formed document still returns false when the limit is too small.
echo json_encode([
json_validate('[1]', 2),
json_validate('[[1]]', 2),
json_validate('[[1]]', 3),
json_validate('{"a":{"b":{"c":1}}}', 4),
json_validate('{"a":{"b":{"c":1}}}', 3),
]), "\n";[true,false,true,true,false]
A small depth is a handy guard when the input comes from outside your program, because it caps how complex a payload you are willing to accept.
Example 3: reading the error message and using the flag
After a call, json_last_error_msg() describes the outcome. The helper below packages the result and message together. The last two lines show a string containing the invalid UTF-8 byte \xFF: it fails normally, but passes when JSON_INVALID_UTF8_IGNORE is given.
function check(string $json, int $flags = 0): string {
$valid = json_validate($json, 512, $flags);
return json_encode(['valid' => $valid, 'message' => json_last_error_msg()]);
}
echo check('{"a":1}'), "\n";
echo check('{"a":1'), "\n";
$bad = "\"a\xFF\"";
echo check($bad), "\n";
echo check($bad, JSON_INVALID_UTF8_IGNORE), "\n";{"valid":true,"message":"No error"}
{"valid":false,"message":"Syntax error"}
{"valid":false,"message":"Malformed UTF-8 characters, possibly incorrectly encoded"}
{"valid":true,"message":"No error"}
Edge cases
- Syntax only: the function does not know your data model.
{"age":"not a number"}is valid JSON even if your application expects an integer. Check the structure separately. - Empty or whitespace-only strings are not valid JSON, so they return
false. - The error state belongs to the most recent call. Read it immediately, before calling another JSON function.
- The manual notes that PHP implements a superset of the original RFC 7159 specification, so rely on the function's result rather than on your own assumptions about the grammar.
- Only
JSON_INVALID_UTF8_IGNOREis accepted for$flags. Flags that helpjson_decode(), such asJSON_THROW_ON_ERROR, are not valid here and cause aValueError.
Common mistakes
- Validating and then decoding. Calling
json_validate()right beforejson_decode()makes PHP parse the text twice, because decoding already validates. If you need the data, decode once and check for failure. Usejson_validate()when you do not need the decoded value right away. - Treating
falseas an exception. Bad JSON just givesfalse. Only invalid arguments raiseValueError. - Passing
0or a negative depth. The depth has to be at least 1. - Forgetting the encoding. Input must be UTF-8. Text in another encoding may fail with a malformed UTF-8 error.
- Reading the error too late. Another JSON call in between can overwrite the message you wanted.
- Assuming validity means safety. A valid document can still be huge or hold unexpected values. Combine the depth limit with your own size and content checks.
Related functions
json_decode()turns a JSON string into PHP data.json_last_error()returns the numeric code of the last JSON error.json_last_error_msg()returns a readable message for the lastjson_validate(),json_encode()orjson_decode()call.
Recap
json_validate() checks syntax and returns a boolean without creating decoded data. Set $depth to limit nesting, use JSON_INVALID_UTF8_IGNORE only when you deliberately tolerate bad UTF-8, and read json_last_error_msg() for the reason behind a false. When you need the decoded value, call json_decode() once instead of validating first.
Tested examples
$inputs = [
'{"name":"Ada","tags":["php","json"]}',
'[1, 2, 3]',
'"text"',
'42',
'null',
'{"name":"Ada",}',
"{'name':'Ada'}",
'',
];
$results = [];
foreach ($inputs as $input) {
$results[] = json_validate($input);
}
echo json_encode($results), "\n";
[true,true,true,true,true,false,false,false]
echo json_encode([
json_validate('[1]', 2),
json_validate('[[1]]', 2),
json_validate('[[1]]', 3),
json_validate('{"a":{"b":{"c":1}}}', 4),
json_validate('{"a":{"b":{"c":1}}}', 3),
]), "\n";
[true,false,true,true,false]
function check(string $json, int $flags = 0): string {
$valid = json_validate($json, 512, $flags);
return json_encode(['valid' => $valid, 'message' => json_last_error_msg()]);
}
echo check('{"a":1}'), "\n";
echo check('{"a":1'), "\n";
$bad = "\"a\xFF\"";
echo check($bad), "\n";
echo check($bad, JSON_INVALID_UTF8_IGNORE), "\n";
{"valid":true,"message":"No error"}
{"valid":false,"message":"Syntax error"}
{"valid":false,"message":"Malformed UTF-8 characters, possibly incorrectly encoded"}
{"valid":true,"message":"No error"}