phpreflectionrecursiondetect

detecting infinite array recursion in PHP?


i've just reworked my recursion detection algorithm in my pet project dump_r()

https://github.com/leeoniya/dump_r.php

detecting object recursion is not too difficult - you use spl_object_hash() to get the unique internal id of the object instance, store it in a dict and compare against it while dumping other nodes.

for array recursion detection, i'm a bit puzzled, i have not found anything helpful. php itself is able to identify recursion, though it seems to do it one cycle too late. EDIT: nvm, it occurs where it needs to :)

$arr = array();
$arr[] = array(&$arr);
print_r($arr);

does it have to resort to keeping track of everything in the recursion stack and do shallow comparisons against every other array element?

any help would be appreciated,
thanks!


Solution

  • Because of PHP's call-by-value mechanism, the only solution I see here is to iterate the array by reference, and set an arbitrary value in it, which you later check if it exists to find out if you were there before:

    function iterate_array(&$arr){
    
      if(!is_array($arr)){
        print $arr;
        return;
      }
    
      // if this key is present, it means you already walked this array
      if(isset($arr['__been_here'])){
        print 'RECURSION';
        return;
      }
    
      $arr['__been_here'] = true;
    
      foreach($arr as $key => &$value){
    
        // print your values here, or do your stuff
        if($key !== '__been_here'){
          if(is_array($value)){
            iterate_array($value);
          }
    
          print $value;
        }
      }
    
      // you need to unset it when done because you're working with a reference...
      unset($arr['__been_here']);
    
    }
    

    You could wrap this function into another function that accepts values instead of references, but then you would get the RECURSION notice from the 2nd level on. I think print_r does the same too.