uasort()函数:数组被用户比较函数修改

3

我有一个类,基本上是一个数组的包装器,并实现了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;
        }
    }

现在,我正在尝试为这个类编写一个简单的排序方法。

要按Key排序,使用以下代码就可以:

$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]:在ListItem.php的第129行,用户比较函数修改了数组


问:如果我只是访问$value来进行比较而没有实际更改任何内容,为什么会出现这种情况?

1个回答

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;
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接