note 99585 deleted from class.arrayaccess by danbrown
| From: | danbrown@php.net | Date: | Wed, 25 Aug 2010 14:01:36 +0000 |
| Subject: | note 99585 deleted from class.arrayaccess by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-172049@lists.php.net to get a copy of this message | ||
Note Submitter: pas dot svijeta at gmail dot com
----
I think this improves uramihsayihok's RecursiveArrayClass class. Here, there's no need for
private $data = array() property declaration; every property is placed in the object with public
visibility, and can be accessed directly. The protected $properties declaration here serves as a
container for publicly set property names, i.e. as index, and iterator distinguishes those
properties from per-class-declared properties (public or privete) with the
$this->properties = array_keys(array_diff_key(get_object_vars($this),
get_class_vars(get_class($this))));
statement, so every property declared within the class isnot taken into account while iterating (a
way to "protect" class-declared properties). Further, every array-like argument in the
multidimensional array is transformed (recursion) to ArrAccesIterator object, allowing consistent
approach to the object properties with foreach construct (see example below). Also, toArray() member
method transforms every object of ArrAccessIterator back to array recursively, thus providing the
consistency of structure.
Notation $this->{$offset} allows indexed (nonhash) arrays to be manipulated with consistently
with respect to array keys.
class ArrAccessIterator implements Countable, Iterator, ArrayAccess
{
protected $properties;
public function __construct(array $data = array())
{
foreach ($data as $key => $value)
$this->{$key} = is_array($value) ? new self($value) : $value;
$this->properties = array_keys(array_diff_key(get_object_vars($this),
get_class_vars(get_class($this))));
}
public function __clone()
{
foreach ($this as $key => $value)
if ($value instanceof self) $this->{$key} = clone $value;
}
public function count()
{
return count(array_keys(array_diff_key(get_object_vars($this),
get_class_vars(get_class($this)))));
}
public function offsetSet($offset, $value)
{
$this->{$offset} = is_array($value) ? new self($value) : $value;
$this->properties = array_keys(array_diff_key(get_object_vars($this),
get_class_vars(get_class($this))));
}
public function offsetGet($offset)
{
return $this->{$offset};
}
public function offsetExists($offset)
{
return isSet($this->{$offset});
}
public function offsetUnset($offset)
{
unset($this->{$offset});
$this->properties = array_keys(array_diff_key(get_object_vars($this),
get_class_vars(get_class($this))));
}
public function rewind()
{
reset($this->properties);
}
public function valid()
{
return !is_null(key($this->properties));
}
public function key()
{
return current($this->properties);
}
public function current()
{
return $this->{$this->key()};
}
public function next()
{
next($this->properties);
}
}
/* example */
$q = array(1, 2, 3, 4, array(12, 13, 14, 15), 6, 7, 8, array(21, 22, 23, 24, array(31, 32, 33,
array(44, 45), 35, 36), 26, 27), 10);
$a_a_i = new ArrAccessIterator($q);
function nasty_recursive($a_a_i, $init = false)
{
static $margin_left = 20;
print '<div style="margin-left:'.strval($margin_left).'px;">';
foreach ($a_a_i as $k => $v) {
print $k.'=>';
$v instanceof Traversable ? nasty_recursive($v) : print $v.'<br />';
}
print '</div>';
$init ? ($margin_left = 20) : ($margin_left += 10);
}
nasty_recursive($a_a_i, true);
unset($a_a_i[4][2]);
print '-------------------';
nasty_recursive($a_a_i, true);
$a_a_i[10] = array('a', 'b', 'c');
print '-------------------';
nasty_recursive($a_a_i, true);
print '-------------------';
print '<br />level 0 count: '.count($a_a_i);
print '<br />level 8 - 4 count: '.count($a_a_i[8][4]);