Question
I need an efficient way to check whether a string contains valid JSON in PHP. Right now I am using this approach, but I suspect it is not ideal:
function isJson($string) {
return is_string($string) &&
(is_object(json_decode($string)) || is_array(json_decode($string)));
}
Is there a faster or better way to validate whether a string is JSON? I am especially interested in correctness and performance.
Short Answer
By the end of this page, you will understand how JSON validation works in PHP, why calling json_decode() multiple times is wasteful, and how to correctly check JSON using json_last_error() or exceptions. You will also see practical examples, common mistakes, and a small project that turns this idea into reusable validation code.
Concept
JSON validation in PHP is usually done by trying to decode the string and then checking whether decoding succeeded.
The key idea is:
- PHP does not provide a separate "is this JSON?" parser that is faster than decoding.
- In practice, you validate JSON by calling
json_decode(). - After decoding, you inspect whether an error occurred.
A common beginner mistake is to decide based on the decoded value's type, such as checking is_object() or is_array(). That seems reasonable at first, but valid JSON is not limited to objects and arrays.
These are all valid JSON values:
{"name":"Ada"}
[1, 2, 3]
"hello"
123
true
Mental Model
Think of json_decode() like a language translator.
- You hand it a string.
- It tries to translate that string from JSON into a PHP value.
- If translation succeeds, the JSON was valid.
- If translation fails, PHP records the reason.
The important part is that you do not ask, "Did I get an object or array?" Instead, you ask, "Did the translator report an error?"
That mental model helps because JSON can translate into many different PHP value types, not just arrays and objects.
Syntax and Examples
The standard pattern in PHP is:
function isJson(string $string): bool
{
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
Example
var_dump(isJson('{"name":"Ada"}')); // true
var_dump(isJson('[1,2,3]')); // true
var_dump(isJson('"hello"')); // true
var_dump(isJson('123')); // true
var_dump(isJson('not json')); // false
Why this is better
json_decode()is called only once.- It works for all valid JSON values.
Step by Step Execution
Consider this function:
function isJson(string $string): bool
{
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
Now trace this input:
$input = '{"active":true}';
$result = isJson($input);
Step by step
$inputstores the string{"active":true}.isJson($input)is called.- Inside the function,
json_decode($string)tries to parse the string. - PHP successfully understands the JSON.
json_last_error()returnsJSON_ERROR_NONE.- The comparison becomes
true. - The function returns
true.
Real World Use Cases
Here are common situations where JSON validation appears in real PHP applications:
API request handling
A server receives JSON in a request body and must reject malformed payloads.
$body = file_get_contents('php://input');
if (!isJson($body)) {
http_response_code(400);
echo 'Invalid JSON';
exit;
}
Reading configuration from a file
$configText = file_get_contents('config.json');
if (!isJson($configText)) {
die('Configuration file is not valid JSON');
}
Importing queue messages
Workers often consume JSON messages from queues such as Redis, RabbitMQ, or SQS.
$message = '{"task":"resize-image","id":42}';
if (isJson($message)) {
$data = json_decode(, );
}
Real Codebase Usage
In real projects, developers usually do more than just "check if it is JSON."
Decode once and keep the result
If you need the decoded data, avoid decoding once for validation and again for usage.
$data = json_decode($input, true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new InvalidArgumentException('Invalid JSON: ' . json_last_error_msg());
}
This pattern is better because parsing happens only once.
Guard clauses
A common pattern is to fail early when input is invalid.
$data = json_decode($payload, true);
if (json_last_error() !== JSON_ERROR_NONE) {
return ['error' => 'Invalid JSON'];
}
Validation after decoding
Valid JSON does not mean valid business data.
$data = json_decode($payload, );
(() !== JSON_ERROR_NONE) {
();
}
(!([])) {
();
}
Common Mistakes
1. Decoding multiple times
Broken approach:
function isJson($string) {
return is_object(json_decode($string)) || is_array(json_decode($string));
}
Problem:
json_decode()runs twice.- Parsing JSON is the expensive part.
- Repeating it wastes time.
Fix:
function isJson(string $string): bool
{
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
2. Assuming valid JSON must be an object or array
Broken assumption:
var_dump(isJson('123'));
(());
Comparisons
| Approach | What it checks | Correct for all valid JSON? | Performance | Best use case |
|---|---|---|---|---|
| `is_object(json_decode(...)) | is_array(json_decode(...))` | Whether decoded result is object or array | No | |
json_decode(...); json_last_error() === JSON_ERROR_NONE | Whether parsing succeeded | Yes | Good | General JSON validation |
json_decode(..., true); is_array($decoded) | Whether JSON is object/array-like data | No, only for structured JSON | Good | APIs expecting objects or arrays |
json_decode(..., true, 512, JSON_THROW_ON_ERROR) | Whether parsing succeeded, via exception | Yes |
Cheat Sheet
// Check if a string is valid JSON
function isJson(string $string): bool
{
json_decode($string);
return json_last_error() === JSON_ERROR_NONE;
}
// Decode and throw on invalid JSON
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
Rules to remember
json_decode()is the normal way to validate JSON in PHP.- Call it once if possible.
- Use
json_last_error()orJSON_THROW_ON_ERROR. - Valid JSON can be:
- object
- array
- string
- number
- boolean
null
- Do not assume only arrays or objects are valid.
json_decode('null')returnsnull, but it is still valid JSON.
Useful helpers
FAQ
Is json_decode() the fastest way to check JSON in PHP?
Yes, in practice this is the standard and efficient way. PHP validates JSON by parsing it, so decoding is the normal approach.
Why is calling json_decode() twice a problem?
Because parsing happens twice. That adds unnecessary work and gives no benefit.
Why does checking is_array() or is_object() reject some valid JSON?
Because valid JSON can also be a string, number, boolean, or null, not just an object or array.
How do I get the reason JSON parsing failed?
Use json_last_error_msg() after json_decode().
Should I use json_last_error() or JSON_THROW_ON_ERROR?
For simple scripts, json_last_error() is fine. For modern applications, JSON_THROW_ON_ERROR is often cleaner.
Is null valid JSON in PHP?
Yes. The string null is valid JSON.
How can I check that JSON is specifically an object or array?
Mini Project
Description
Build a small PHP utility that validates incoming JSON payloads and returns either decoded data or a readable error message. This mirrors a common backend task when handling API requests, webhooks, or configuration files.
Goal
Create a reusable JSON parser that detects invalid JSON and safely returns decoded PHP data.
Requirements
- Write a function that accepts a JSON string.
- Decode the JSON only once.
- Return a success result with decoded data when the JSON is valid.
- Return an error result with a helpful message when the JSON is invalid.
- Demonstrate the function with both valid and invalid examples.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.