Question
JSON vs serialize() in PHP: Choosing How to Store Arrays
Question
I need to store a multi-dimensional associative array in a flat file for caching. Most of the time, I will read the data back into PHP as an array, but occasionally I may need to convert it to JSON for use in a web application.
Would it be better to store the data as JSON or as a PHP serialized array in the cache file?
I have read that in newer versions of PHP, json_decode() can sometimes be faster than unserialize(). I am currently leaning toward JSON because:
- it is easier for humans to read,
- it can be used by both PHP and JavaScript with little extra work,
- and it may even decode faster in some cases.
Are there any important pitfalls to consider? Are there reliable benchmarks or practical reasons to prefer one format over the other?
Example of the kind of data being stored:
$data = [
'user' => [
'id' => 42,
'name' => 'Alice',
'roles' => ['admin', 'editor']
],
'settings' => [
'theme' => 'dark',
'notifications' => true
]
];
Short Answer
By the end of this page, you will understand the trade-offs between json_encode()/json_decode() and serialize()/unserialize() in PHP. You will learn which format is better for portability, readability, type preservation, performance, and caching use cases, and how to choose the right one for real projects.
Concept
When you want to save a PHP array into a file, database, or cache, you usually need to convert it into a string first. This process is called serialization.
In PHP, two common ways to do this are:
serialize()/unserialize()json_encode()/json_decode()
Although both turn data into a string and back again, they are designed for different goals.
serialize()
serialize() is PHP-specific. It is built to preserve PHP data structures as accurately as possible.
It can store:
- associative arrays
- indexed arrays
- strings
- integers
- floats
- booleans
null- objects
This makes it useful when the data will stay inside PHP and you need to preserve PHP-specific types.
JSON
JSON is a language-independent text format. It is ideal when data needs to move between systems, especially between PHP and JavaScript.
It is usually:
- easier to read
- easier to inspect manually
- widely supported
- good for APIs, config files, and frontend communication
But JSON does not represent every PHP type exactly the same way. For example, it does not distinguish between associative arrays and objects in the same PHP-specific way, and it cannot represent PHP objects like serialize() can.
Why this matters
Choosing the format affects:
- portability: can other languages read it?
- type fidelity: does it preserve PHP data exactly?
- safety: can decoding untrusted data create risks?
- performance: how fast is encoding and decoding?
- debugging: can humans inspect the cached file easily?
For a cache file containing a multi-dimensional associative array, the best choice usually depends on whether you value cross-language use and readability more than full PHP type preservation.
A practical rule is:
- Use JSON when the data is simple and may be consumed outside PHP.
- Use
serialize()when you need exact PHP type preservation.
For many array-based cache cases, JSON is a strong choice if your data contains only standard scalar and array values.
Mental Model
Think of these two formats as different kinds of storage boxes:
serialize()is a box designed specifically for PHP. It labels everything in a way PHP understands very precisely.- JSON is a universal shipping box. Many languages can open it, but it may not preserve every PHP-specific detail.
If your data is staying inside a PHP-only room, the PHP box may be convenient.
If your data might travel to JavaScript, an API, or be inspected by humans, the universal box is often better.
Another way to think about it:
serialize()says: "store this exactly as PHP sees it."- JSON says: "store this in a common format that many systems understand."
Syntax and Examples
Here is the basic syntax for both approaches.
Using serialize()
$data = [
'name' => 'Alice',
'age' => 30,
'active' => true
];
$serialized = serialize($data);
file_put_contents('cache.txt', $serialized);
$loaded = unserialize(file_get_contents('cache.txt'));
print_r($loaded);
What this does
serialize($data)converts the PHP array into a PHP-specific string.file_put_contents()writes that string to a file.unserialize()converts it back into a PHP value.
Using JSON
$data = [
'name' => 'Alice',
'age' => 30,
'active' => true
];
$json = json_encode($data);
file_put_contents('cache.json', $json);
$loaded = json_decode(file_get_contents('cache.json'), true);
print_r($loaded);
What this does
json_encode($data)converts the array to JSON text.json_decode(..., true)converts JSON back into a PHP associative array.- The second argument
trueis important if you want an array instead of an object.
Comparing the output
Serialized output
a:3:{s:4:"name";s:5:"Alice";s:3:"age";i:30;s:6:"active";b:1;}
JSON output
{"name":"Alice","age":30,"active":true}
JSON is usually easier to inspect manually.
Example with nested associative arrays
$data = [
'user' => [
'id' => 42,
'name' => 'Alice',
'roles' => ['admin', 'editor']
],
'settings' => [
'theme' => 'dark',
'notifications' => true
]
];
$json = json_encode($data, JSON_PRETTY_PRINT);
echo $json;
Output:
{
"user": {
"id": 42,
"name": "Alice",
"roles": [
"admin",
"editor"
]
},
"settings": {
"theme": "dark",
"notifications": true
}
}
This readability is one reason JSON is popular for cache files and configuration-like data.
Step by Step Execution
Consider this example using JSON for a cache file.
$data = [
'product' => [
'id' => 10,
'name' => 'Keyboard'
],
'in_stock' => true
];
$json = json_encode($data);
file_put_contents('cache.json', $json);
$contents = file_get_contents('cache.json');
$loaded = json_decode($contents, true);
echo $loaded['product']['name'];
Step-by-step
1. Create the PHP array
$data = [
'product' => [
'id' => 10,
'name' => 'Keyboard'
],
'in_stock' => true
];
At this point, $data is a normal nested PHP array.
2. Encode it as JSON
$json = json_encode($data);
Now $json contains a string like this:
{"product":{"id":10,"name":"Keyboard"},"in_stock":true}
3. Save it to a file
file_put_contents('cache.json', $json);
The string is written to disk.
4. Read the file back
$contents = file_get_contents('cache.json');
Now $contents is the JSON string from the file.
5. Decode back to a PHP array
$loaded = json_decode($contents, true);
Because of true, $loaded becomes an associative array.
6. Access nested values
echo $loaded['product']['name'];
This prints:
Keyboard
Important note
If you forget the second argument in json_decode():
$loaded = json_decode($contents);
then $loaded becomes an object, and you would need:
echo $loaded->product->name;
Real World Use Cases
Here are common situations where this choice matters.
1. File-based caching
If you generate expensive data once and want to reuse it later, you can store it in a flat file.
- JSON works well for arrays of settings, API responses, menu structures, and content metadata.
serialize()works well when the cached data includes PHP-specific structures.
2. API responses
If the cached data may later be sent directly to the browser or another service, JSON is often the best format because it is already API-ready.
3. Configuration snapshots
Readable configuration exports are easier to debug as JSON.
4. Storing session-like internal PHP data
If the data stays fully inside PHP and must preserve exact PHP values, serialize() may be more suitable.
5. Data sharing between backend and frontend
If the same cached data is used in PHP and JavaScript, JSON avoids an extra conversion step.
6. Logging and diagnostics
Human-readable JSON files are often easier to inspect during debugging than serialized PHP strings.
Real Codebase Usage
In real codebases, developers usually choose based on data shape, consumers, and safety.
Common patterns
Use JSON for plain data structures
Teams often store simple arrays in JSON when the data contains only:
- strings
- numbers
- booleans
- null
- nested arrays
This is common for:
- cached API payloads
- feature flags
- configuration data
- frontend-ready content
Use serialize() for PHP-only values
Developers may use serialize() when they need to preserve:
- exact PHP arrays
- objects
- special internal structures
But many teams avoid storing serialized objects unless absolutely necessary.
Validate before decoding or unserializing
A common real-world pattern is to check whether the file exists and whether decoding succeeded.
$path = 'cache.json';
if (!file_exists($path)) {
return [];
}
$data = json_decode(file_get_contents($path), true);
if (!is_array($data)) {
return [];
}
return $data;
This is a guard clause pattern: fail early if something is missing or invalid.
Prefer safe defaults
In production code, developers often return an empty array or regenerate the cache if the file is corrupted.
Avoid unserialize() on untrusted input
This is a major real-world rule. Serialized PHP data can be dangerous if it comes from a source you do not control, especially when objects are involved.
Benchmark in your own environment
Performance can vary by:
- PHP version
- array size
- nesting depth
- string lengths
- disk I/O
In real projects, developers benchmark with their actual data instead of relying only on general claims.
Common Mistakes
Here are common beginner mistakes and how to avoid them.
1. Forgetting true in json_decode()
Broken code:
$data = json_decode($json);
echo $data['name'];
Problem:
json_decode()returns an object by default, not an associative array.
Fix:
$data = json_decode($json, true);
echo $data['name'];
2. Assuming JSON preserves every PHP type exactly
Broken assumption:
$value = ['number_as_string' => '123'];
JSON is good for common data, but it is not a perfect PHP type container for every edge case.
Avoid this by using JSON for plain data and serialize() only when PHP-specific fidelity is truly needed.
3. Using unserialize() on untrusted data
Broken code:
$userInput = $_POST['payload'];
$data = unserialize($userInput);
Problem:
- This can create security risks.
Fix:
- Only unserialize data from trusted sources.
- Prefer JSON for external or user-controlled input.
4. Ignoring encoding/decoding failures
Broken code:
$data = json_decode(file_get_contents('cache.json'), true);
Problem:
- If the file is invalid or empty, this may return
null.
Fix:
$data = json_decode(file_get_contents('cache.json'), true);
if (json_last_error() !== JSON_ERROR_NONE) {
$data = [];
}
5. Comparing only decode speed
A common mistake is focusing only on json_decode() vs unserialize() speed.
You should consider:
- encode speed
- decode speed
- file size
- readability
- type support
- security
- future portability
6. Storing objects when arrays are enough
If your cache is just structured data, arrays are simpler and safer than serialized objects.
Prefer plain arrays unless object behavior is truly needed.
Comparisons
Here is a practical comparison.
| Feature | JSON | serialize() |
|---|---|---|
| Readable by humans | Usually yes | Usually no |
| Works outside PHP | Yes | No |
| Good for JavaScript | Yes | No |
| Preserves PHP-specific types exactly | No | Yes |
| Supports PHP objects | Limited / not as PHP objects | Yes |
| Safer for external data | Usually yes | No, be careful with unserialize() |
| Best for APIs | Yes | No |
| Best for PHP-only internal structures | Sometimes | Often yes |
| Easy to debug in files | Yes | Harder |
JSON vs serialize() for caching
| Situation | Better choice |
|---|---|
| Cache contains plain arrays and scalars | JSON |
| Cache may be used by JavaScript | JSON |
| Cache must preserve PHP objects | serialize() |
| Data may come from untrusted sources | JSON |
| Human inspection matters | JSON |
| PHP-specific type fidelity matters most | serialize() |
A useful rule of thumb
If your cached data is just nested associative arrays, strings, numbers, booleans, and null, JSON is often the cleaner choice.
If you need PHP-only behavior and exact type preservation, serialize() is the stronger PHP-native option.
Cheat Sheet
Quick decision guide
- Use JSON for plain array data, portability, and readability.
- Use
serialize()for PHP-only storage when exact PHP types matter. - Avoid
unserialize()on untrusted input.
Core syntax
// JSON
$string = json_encode($data);
$data = json_decode($string, true);
// PHP serialization
$string = serialize($data);
$data = unserialize($string);
JSON tips
$json = json_encode($data, JSON_PRETTY_PRINT);
$array = json_decode($json, true);
json_decode($json)returns an object by default.json_decode($json, true)returns an associative array.
Error checking
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$data = [];
}
Best fit for JSON
- cache files with plain data
- frontend/backend shared data
- API payloads
- human-readable storage
Best fit for serialize()
- PHP-only storage
- exact type preservation
- object storage when necessary
Pitfalls
- JSON does not preserve every PHP-specific structure.
unserialize()can be risky with untrusted data.- Performance depends on real data and environment.
- Disk I/O can matter more than encode/decode speed.
FAQ
Should I use JSON or serialize() for PHP cache files?
If the cache contains plain arrays and scalar values, JSON is often the better choice because it is readable, portable, and easy to reuse in JavaScript. If you need exact PHP type preservation, use serialize().
Is json_decode() faster than unserialize()?
Sometimes, but it depends on PHP version, data shape, and environment. You should benchmark with your actual data instead of assuming one is always faster.
Is JSON safer than unserialize() in PHP?
Yes, generally. unserialize() can be dangerous with untrusted input, especially when objects are involved. JSON is usually the safer option for external data.
Does JSON preserve associative arrays in PHP?
Yes, for normal use cases. Use json_decode($json, true) to get an associative array back.
Can JSON store PHP objects?
Not in the same PHP-specific way as serialize(). JSON stores data, not full PHP object state and behavior.
Why is JSON often easier to debug?
Because the file contents are usually readable by humans, especially with JSON_PRETTY_PRINT.
If I only use the data in PHP, should I always use serialize()?
Not always. If the data is simple and readability matters, JSON may still be a better choice.
What matters more than raw encode/decode speed?
Type fidelity, safety, file size, maintainability, portability, and how the data is actually used in your application.
Mini Project
Description
Build a simple file-based cache system in PHP that stores product data and reloads it later. This project demonstrates how to save nested arrays to disk using JSON, validate cache contents, and safely fall back when the cache file is missing or invalid.
Goal
Create a reusable PHP script that writes an associative array to a cache file as JSON and reads it back as a PHP array.
Requirements
- Create a nested associative array with at least two products.
- Save the array to a flat file using JSON.
- Load the cache file back into PHP as an associative array.
- Handle the case where the cache file is missing or invalid.
- Print one value from the loaded cache to prove it works.
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.