note 89621 added to class.arrayobject

From: Date: Tue, 17 Mar 2009 07:51:26 +0000
Subject: note 89621 added to class.arrayobject
Groups: php.notes 
Request: Send a blank email to php-notes+get-152021@lists.php.net to get a copy of this message
For those who thinks that it is impossible for a class implementing ArrayAccess to behave exactly like a real array, I wrote this class for my homemade framework. It features: * It's an object so you can perform chained gets/sets: $data->fruit->color->red = 'Apple'; * It's an array so you can perform multidimensional gets/sets too: $data['fruit']['color']['red'] = 'Apple'; //identical as the above code * Returns value by reference; $tmp =& $data['fruit']; $tmp->color->red = 'Apple'; // or... $tmp['color']['red'] = 'Apple'; * Use array functions. The method &toArray, returns the reference of the actual array contained in the object. This is very fast even for a big array, since whatever stored in Data object is the actual array. array_walk_recursive($data->toArray(), 'someCallback'); <?php /** Comments are trimmed down... * Kiara Framework 090312 -alpha- * @author Ario <rarioj at gmail dot com> * @license BSD License */ class Data implements Countable, Iterator, ArrayAccess { protected $_data; protected $_pos; public function __construct(array $array = array()) { $this->_data =& $array; $this->_pos = 0; } public function __get($key) { if (!isset($this->_data[$key])) $this->_data[$key] = array(); return $this->objectify($this->_data[$key]); } public function __set($key, $value) { $this->_data[$key] = $value; } public function __isset($key) { return isset($this->_data[$key]); } public function __unset($key) { unset($this->_data[$key]); } public function count() { return count($this->_data); } public function current() { return $this->objectify(current($this->_data)); } public function key() { return key($this->_data); } public function next() { next($this->_data); $this->_pos++; } public function rewind() { reset($this->_data); $this->_pos = 0; } public function valid() { return $this->_pos < count($this->_data); } public function offsetGet($offset) { $data =& $this->_data; if (is_null($offset)) { $data[] = array(); end($data); $offset = key($data); } return $this->__get($offset); } public function offsetSet($offset, $value) { $this->__set($offset, $value); } public function offsetExists($offset) { return $this->__isset($offset); } public function offsetUnset($offset) { $this->__unset($offset); } public function &toArray() { return $this->_data; } public function objectify(&$data) { if (!is_array($data)) return $data; return new self(&$data); } } ?> <?php // Constructing the class, you could provide the initial array as a param. $data = new Data( /* put initial array here */ ); // Since this object behave like an object, and an array: // You can do chained sets: $data->one->two->three = '123'; // And also assign using multidimensional matrix: $data['four']['five']['six'] = '456'; // You can also return the object as a reference. $tmp =& $data['seven']; // The do the stuff with it. $tmp['eight']['nine']['ten'] = '78910'; $tmp->eight->nine->eleven = '78911'; // Test: A function to double a value. function _double(&$v) { $v = (int) $v * 2; } // Test: A function to print key => value pair. function _print($v, $k) { echo $k.' = '.$v.PHP_EOL; } // Double the value. array_walk_recursive($data->toArray(), '_double'); // Print them. array_walk_recursive($data->toArray(), '_print'); // See what we have now. print_r($data->toArray()); ?> Result: three = 246 six = 912 ten = 157820 eleven = 157822 Array ( [one] => Array ( [two] => Array ( [three] => 246 ) ) [four] => Array ( [five] => Array ( [six] => 912 ) ) [seven] => Array ( [eight] => Array ( [nine] => Array ( [ten] => 157820 [eleven] => 157822 ) ) ) ) ---- Server IP: 202.158.52.162 Probable Submitter: 114.59.12.172 ---- Manual Page -- http://www.php.net/manual/en/class.arrayobject.php Edit -- https://master.php.net/note/edit/89621 Del: integrated -- https://master.php.net/note/delete/89621/integrated Del: useless -- https://master.php.net/note/delete/89621/useless Del: bad code -- https://master.php.net/note/delete/89621/bad+code Del: spam -- https://master.php.net/note/delete/89621/spam Del: non-english -- https://master.php.net/note/delete/89621/non-english Del: in docs -- https://master.php.net/note/delete/89621/in+docs Del: other reasons-- https://master.php.net/note/delete/89621 Reject -- https://master.php.net/note/reject/89621 Search -- https://master.php.net/manage/user-notes.php

« previous php.notes (#152021) next »