A number of problems here. First and foremost you are not assigning the data returned from the recursive call to any kind of data structure. Also, you should be doing a better job of checking edge conditions. Finally, if your Doc Block says that array is returned, you need to 100% make sure you are returning an array. That is the contract you are making with the caller when they read the documentation on this method, so you should adhere to that.
The example below assumes you are just going to return a numerically indexed array of values to the initial caller. This example includes a merge of recursive results to active array, better handling around input validation, and the consistent return of a numerically-indexed array (with empty array signifying no results).
/**
* @param mixed $needle Integer or string key value used for recursive search.
* @param array $haystack Array to be searched.
*
* @throws InvalidArgumentException
*
* @return array Return numerically-indexed array with empty array if no match.
*/
public function recursiveArraySearch($needle, array $haystack)
{
// validate that we have a proper needle passed
if(!is_int($needle) && !is_string($needle)) {
throw new InvalidArgumentException(
'Invalid search needle type passed as argument. ' .
"Integer or string value expected. Value passed:\n" .
var_export($needle, true)
);
}
$array = [];
foreach ($haystack as $key => $value) {
// recursively search if $value is non-empty array
if(is_array($value) && !empty($value)) {
array_merge($array, $this->recursiveArraySearch($needle, $value));
}
// otherwise, we can make exact string/integer comparison
else if ($key === $needle) {
$array[] = $value;
}
}
return $array;
}
Note here that I am assuming you are looking for all matches in the recursive structure. If you are looking for the first match, you can do something like the following, which is a breadth-first search.
/**
* @param mixed $needle Integer or string key value used for recursive search.
* @param array $haystack Array to be searched.
*
* @throws InvalidArgumentException
*
* @return mixed Return values could be mixed since we have no constraint on
* value types in haystack. Null will be returned on no match, thus
* this function cannot differentiate explicitly defined null values
* from no match.
*/
public function recursiveBreadthFirstSingleMatchArraySearch($needle, array $haystack)
{
// validate that we have a proper needle passed
if(!is_int($needle) && !is_string($needle)) {
throw new InvalidArgumentException(
'Invalid search needle type passed as argument. ' .
"Integer or string value expected. Value passed:\n" .
var_export($needle, true)
);
}
// see if there is key match at first level of array
if(array_key_exists($needle, $haystack)) {
return $haystack[$needle];
}
// iterate through haystack performing recursive search on array until match
foreach ($haystack as $key => $value) {
// recursively search if $value is non-empty array
if(is_array($value) && !empty($value)) {
$result = $this->
recursiveBreadthFirstSingleMatchArraySearch($needle, $value));
if (!is_null($result)) {
return $result;
}
}
}
return null;
}