✋ 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:
- Flatten two-dimensional arrays in PHP (when keys don’t matter)
- Pluck a list of the given key/value pairs from a PHP array
- Flatten a PHP array recursively I
- 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);
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
)
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));
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);
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);
And the output will be:
Array
(
[0] => John
[1] => Sally
[2] => Jane
[3] => Peter
)
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);
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
)
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);
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
)
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
- PHP double question marks (Null coalescing operator) explained
- How to remove the last character from a string in PHP
- How to become a web developer when you have no degree
- Do you need to know CMS as a back-end developer?
- How back-end web frameworks work?
- Your master sword: a programming language
- What do back-end developers do?
Top comments (1)
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