I have a class that is basically a wrapper to an Array and implements IteratorAggregate.
When a new object of the class is created, it stores it’s value in a protected variable called $value. The value can be a string, integer, etc.. or a traversable object (like an array).
This object is “recursive” since when a traversable object (like an array) is passed to the constructor, he creates another instance of the class. Here’s the constructor to clarify:
class ListItem implements \IteratorAggregate
{
protected $readOnly = false;
protected $key;
protected $value;
public function __construct($key, $value, $readOnly = false)
{
if($readOnly) $this->readOnly = true;
if(is_numeric($key)) $key = 'index'.$key;
$this->key = $key;
if (is_array($value) || $value instanceof Traversable) {
$this->value = array();
foreach($value as $k => $v) {
if(is_numeric($k)) $k = 'index'.$k;
$this->value[$k] = new ListItem($k, $v, $readOnly);
}
} else {
$this->value = $value;
}
}
public function __toString()
{
if ( is_array($this->value) ) {
return 'ListItem OBJECT(' . count($this->value) . ')';
} else {
return $this->value;
}
}
Right now, I’m trying to write a simple sorting method for the class.
To sort by Key, this works like a charm:
$success = ksort($this->value, $comparison);
but to sort by value, asort does not work since the actual value I’m trying to sort is stored inside the value property.
So I tried using uasort, like this:
$success = uasort($this->value, function ($a, $b)
{
if ($a->value == $b->value) return 0;
else if($a->value < $b->value) return -1;
else return 1;
});
but for some unclear reason i get the following error:
Warning: uasort() [function.uasort]: Array was modified by the user
comparison function in /* /* /* /ListItem.php on line 129
Q. Why does this happen if I’m just accessing $value for comparison not actually changing anything?
It seems a closure (or anonymous function) is in the global scope which means
uasortcould not access private or protected members of theListItemobject (although otherListItemObjects can access their sibling’s private/protected properties)this solved the problem: (casting to string)