In a normal array you can select this way
$key='example';
echo $array[$key];
How about in a multidimensional?
$keys='example[secondDimension][thirdDimension]';
echo $array[$keys];
What's the proper way to go about this?
In a normal array you can select this way
$key='example';
echo $array[$key];
How about in a multidimensional?
$keys='example[secondDimension][thirdDimension]';
echo $array[$keys];
What's the proper way to go about this?
i think this solution is good.
note that you have to wrap all keys with "[" and "]".
$array = array(
'example' => array(
'secondDimension' => array(
'thirdDimension' => 'Hello from 3rd dimension',
)
),
);
function array_get_value_from_plain_keys($array, $keys)
{
$result;
$keys = str_replace(array('[', ']'), array("['", "']"), $keys); // wrapping with "'" (single qoutes)
eval('$result = $array' . $keys . ';');
return $result;
}
$keys = '[example][secondDimension][thirdDimension]'; // wrap 1st key with "[" and "]"
echo array_get_value_from_plain_keys($array, $keys);
Learn more about eval() function
if you also want to check if the value is defined or not then you can use this function
function array_check_is_value_set_from_plain_keys($array, $keys)
{
$result;
$keys = str_replace(array('[', ']'), array("['", "']"), $keys); // wrapping with "'" (single qoutes)
eval('$result = isset($array' . $keys . ');');
return $result;
}
Giving a better name to that function will be appreciated ^^
Here is a solution without using eval:
$array = [
'example' => [
'secondDimension' => [
'thirdDimension' => 'Hello from 3rd dimension',
],
],
];
$keys = '[example][secondDimension][thirdDimension]';
function get_array_value( $array, $keys ) {
$keys = explode( '][', trim( $keys, '[]' ) );
return get_recursive_array_value( $array, $keys );
}
function get_recursive_array_value( $array, $keys ) {
if ( ! isset( $array[ $keys[0] ] ) ) {
return null;
};
$res = $array[ $keys[0] ];
if ( count( $keys ) > 1 ) {
array_shift( $keys );
return get_recursive_array_value( $res, $keys );
} else {
return $res;
}
}
echo get_array_value( $array, $keys );
Want you to use the $b array to follow the nested keys of the $a array and get the value in $c ?
<?php
$a = [ 'key_1' => [ 'key_2' => [ 'key_3' => 'value', ], ], ] ;
$b = ['key_1', 'key_2', 'key_3', ] ;
if ($b)
{
$c = $a ; // $a is not copied (copy-on-write)
foreach($b as $k)
if (isset($c[$k]))
$c = $c[$k] ;
else
{
unset($c);
break;
}
var_dump($c);
}
/*
output :
string(5) "value"
*/
or do you want to generate the $b array for an arbitrary formed string and get $c as a reference ?
<?php
$a = [ 'key_1' => [ 'key_2' => [ 'key_3' => 'value', ], ], ] ;
$b = '[key_1][key_2][key_3]';
if ($b !== '')
{
$b = explode('][', trim($b, '[]'));
$c = &$a ;
foreach($b as $k)
if (isset($c[$k]))
$c = &$c[$k] ;
else
{
unset($c);
break;
}
}
var_dump($c);
$c = 'new val' ;
unset($c);
var_dump($a['key_1']['key_2']['key_3']);
/*
output :
string(5) "value"
string(7) "new val"
*/
Simplified example using eval() I wrote to extract phone numbers from an array of Shopify customer data:
// this is weird but whatever
$arrayPaths = array(
'[\'phone\']',
'[\'addresses\'][0][\'phone\']',
'[\'addresses\'][1][\'phone\']'
);
foreach ($arrayPaths as $path) {
// hack to store/access multidimentional array keys as array, sets
// a variable named $phoneNumber
$code = '$phoneNumber = $dataArray' . $path . ';';
eval($code);
var_dump($phoneNumber);
}
DISCLAIMER FOR THE EVAL() POLICE: don't use eval() if there is any chance of code injection via malicious user input. I'm running this as part of a one-time data migration script on a VM on my local computer, the only network interactions are calls out to the Shopify API.
The most elegant way to solve this problem, is to make a recursive function that gets the value. Here is my suggestion:
/**
* Get value of given path of keys for a given multidimentional array in a recursive way.
* @param array $array A multidimentional array
* @param array $key A path of keys, example [1, 'name']
* @param mixed $default What to return if path of keys does not exist in given array
* @return mixed The found value, or the default value (can be any data type)
*/
function recursiveGetValue(array $array, array $key, $default=null) {
$currentKey = current($key);
if (!array_key_exists($currentKey, $array)) {
return $default;
}
else if (count($key)==1) {
return $array[$currentKey];
}
else {
$restArray = $array[$currentKey];
$restKey = array_slice($key, 1);
return recursiveGetValue($restArray, $restKey, $default);
}
}
$array = [
'one' =>['name'=>'Per', 'age'=>10],
'two' =>['name'=>'Pål', 'age'=>20],
'three'=>['name'=>'Jan', 'age'=>15],
];
echo(recursiveGetValue($array, ['two', 'age']));
You have to use a separate variable for each dimension of the array. A common pattern you see with multidimensional arrays where you need to do something with the 2nd dimension is something like this:
$pets = [
'dog' => ['Jack', 'Fido', 'Woofie'],
'cat' => ['Muggles', 'Snowball', 'Kitty'],
];
// Loop through keys in first dimension
foreach ($pets as $type => $names) {
foreach ($names as $index => $name) {
// And do something with second dimension using the variable
// you've gained access to in the foreach
$pets[$type][$index] = strtoupper($name);
}
}