我有一个类,它基本上是一个Array的包装器,并实现了IteratorAggregate。 创建类的新对象时,它会将其值存储在名为$ value的受保护变量中。值可以是字符串,整数等。或者是可遍历的对象(如数组)。
此对象是“递归的”,因为当可遍历对象(如数组)传递给构造函数时,他会创建该类的另一个实例。这是澄清的构造函数:
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;
}
}
现在,我正在尝试为该类编写一个简单的排序方法。
按键排序,这就像魅力一样:
$success = ksort($this->value, $comparison);
但是要按值排序,asort不起作用,因为我尝试排序的实际值存储在value属性中。
所以我尝试使用uasort,就像这样:
$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;
});
但由于某些不明原因,我收到以下错误:
警告:uasort()[function.uasort]:用户修改了数组 第129行的/ * / * / * /ListItem.php中的比较函数
问。如果我只是为了比较访问$ value而实际上没有改变任何东西,为什么会发生这种情况?
答案 0 :(得分:1)
似乎闭包(或匿名函数)在全局范围内,这意味着uasort
无法访问ListItem
对象的私有或受保护成员(尽管其他ListItem
对象可以访问他们兄弟的私人/受保护财产)
这解决了问题:(转换为字符串)
$success = uasort($this->value, function ($objA, $objB) use ($comparison)
{
$a = (string) $objA;
$b = (string) $objB;
if($comparison == ListItem::SORT_NUMERIC) {
if (is_numeric($a)) $a = (int) $a;
if (is_numeric($b)) $b = (int) $b;
}
if ($a == $b) return 0;
else if($a < $b) return -1;
else return 1;
});