Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * Drills the array to the last but second path segment and returns the parent (by reference), and the last segment
- * key for further operations. With these references you are free to read/set/unset the element in the original
- * array.
- *
- * Example usage:
- *
- * You have array $foo, and you want to check if $foo['a']['b']['c'] exists and if so output its value, then unset
- * it inside the array. We do this without having the path hardcoded at the time of programming:
- *
- * $path = 'a.b.c';
- * $parent = & Phi_Data_ArrayUtils::drill($path, $foo, $key);
- *
- * if (isset($parent[$key])) {
- * echo $parent[$key];
- * unset($parent[$key]);
- * }
- *
- * @param string $path Array path identifier, for example: 'abc[def][ghi]', or 'abc.def.ghi'.
- * @param array $arr Array to be scanned.
- * @param string $key Returns in this var the key under which the element is found (as per path spec).
- * @param bool $force Optional (default = false). When true, if the parent array doesn't exist, it's created
- * as per spec. If a non-last segment along the way does exist, but is a scalar, $parent
- * will still return null;
- * @param string $delim One or more chars that will be considered delimiters between path segments, by default
- * ".[]" (to understand dot path and standard PHP array syntax).
- * @return mixed The parent array of the element. Null if doesn't exist.
- */
- static public function & drill($path, & $arr, & $key, $force = false, $delim = '.[]')
- {
- $node = & $arr; // current node
- /*
- TODO: commented out since not compatible with the short dot syntax
- // this special case speeds up resolving single-segment paths (a common case) but slows down
- // a little the two and more segs. No enough stats to decide whether to drop this.
- if ($path[strlen($path) - 1] != ']') {
- $key = $path;
- return $arr;
- }
- */
- $key = strtok($path, $delim);
- // NOTE: caching the parsed keys was tried but cache management turned out slower than parsing always
- // caching on a higher level by the caller, when possible, may be efficient
- // unrolling the loop for the first few cycles shaves ~10% of the function run time.
- // this is the same code as the for loop below (compacted)
- if (($ck = strtok($delim)) === false) return $node;
- if (!isset($node[$key])) if ($force) { $node[$key] = array(); } else { $res = null; return $res; }
- $node = & $node[$key]; $key = $ck;
- if (($ck = strtok($delim)) === false) return $node;
- if (!isset($node[$key])) if ($force) { $node[$key] = array(); } else { $res = null; return $res; }
- $node = & $node[$key]; $key = $ck;
- if (($ck = strtok($delim)) === false) return $node;
- if (!isset($node[$key])) if ($force) { $node[$key] = array(); } else { $res = null; return $res; }
- $node = & $node[$key]; $key = $ck;
- for (;;) {
- // ck = candidate key
- if (($ck = strtok($delim)) === false) return $node;
- if (!isset($node[$key])) {
- if ($force) {
- $node[$key] = array();
- } else {
- $res = null; return $res;
- }
- }
- $node = & $node[$key];
- $key = $ck;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement