Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
<?php /** * Binding references from variables to deep array and object structures. * * joon park - joon@dvessel.com */ function &_select_reference(&$elements, $selection) { // Clean and convert selection strings into a flat array. // Uses ">" to delimit each value. if (!empty($selection) && is_string($selection)) { $selection = explode('>', str_replace(array(' '), '', $selection)); } return _sub_select($elements, $selection); } function &_sub_select(&$elements, &$selection) { // Keep traversing in recursive calls. Always maintain reference. foreach ($selection as $i => $select) { // Treat arrays and objects the same for consistency. if (is_array($elements) && isset($elements[$select])) { $element_child = &$elements[$select]; } elseif (is_object($elements) && isset($elements->$select)) { $element_child = &$elements->$select; } else { // A miss. Break out and do nothing. $return_element = FALSE; break; } // Recurse. unset($selection[$i]); $return_element = &_sub_select($element_child, $selection); } // If $return_element is not set, then the target was found. if (!isset($return_element)) { $return_element = &$elements; } return $return_element; } // Example: ================================================================== $var['member_a']['sub_member_a']['sub_sub_member_a'] = 'AAA'; $var['member_a']['sub_member_b']['sub_sub_member_c'] = 'ABC'; $var['object']->member['a']['b']['c'] = 'Object:ABC'; // Traverse through array keys to bind reference. $sub_element = &_select_reference($var, 'member_a > sub_member_a > sub_sub_member_a'); $sub_element = 'AAX'; print var_dump($var); // Outputs: // array(2) { // ["member_a"]=> // array(2) { // ["sub_member_a"]=> // array(1) { // ["sub_sub_member_a"]=> // &string(3) "AAX" << referenced through $sub_element // } // ["sub_member_b"]=> // array(1) { // ["sub_sub_member_c"]=> // string(3) "ABC" // } // } // … $object_deep_c = &_select_reference($var, 'object > member > a > b > c'); $object_deep_c = 'Object:ABX'; print var_dump($var); // Outputs: // array(2) { // … // ["object"]=> // object(stdClass)#1 (1) { // ["member"]=> // array(1) { // ["a"]=> // array(1) { // ["b"]=> // array(1) { // ["c"]=> // &string(10) "Object:ABX" << referenced through $object_deep_c // } // } // } // } // }
This paste will be private.
From the Design Piracy series on my blog: