For people who searched for php multidimensional array get values and actually want to solve problem comes from getting one column value from a 2 dimensinal array (like me!), here's a much elegant way than using foreach, which is array_column
For example, if I only want to get hotel_name from the below array, and form to another array:
$hotels = [
[
'hotel_name' => 'Hotel A',
'info' => 'Hotel A Info',
],
[
'hotel_name' => 'Hotel B',
'info' => 'Hotel B Info',
]
];
I can do this using array_column:
$hotel_name = array_column($hotels, 'hotel_name');
print_r($hotel_name); // Which will give me ['Hotel A', 'Hotel B']
For the actual answer for this question, it can also be beautified by array_column and call_user_func_array('array_merge', $twoDimensionalArray);
Let's make the data in PHP:
$hotels = [
[
'hotel_name' => 'Hotel A',
'info' => 'Hotel A Info',
'rooms' => [
[
'room_name' => 'Luxury Room',
'bed' => 2,
'boards' => [
'board_id' => 1,
'price' => 200
]
],
[
'room_name' => 'Non Luxy Room',
'bed' => 4,
'boards' => [
'board_id' => 2,
'price' => 150
]
],
]
],
[
'hotel_name' => 'Hotel B',
'info' => 'Hotel B Info',
'rooms' => [
[
'room_name' => 'Luxury Room',
'bed' => 2,
'boards' => [
'board_id' => 3,
'price' => 900
]
],
[
'room_name' => 'Non Luxy Room',
'bed' => 4,
'boards' => [
'board_id' => 4,
'price' => 300
]
],
]
]
];
And here's the calculation:
$rooms = array_column($hotels, 'rooms');
$rooms = call_user_func_array('array_merge', $rooms);
$boards = array_column($rooms, 'boards');
foreach($boards as $board){
$board_id = $board['board_id'];
$price = $board['price'];
echo "Board ID is: ".$board_id." and price is: ".$price . "<br/>";
}
Which will give you the following result:
Board ID is: 1 and price is: 200
Board ID is: 2 and price is: 150
Board ID is: 3 and price is: 900
Board ID is: 4 and price is: 300
Answer from Ng Sek Long on Stack OverflowFor people who searched for php multidimensional array get values and actually want to solve problem comes from getting one column value from a 2 dimensinal array (like me!), here's a much elegant way than using foreach, which is array_column
For example, if I only want to get hotel_name from the below array, and form to another array:
$hotels = [
[
'hotel_name' => 'Hotel A',
'info' => 'Hotel A Info',
],
[
'hotel_name' => 'Hotel B',
'info' => 'Hotel B Info',
]
];
I can do this using array_column:
$hotel_name = array_column($hotels, 'hotel_name');
print_r($hotel_name); // Which will give me ['Hotel A', 'Hotel B']
For the actual answer for this question, it can also be beautified by array_column and call_user_func_array('array_merge', $twoDimensionalArray);
Let's make the data in PHP:
$hotels = [
[
'hotel_name' => 'Hotel A',
'info' => 'Hotel A Info',
'rooms' => [
[
'room_name' => 'Luxury Room',
'bed' => 2,
'boards' => [
'board_id' => 1,
'price' => 200
]
],
[
'room_name' => 'Non Luxy Room',
'bed' => 4,
'boards' => [
'board_id' => 2,
'price' => 150
]
],
]
],
[
'hotel_name' => 'Hotel B',
'info' => 'Hotel B Info',
'rooms' => [
[
'room_name' => 'Luxury Room',
'bed' => 2,
'boards' => [
'board_id' => 3,
'price' => 900
]
],
[
'room_name' => 'Non Luxy Room',
'bed' => 4,
'boards' => [
'board_id' => 4,
'price' => 300
]
],
]
]
];
And here's the calculation:
$rooms = array_column($hotels, 'rooms');
$rooms = call_user_func_array('array_merge', $rooms);
$boards = array_column($rooms, 'boards');
foreach($boards as $board){
$board_id = $board['board_id'];
$price = $board['price'];
echo "Board ID is: ".$board_id." and price is: ".$price . "<br/>";
}
Which will give you the following result:
Board ID is: 1 and price is: 200
Board ID is: 2 and price is: 150
Board ID is: 3 and price is: 900
Board ID is: 4 and price is: 300
This is the way to iterate on this array:
foreach($hotels as $row) {
foreach($row['rooms'] as $k) {
echo $k['boards']['board_id'];
echo $k['boards']['price'];
}
}
You want to iterate on the hotels and the rooms (the ones with numeric indexes), because those seem to be the "collections" in this case. The other arrays only hold and group properties.
TL;DR
$result = call_user_func_array('array_merge', $array);
Credit: How to "flatten" a multi-dimensional array to simple one in PHP?
In your use case, you should use it like this:
<?php
$array = [
'car' => [
'BMW' => 'blue',
'toyota' => 'gray'
],
'animal' => [
'cat' => 'orange',
'horse' => 'white'
]
];
$result = call_user_func_array('array_merge', $array);
$result = array_values($result);
//$result = ['blue', 'gray', 'orange', 'white']
Old but as far i see not really a "working on all cases" function posted.
So here is the common classic recursively function:
function getArrayValuesRecursively(array $array)
{
$values = [];
foreach ($array as $value) {
if (is_array($value)) {
$values = array_merge($values,
getArrayValuesRecursively($value));
} else {
$values[] = $value;
}
}
return $values;
}
Example array:
$array = [
'car' => [
'BMW' => 'blue',
'toyota' => 'gray'
],
'animal' => [
'cat' => 'orange',
'horse' => 'white'
],
'foo' => [
'bar',
'baz' => [
1,
2 => [
2.1,
'deep' => [
'red'
],
2.2,
],
3,
]
],
];
Call:
echo var_export(getArrayValuesRecursively($array), true) . PHP_EOL;
Result:
// array(
// 0 => 'blue',
// 1 => 'gray',
// 2 => 'orange',
// 3 => 'white',
// 4 => 'bar',
// 5 => 1,
// 6 => 2.1,
// 7 => 'red',
// 8 => 2.2,
// 9 => 3,
// )
Assuming $array contains your data, the following code will do it.
$result = array();
foreach($array as $a){
foreach($a as $l){
list($ab, $it) = explode(",", $l, 2);
$ab = substr($ab, strlen("Ability:"));
$it = substr($it, strlen("Itemname:"));
$result[] = array(
'Ability' => $ab,
'Itemname' => $it
);
}
}
Try this, it works for me. I match the desired strings with a regex
<?php
$arr[][] = 'Ability:B,Itemname:Session #3: Tues June 28th - Fri July 8th (9-2:00PM)#1 only: 2pm';
$arr[][] = 'Ability:B+,Itemname:Session #3: Tues June 28th - Fri July 8th (9-2:00PM)#1 only: 2pm';
$arr[][] = 'Ability:B++,Itemname:Session #3: Tues June 28th - Fri July 8th (9-2:00PM)#1 only: 2pm';
$pattern = '/Ability:(.*),Itemname:(.*)$/m';
for ($i = 0; $i < count($arr); $i++) {
for ($j = 0; $j < count($arr[$i]); $j++) {
preg_match_all($pattern, $arr[$i][$j], $matchResult);
echo 'Original string: '. $arr[$i][$j].'<br>';
echo 'Ability: '.$matchResult[1][0].'<br>';
echo 'Itemname: '.$matchResult[2][0].'<br>';
echo '<br><hr><br>';
}
}
?>
The thing that is probably tripping you up is that suitability is an array of arrays not just an array so in an example where you want to get the species_name property of the first second top level element you would use something like
$array[1]["suitability"][0]["species_name"];
It's worth noting that your first array does not contain a "suitability" value so that would not be able to be accessed. In a foreach loop you could use a construct similar to this:
foreach($array as $value){
if (isset($value["suitability"])){
echo $value["suitability"][0]["species_name"];
}
}
For getting nested element value from multidimensional array (with optional fallback to default value) you can use get method from this array library:
Arr::get($array, "$index1.suitability.$index2.species_name")
// Or using array of keys
Arr::get($array, [$index1, 'suitability', $index2, 'species_name'])
You can use array_column like as
echo array_column($myoptions,1,0)['3 days'];//72
Demo
It's not likely that the array you showed us is really what you're after.
PHP's arrays are so-called associative arrays, meaning that you can use anything to index them, not just numbers:
$myoptions = array(
"1 day" => 24,
"2 days" => 48,
"3 days" => 72,
);
So,
echo $myoptions["3 days"]
or
$days = "3 days";
echo $myoptions[$days];
would directly return what you need. Of course, in real life applications, you would need to make sure that your input matches one of the indexes of the array.
Actually, but this is not something we can decide without knowing what you try to accomplish but in most cases you really need the opposite:
$myoptions = array(
24 => "1 day",
48 => "2 days",
72 => "3 days",
);
That is, your program stores and uses the numeric part, the number of hours internally, and whenever you need to display the option it represents to the user, you do the conversion to the human readable format, not the other way around.
I have created a function that you can more or less give it any product and it will return the key and value from the array
<?php
class Products
{
public function products_list()
{
$customerType = 'national';
$productType = 'phones';
$phoneType = 'Apple';
$productsArr[] = array(
'customerType' => 'national', 'productType' => array(
'phones' => array(
'Apple' => 'iPhone',
'Sony' => 'Xperia',
'Samsung' => 'Galaxy'
),
'cases' => array(
'leather' => 'black',
'plastic' => 'red',
),
),
'international' => array(
'phones' => array(
'BlackBerry' => 'One',
'Google' => 'Pixel',
'Samsung' => 'Note'
),
'cases' => array(
'leather' => 'blue',
'plastic' => 'green'
),
)
);
echo $this->get_value($phoneType, $productsArr) .'<br>';
echo $this->get_value($customerType, $productsArr) .'<br>';
echo $this->get_value($productType, $productsArr) .'<br>';
}
function get_value($product, array $products)
{
$iterator = new RecursiveIteratorIterator(new RecursiveArrayIterator($products), RecursiveIteratorIterator::CHILD_FIRST);
foreach ($iterator as $key => $value) {
if (is_string($value) && ($key == $product)) {
return 'key ->' . $key .' value ->'.$value;
}
}
return "";
}
}
$phone_products = new Products();
$phone_products->products_list();
To use it within the class just call
$this->get_value($phoneType, $productsArr);
from without the class call
$phone_products = new Products();
echo ($phone_products->get_value($phoneType, $productsArr));
//output: key ->Apple value ->iPhone
NB: $phoneType, $productsArr will either be defined the methods they are being used in or passed from other methods or define global variables within the class.
If you want single entry:
echo $productsArr[0]['productType']['phones']['Apple']."<br />";
If there are multiple data, you can use foreach:
foreach ($productsArr as $prod){
echo $prod['productType']['phones']['Apple']."<br />";
}