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

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

Top comments (2)

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

Some comments may only be visible to logged-in visitors. Sign in to view all comments.