Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

For some reason, using the following means to loop an array resists its break statements and continues to loop recursively to the utmost last element of the array

function loop($target, $array) {
  if($this) {
    if(!isset($GLOBALS["loop"])) {
      $GLOBALS["loop"]+=1;
      $GLOBALS["arrayCount"] = count($array, COUNT_RECURSIVE);
    }
  }
  $keys = array_keys($array);
  $values = array_values($array);
  for($i=0;$i<count($array);$i++) {
    $GLOBALS["iteration"]+=1;
    if($keys[$i] === $target) {
      print "Found $target.<br>";
      break;
    }
    if(is_array($array[$i])) {
      loop($target, $array[$i]);
    }
    if($values[$i] === $target) {
      print "Found $target.<br>";
      break;
    }
    if($GLOBALS["iteration"] >= $GLOBALS["arrayCount"]) {
      print "Looped array.<br>";
      break;
    }
}

Any help is greatly appreciated!

Solved: it required an exit statement to be appended, so thanks to the mysterious comment which disappeared for whatever reason! Although, it would be interesting to learn of why a break statement is insufficient to stop the recursive looping.

share|improve this question
 
Why not use array_key_exists() or even isset($array[$target])? –  g13n May 18 '12 at 1:24
 
@g13n that's merely to log the total number of iterations and complete length of the initial input array. That's not the reason why this isn't working as intended. –  user784446 May 18 '12 at 1:29

3 Answers

I actually found the issue ...

The following code:

if(is_array($array[$i])) {
  loop($target, $array);
}

should be:

if(is_array($array[$i])) {
  loop($target, $array[$i]);
}
share|improve this answer
 
Apologies, but that was due to a type error when providing an example. This still doesn't solve the problem. –  user784446 May 18 '12 at 1:42
 
@user784446 there are some fundamental problems in the program. You are looping through the array (using count) but note that if the array is an associative array then $array[$i] would be undefined. –  g13n May 18 '12 at 1:54
 
But it works, I can suppress the undefined notification if I want. –  user784446 May 18 '12 at 20:10

Just a guess, but maybe those statements should be else ifs? Could cause some weird recursion issues unless that's intentional.

share|improve this answer
 
Thanks for the reply. It's worked before this way but I'm not entirely cognizant of the differences from a previous use of this method. –  user784446 May 18 '12 at 1:23
 
@jmosesman the else ... if is not really necessary, its more of a syntactic sugar –  g13n May 18 '12 at 1:27
 
Using a series of if statements will check each statement within each iteration of the for loop. So it could be possible that the second if statement is true, and also the third one. If each of these 4 if statements are exclusive conditions (you only want one to happen), the second, third, and fourth ifs can be changed to else if--so if a statement is found to be true it will skip the others for that iteration. Hope that's what you were asking and not a lot of information you didn't want or need. –  jmosesman May 18 '12 at 1:27
 
@jmosesman they are, but in this case he's either looping around or exiting based on each condition. –  g13n May 18 '12 at 1:29

That's a rather strange loop you have there. You can avoid writing your own recursion using built-in types; I think this is what you're trying to do:

<? //PHP 5.4+

$loop = static function($target, array $array){
    $query = $array;
    $query = new \RecursiveArrayIterator($query);
    $query = new \RecursiveIteratorIterator(
        $query, 
        \RecursiveIteratorIterator::SELF_FIRST
    );
    foreach($query as $key => $value){
        if ($key === $target){
            return "Found $target (key)";
        } elseif ($value === $target){
            return "Found $target (value)";
        }
    }
};

$testData = [
 'key1' => 'value1',       
 'key2' => 'value2',
 'key3' => [
     'key4' => 'value4',
 ],      
];

echo
    $loop('key2', $testData), '<br/>',
    $loop('key3', $testData), '<br/>',
    $loop('key4', $testData), '<br/>',
    $loop('value4', $testData), '<br/>'
;
/*
Found key2 (key)
Found key3 (key)
Found key4 (key)
Found value4 (value)
 */
?>
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.