Question

JSON vs serialize() in PHP: Choosing How to Store Arrays

phpperformancearraysjsonserialization

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."
Take Quiz

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 true is 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.

Take Quiz

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.

FeatureJSONserialize()
Readable by humansUsually yesUsually no
Works outside PHPYesNo
Good for JavaScriptYesNo
Preserves PHP-specific types exactlyNoYes
Supports PHP objectsLimited / not as PHP objectsYes
Safer for external dataUsually yesNo, be careful with unserialize()
Best for APIsYesNo
Best for PHP-only internal structuresSometimesOften yes
Easy to debug in filesYesHarder

JSON vs serialize() for caching

SituationBetter choice
Cache contains plain arrays and scalarsJSON
Cache may be used by JavaScriptJSON
Cache must preserve PHP objectsserialize()
Data may come from untrusted sourcesJSON
Human inspection mattersJSON
PHP-specific type fidelity matters mostserialize()

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.

Take Quiz

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.

Take Quiz

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.
Take Quiz

Keep learning

Related questions

View more