Try it yourself with our free Json Formatter tool — runs entirely in your browser, no signup needed.

How to Flatten nested JSON in PHP

How to Flatten Nested JSON in PHP

Introduction

Working with JSON data is a common task in web development, and often, this data comes in a nested format. However, there are situations where it's more convenient to work with a flat structure. Flattening nested JSON can be a bit tricky, but with the right approach, it can be accomplished efficiently. In this article, we'll explore how to flatten nested JSON in PHP, covering a quick example, a step-by-step breakdown, handling edge cases, common mistakes, performance tips, and frequently asked questions.

Quick Example

Here's a minimal example that flattens a nested JSON object:

<?php

function flatten_json($json) {
    $result = array();
    foreach ($json as $key => $value) {
        if (is_array($value)) {
            $flat = flatten_json($value);
            foreach ($flat as $subkey => $subvalue) {
                $result[$key . '_' . $subkey] = $subvalue;
            }
        } else {
            $result[$key] = $value;
        }
    }
    return $result;
}

$json = '{
    "name": "John",
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "CA",
        "zip": "12345"
    }
}';

$json_array = json_decode($json, true);
$flattened = flatten_json($json_array);

print_r($flattened);

This code defines a recursive function flatten_json that takes a JSON object as input and returns a flattened array.

Step-by-Step Breakdown

Let's walk through the flatten_json function:

  1. We initialize an empty array $result to store the flattened data.
  2. We loop through each key-value pair in the input JSON object using foreach.
  3. If the value is an array (i.e., a nested object), we recursively call flatten_json on that value and store the result in $flat.
  4. We then loop through each key-value pair in $flat and add the values to $result with the corresponding keys prefixed with the parent key and an underscore.
  5. If the value is not an array, we simply add it to $result with its original key.
  6. Finally, we return the flattened $result array.

Handling Edge Cases

Empty/Null Input

If the input JSON is empty or null, the function will return an empty array:

$json = '';
$json_array = json_decode($json, true);
$flattened = flatten_json($json_array);
print_r($flattened); // Output: array()

Invalid Input

If the input is not a valid JSON string, json_decode will return null, and the function will throw an error:

$json = ' invalid json ';
$json_array = json_decode($json, true);
$flattened = flatten_json($json_array); // Error: Argument 1 passed to flatten_json() must be of the type array, null given

To handle this case, you can add a simple check before calling flatten_json:

if ($json_array === null) {
    // Handle invalid input
}

Large Input

For very large JSON inputs, the recursive approach may cause a stack overflow. In such cases, you can use an iterative approach using a queue:

function flatten_json_iterative($json) {
    $result = array();
    $queue = array($json);

    while (!empty($queue)) {
        $item = array_shift($queue);
        foreach ($item as $key => $value) {
            if (is_array($value)) {
                $queue[] = $value;
            } else {
                $result[$key] = $value;
            }
        }
    }
    return $result;
}

Unicode/Special Characters

The function handles Unicode and special characters correctly, as PHP's json_decode function supports them:

$json = '{
    "name": "Jöhn",
    "address": {
        "street": "123 Main St",
        "city": "Anytown",
        "state": "CA",
        "zip": "12345"
    }
}';
$json_array = json_decode($json, true);
$flattened = flatten_json($json_array);
print_r($flattened);

Common Mistakes

1. Not Handling Null Values

Incorrect code:

function flatten_json($json) {
    // ...
    if (is_array($value)) {
        // ...
    } else {
        $result[$key] = $value; // What if $value is null?
    }
    // ...
}

Corrected code:

function flatten_json($json) {
    // ...
    if (is_array($value)) {
        // ...
    } else {
        if ($value !== null) {
            $result[$key] = $value;
        }
    }
    // ...
}

2. Not Handling Non-String Keys

Incorrect code:

function flatten_json($json) {
    // ...
    foreach ($json as $key => $value) {
        // ...
        $result[$key . '_' . $subkey] = $subvalue;
    }
    // ...
}

Corrected code:

function flatten_json($json) {
    // ...
    foreach ($json as $key => $value) {
        // ...
        $result[(string) $key . '_' . (string) $subkey] = $subvalue;
    }
    // ...
}

3. Not Handling Deeply Nested Objects

Incorrect code:

function flatten_json($json) {
    // ...
    if (is_array($value)) {
        $flat = flatten_json($value);
        foreach ($flat as $subkey => $subvalue) {
            $result[$key . '_' . $subkey] = $subvalue;
        }
    }
    // ...
}

Corrected code:

function flatten_json($json) {
    // ...
    if (is_array($value)) {
        $flat = flatten_json($value);
        foreach ($flat as $subkey => $subvalue) {
            $result[$key . '_' . $subkey] = $subvalue;
        }
    } else if (is_object($value)) {
        $flat = flatten_json(get_object_vars($value));
        foreach ($flat as $subkey => $subvalue) {
            $result[$key . '_' . $subkey] = $subvalue;
        }
    }
    // ...
}

Performance Tips

  1. Use Iterative Approach for Large Inputs: As mentioned earlier, for very large JSON inputs, an iterative approach using a queue can help prevent stack overflows.
  2. Use json_decode with the JSON_OBJECT_AS_ARRAY Flag: When decoding JSON, use the JSON_OBJECT_AS_ARRAY flag to ensure that objects are converted to arrays, which can improve performance.
$json_array = json_decode($json, true, 512, JSON_OBJECT_AS_ARRAY);
  1. Avoid Unnecessary Function Calls: Minimize the number of function calls by using a single loop to process the JSON data.

FAQ

Q: How does the flatten_json function handle nested arrays?

A: The function recursively calls itself for each nested array, flattening the data into a single-level array.

Q: What happens if the input JSON is invalid?

A: The json_decode function will return null, and the flatten_json function will throw an error.

Q: Can I use this function with JSON objects that have deeply nested structures?

A: Yes, the function can handle deeply nested objects by recursively calling itself for each nested object.

Q: How can I improve the performance of the flatten_json function for large inputs?

A: Use an iterative approach using a queue, and consider using the JSON_OBJECT_AS_ARRAY flag when decoding JSON.

Q: Are there any security concerns when using this function?

A: As with any function that processes user input, ensure that the input JSON data is validated and sanitized to prevent potential security vulnerabilities.

AI agent tools available. The CodeTidy MCP Server gives Claude, Cursor, and other AI agents access to 60+ developer tools. One command: npx @codetidy/mcp