DEV Community

Cover image for How to Flatten an array in PHP (four methods)
Reza Lavarian
Reza Lavarian

Posted on • Originally published at decodingweb.dev

11

How to Flatten an array in PHP (four methods)

Update: This post was originally published on my blog decodingweb.dev, where you can read the latest version for a 💯 user experience. ~reza

There’s no built-in function in PHP to flatten a multi-dimensional array, but it’s not a difficult thing to do in PHP. In fact, it’s quite easy.

We usually flatten arrays of data fetched from a database or an API. In real-world scenarios, we’d usually want to take a few fields off each row for displaying in our views.

How to flatten an array in PHP

In this tutorial, we’ll explore four ways of flattening arrays (two-dimensional and multi-dimensional) in PHP:

  1. Flatten two-dimensional arrays in PHP (when keys don’t matter)
  2. Pluck a list of the given key/value pairs from a PHP array
  3. Flatten a PHP array recursively I
  4. Flatten a PHP array recursively II

Flatten two-dimensional arrays in PHP

If you have a two-dimensional array, you can flatten it by unpacking the array and passing it as an argument to the array_merge() function.

<?php

// Each array has two Apple devices in each category (iPads, phones, and laptops)
$products = [
     ['iPad Air', 'iPad pro'],
     ['iPhone 13', 'iPhone 13 mini'],
     ['MacBook Air', 'MacBook Pro']
];

// Flatten the array
$result = array_merge(...$products);
print_r($result);
Enter fullscreen mode Exit fullscreen mode

And this will be the output:

Array
(
  [0] => iPad Air
  [1] => iPad pro
  [2] => iPhone 13
  [3] => iPhone 13 mini
  [4] => MacBook Air
  [5] => MacBook Pro
)
Enter fullscreen mode Exit fullscreen mode

In PHP versions before 8.1, if the $products array has string keys, you must extract the values with array_values() first:

<?php
// ...

$result = array_merge(...array_values($products));
Enter fullscreen mode Exit fullscreen mode

For PHP versions before 7.4: if the $products array is empty, the array_merge() would be invoked without arguments. This will raise an error. To avoid the error, add an empty array [] to the array_merge() arguments:

<?php
// ...

$results = array_merge([], ...$products);
Enter fullscreen mode Exit fullscreen mode

Argument unpacking has been available since PHP 5.6+.

Note: Since PHP 8.1, unpacking the outer array with string keys (associative arrays) is possible without using array_values().

Pluck a list of the given key/value pairs from the array

If you have an array of arrays (two-dimensional), and you want to take a specific key (e.g., name) off each array and create an array of names, you can use array_column().

Imagine you've fetched a list of customers from the database, and you have the results as a two-dimensional array. Now you want to create an array containing the name of each person.

Here's how it's done:

<?php

// Array representing a possible record set returned from a database
$records = array(
    array(
        'id' => 2135,
        'first_name' => 'John',
        'last_name' => 'Doe',
    ),
    array(
        'id' => 3245,
        'first_name' => 'Sally',
        'last_name' => 'Smith',
    ),
    array(
        'id' => 5342,
        'first_name' => 'Jane',
        'last_name' => 'Jones',
    ),
    array(
        'id' => 5623,
        'first_name' => 'Peter',
        'last_name' => 'Doe',
    )
);

$first_names = array_column($records, 'first_name');
print_r($first_names);
Enter fullscreen mode Exit fullscreen mode

And the output will be:

Array
(
    [0] => John
    [1] => Sally
    [2] => Jane
    [3] => Peter
)
Enter fullscreen mode Exit fullscreen mode

Flatten a PHP array recursively I

If your array has more than two dimensions (multi-dimensional), we need to take a recursive approach. The starter method is array_walk_recursive().

Here's how it's done:

<?php

$data = [
    'name' => 'James',
    'contact' => [
        'phone' => [
            'work_phone' => '000',
            'home_phone' => '111'
        ],
        'emails' => 'james@test',
    ]
];

$results = [];
array_walk_recursive($data, function ($item, $key) use (&$results){$results[$key] = $item;});

print_r($results);
Enter fullscreen mode Exit fullscreen mode

This function takes an array and iterates over every element recursively. On each iteration, the provided callback is executed.

The callback accepts two arguments, $item and $key.

Since the $results array is declared in the global scope, we import it into the callback (via use()) as a reference (&$results) - so that we can modify it.

And this will be the output:

Array
(
  [name] => James
  [work_phone] => 000
  [home_phone] => 111
  [emails] => james@test
)
Enter fullscreen mode Exit fullscreen mode

Please note if there are elements with the same key, the former will be overridden by the latter.

Flatten a PHP array recursively II

If you need more control over the flattening process, it's easy to create a recursive function yourself.

Let's see how:

<?php

$data = [
    'name' => 'James',
    'contact' => [
        'phone' => [
            'work_phone' => '000',
            'home_phone' => '111'
        ],
        'emails' => 'james@test',
    ]
];

function flatten($array) {
    $results = [];

    foreach ($array as $key => $value) {
        if (is_array($value) && ! empty($value)) {
            $results = array_merge($results, flatten($value));
        } else {
            $results[$key] = $value;
        }
    }

    return $results;
}


$results = [];
$results = flatten($data);

print_r($results);
Enter fullscreen mode Exit fullscreen mode

In the above code, we took a recursive approach. The flatten() function takes a PHP array and iterates over all the elements by a foreach().

On each iteration, we check if the current value is an array and not empty.

If it's a non-empty array, we call the flatten() function with the current element as its argument.

If the current element isn't an array, we push it to $results.

Basically, the function keeps calling itself until it has gone over all non-array elements (down to the deepest level), and has pushed them to the $results array.

And this will output:

Array
(
  [name] => James
  [work_phone] => 000
  [home_phone] => 111
  [emails] => james@test
)
Enter fullscreen mode Exit fullscreen mode

Wrapping up

We usually flatten arrays fetched from a data source, like a database or an API. Taking a recursive approach is usually the most natural way to flatten arrays. However, array_walk_recursive() and array_column() work quite well in specific scenarios.

I hope you found this guide helpful.

Thanks for reading.


❤️ You might like

Neon image

Serverless Postgres in 300ms (!)

10 free databases with autoscaling, scale-to-zero, and read replicas. Start building without infrastructure headaches. No credit card needed.

Try for Free →

Top comments (1)

Collapse
 
web-medias profile image
Web-Medias

Yes reza! It is so cool the recursive method (II) and in other words, it can be used properly to build a full flow of items for a select element with <option> and its <optgroup>...
I ve change a litle bit the way of item is setted in the else case :

Flatten a PHP array recursively II to create a grouped options

<?php

$data = [
    'guid-1' => 'Custom title 1',
    'guid-2' => 'Custom title 2',

    'Posts' => [
        'guid-3' => 'Custom title 3',
        'guid-4' => 'Custom title 4'
    ],
    'Pages' => [
        'guid-5' => 'Custom title 5',
        'guid-6' => 'Custom title 6'
    ],

];


function flatten($array) {
    $results = [];

    foreach ($array as $key => $value) {
        if (is_array($value) && ! empty($value)) {
            $results = array_merge($results, ['<optgroup label="'.$key.'" aria-label="'.$key.'">'], flatten($value), ['</optgroup>'] );
        } else {
            array_push( $results,  '<option value="'.$key.'" label="'. htmlentities($value, ENT_QUOTES) .'">'. $value .'</option>' );
        }
    }

    return $results;
}


$results = [];
$results = flatten($data);

echo "<pre><code>";
print_r($results);
echo "</code></pre>";
Enter fullscreen mode Exit fullscreen mode

Image of Stellar post

Check out Episode 1: How a Hackathon Project Became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay