I want to search values in array by key, but I am having trouble when those keys value are an array, I have the following code:
$key_to_search = "sizes";
$result = [];
$array = [
"color" => "red",
"subcolor" => "green",
"sizes" => [
"depth_mm" => 40.5,
"width_mm" => 300,
"height_mm" => 2
],
"launch_date" => "2023-01-01"
];
$iterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator(
$array
)
);
foreach($iterator as $key=>$value)
{
if($key_to_search==$key && $value!=='')
{
$result[] = $value;
}
}
var_dump($result);
The key to search is on $key_to_search
variable, if I use other one which does not have an array as value its finding correctly the values, but when the value is an array it just ignored.
Expected result for search of "sizes" would be:
[
"depth_mm" => 40.5,
"width_mm" => 300,
"height_mm" => 2
]
There’s a working example using the classic way without RecursiveIteratorIterator
:
public function searchPropertyValuesByKey($key_to_search, $array_to_search = null) {
if($array_to_search == null) {
$array_to_search = [
"color" => "red",
"subcolor" => "green",
"sizes" => [
"depth_mm" => 40.5,
"width_mm" => 300,
"height_mm" => 2
],
"launch_date" => "2023-01-01"
];
}
$result = [];
foreach($array_to_search as $key=>$value)
{
if($key_to_search==$key && $value!=='')
{
$result[] = $value;
}
if(is_array($value)){
$callback_result = $this->searchPropertyValuesByKey($key_to_search, $value);
if($callback_result !== null) {
$result[] = $callback_result;
}
}
}
if(count($result) == 1)
return $result[0];
else if(count($result) > 1)
throw new Exception("Property '".$key_to_search."' is found multiple times! (".count($result).") ".json_encode($result).", in product_id: ".$this->id." >> ".json_encode($this->propierties)."");
else
return null;
}
2
Answers
If you change the definition of
$iterator
to the following, it works as you’ve stated:I don’t believe that the
RecursiveIteratorIterator
is required.The constructor of RecursiveIteratorIterator has three parameters: a
Traversable
(which you correctly specified), a$mode
, which defaults toRecursiveIteratorIterator::LEAVES_ONLY
(that’s the problem) and$flags
. So, in order to consider non-leaf items, you will need to specify a different value for your second parameter. I have tried your example with RecursiveIteratorIterator::SELF_FIRST and it worked.Code:
Result: