So you want to look for a value on an array where you know the path to?
Had the same thing, build me something.
Its not perfect. But it does the job.
Note: if you change it then do not return false if path not found. Because false could be a found value too.
The method:
/**
* Returns a value from given source by following the given keys.
*
* Example:
* <code>
* $array = [
* 'foo' => [
* 'bar' => [
* 'baz' => null,
* ],
* 'bar_2' => [
* 0 => [
* 'baz' => null,
* ],
* 1 => [
* 'baz' => 123,
* ],
* 2 => [
* 'baz' => 456,
* ],
* ]
* ]
* ];
* ::find($array, ['foo', 'bar_2', 1, 'baz']) // 123
* </code>
*
* @param array $source
* @param array $keys
*
* @return array|bool|mixed
*/
public function find(array $source, array $keys)
{
if (empty($keys)) {
// No keys - so actually expect the complete source to return.
return $source;
}
// Get the (next-) first key.
$keyCurrent = array_shift($keys);
if (!array_key_exists($keyCurrent, $source)) {
// Expected path to value does not exist.
throw new \InvalidArgumentException("Key '{$keyCurrent}' not found.");
}
$source = $source[$keyCurrent];
if (!empty($keys)) {
// Still got keys - need to keep looking for the value ...
if (!is_array($source)) {
// but no more array - cannot continue.
// Expected path to value does not exist. Return false.
throw new \InvalidArgumentException("No array on key '{$keyCurrent}'.");
}
// continue the search recursively.
$source = $this->find($source, $keys);
}
// No more keys to search for.
// We found the value on the given path.
return $source;
}
The test:
$array = [
'a' => ['id' => 'something at array[a][id]'],
'b' => ['id' => 'something at array[b][id]'],
'c' => [
'ca' => [
'cb' => [
'cc' => ['id' => 'something at array[c][ca][cb][cc][id]'],
],
],
],
];
$value = $this->find($array, ['c', 'ca', 'cb', 'cc', 'id']);
// something at array[c][ca][cb][cc][id]
$value = $this->find($array, ['c', 'ca', 'cb', 'cc']);
// array (
// 'id' => 'something at array[c][ca][cb][cc][id]',
// )
$value = $this->find($array, ['b', 'id']);
// something at array[b][id]
$value = $this->find($array, ['c', 'ca', 'cb', 'cc', 'does_not_exist']);
// Fatal error: Uncaught InvalidArgumentException: Key 'does_not_exist' not found. in