Q:

Recursive search return all keys where value is present

Currently stuck trying to get the last part working, wanting to get all array keys returned where the value exists.
Test data
$testArr = array(
    'id' => '249653315914',
    'title' => 'testing',
    'description' => 'testing',
    'usernames' => array('jake', 'liam', 'john'),
    'masterNames' => array('jake'),
    'data' => array(
        'aliases' => array(
            'jake'
        )
    )
);

Method
recursive_search('jake', $testArr);

function recursive_search($needle, $haystack, $child = false) {
    $values = array();
    foreach($haystack as $key => $value) {
        $current_key = $key;
        if($needle === $value OR (is_array($value) && $children = recursive_search($needle, $value, true) !== false)) {
            if($child) {
                if($needle == $value) {
                    return true;
                }
                echo "children: $child, current_key: $current_key   ";
                return $current_key;
            }
            echo "current_key: $current_key, key: $key <br>";
            $values[] = $current_key;
        }
    }
    if(!empty($values)) {
        return $values;
    }
    return false;
}

Output
current_key: usernames, key: usernames 
current_key: masterNames, key: masterNames 
children: 1, current_key: aliases current_key: data, key: data 
array (size=3)
  0 => string 'usernames' (length=5)
  1 => string 'masterNames' (length=8)
  2 => string 'data' (length=4)

Expected
  array(
    'usernames',
    'masterNames',
    'data' => array('aliases')
  )

I'm losing track on the $child part I think, somewhere I should be returning something and assigning it but I think I've looked at this to long and overlooking the obvious.
Any help is awesome.

A:

$testArr = array(
    'id' => '249653315914',
    'title' => 'jake',
    'description' => 'testing',
    'usernames' => array('jake', 'liam', 'john'),
    'masterNames' => array('jake'),
    'data' => array(
        'aliases' => array(
            'jake'
        ),
        'aliases2' => array('level3' => array('jake'))
    )
);

function recursive_search($needle, $haystack) {
   $return = array();
   if (is_array($haystack))
      foreach($haystack as $key => $value)
      {
          if (is_array($value))
          {
             $child = recursive_search($needle, $value); 
             if (is_array($child) && !empty($child))
                $return = array_merge($return, array($key => $child));
             elseif ($child) $return[] = $key;
          }
          elseif ($value === $needle)
             if (is_integer($key))
                return true;
             else
                $return[] = $key;
      }
      elseif ($haystack === $needle)
         return true;

   return $return;
}

Output
Array
(
    [0] => title
    [1] => usernames
    [2] => masterNames
    [data] => Array
        (
            [0] => aliases
            [aliases2] => Array
                (
                    [0] => level3
                )

        )

)

Testing is needed, no warranty that it will work in all cases. Also, in the cases like this array('level3' => array('jake'), 'jake'), it will not go deeper to level3 and so on, as 'jake' is present in the original array. Please mention if that is not a desired behavior.
Edit by Bankzilla: To work with objects
function recursive_search($needle, $haystack) {
    $return = array();
    if (is_array($haystack) || is_object($haystack)) {
        foreach($haystack as $key => $value) {
            if (is_array($value) || is_object($value)) {
                $child = recursive_search($needle, $value); 
                if ((is_array($child) || is_object($child)) && !empty($child)) {
                    $return = array_merge($return, array($key => $child));
                } elseif ($child) {
                    $return[] = $key;
                }
            }
            elseif ($value === $needle) {
                if (is_integer($key)) {
                    return true;
                } else {
                    $return[] = $key;
                }
            }
        }
    } elseif ($haystack === $needle) {
        return true;
    }
    return $return;
}

