Advertisement
Guest User

Untitled

a guest
Jul 6th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     /**
  2.      * Drills the array to the last but second path segment and returns the parent (by reference), and the last segment
  3.      * key for further operations. With these references you are free to read/set/unset the element in the original
  4.      * array.
  5.      *
  6.      * Example usage:
  7.      *
  8.      * You have array $foo, and you want to check if $foo['a']['b']['c'] exists and if so output its value, then unset
  9.      * it inside the array. We do this without having the path hardcoded at the time of programming:
  10.      *
  11.      * $path = 'a.b.c';
  12.      * $parent = & Phi_Data_ArrayUtils::drill($path, $foo, $key);
  13.      *
  14.      * if (isset($parent[$key])) {
  15.      *      echo $parent[$key];
  16.      *      unset($parent[$key]);
  17.      * }
  18.      *
  19.      * @param string $path      Array path identifier, for example: 'abc[def][ghi]', or 'abc.def.ghi'.
  20.      * @param array $arr        Array to be scanned.
  21.      * @param string $key       Returns in this var the key under which the element is found (as per path spec).
  22.      * @param bool $force       Optional (default = false). When true, if the parent array doesn't exist, it's created
  23.      *              as per spec. If a non-last segment along the way does exist, but is a scalar, $parent
  24.      *              will still return null;
  25.      * @param string $delim     One or more chars that will be considered delimiters between path segments, by default
  26.      *              ".[]" (to understand dot path and standard PHP array syntax).
  27.      * @return mixed        The parent array of the element. Null if doesn't exist.
  28.      */
  29.     static public function & drill($path, & $arr, & $key, $force = false, $delim = '.[]')
  30.     {  
  31.         $node = & $arr; // current node
  32.        
  33.         /*
  34.         TODO: commented out since not compatible with the short dot syntax
  35.  
  36.         // this special case speeds up resolving single-segment paths (a common case) but slows down
  37.         // a little the two and more segs. No enough stats to decide whether to drop this.
  38.         if ($path[strlen($path) - 1] != ']') {
  39.             $key = $path;
  40.             return $arr;
  41.         }
  42.         */
  43.        
  44.         $key = strtok($path, $delim);
  45.        
  46.         // NOTE: caching the parsed keys was tried but cache management turned out slower than parsing always
  47.         // caching on a higher level by the caller, when possible, may be efficient
  48.        
  49.         // unrolling the loop for the first few cycles shaves ~10% of the function run time.
  50.         // this is the same code as the for loop below (compacted)
  51.        
  52.         if (($ck = strtok($delim)) === false) return $node;
  53.         if (!isset($node[$key])) if ($force) { $node[$key] = array(); } else { $res = null; return $res; }
  54.         $node = & $node[$key]; $key = $ck;
  55.        
  56.         if (($ck = strtok($delim)) === false) return $node;
  57.         if (!isset($node[$key])) if ($force) { $node[$key] = array(); } else { $res = null; return $res; }
  58.         $node = & $node[$key]; $key = $ck;
  59.        
  60.         if (($ck = strtok($delim)) === false) return $node;
  61.         if (!isset($node[$key])) if ($force) { $node[$key] = array(); } else { $res = null; return $res; }
  62.         $node = & $node[$key]; $key = $ck;
  63.        
  64.         for (;;) {
  65.             // ck = candidate key
  66.             if (($ck = strtok($delim)) === false) return $node;
  67.            
  68.             if (!isset($node[$key])) {
  69.                 if ($force) {
  70.                     $node[$key] = array();
  71.                 } else {
  72.                     $res = null; return $res;
  73.                 }
  74.             }
  75.            
  76.             $node = & $node[$key];
  77.             $key = $ck;
  78.         }
  79.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement