我必须实现哪个 SPL 接口才能在对象上使用 usort() 函数?

Posted

技术标签:

【中文标题】我必须实现哪个 SPL 接口才能在对象上使用 usort() 函数?【英文标题】:Which SPL interface I must implement to be able to use usort() function on an object? 【发布时间】:2013-02-14 16:55:05 【问题描述】:

我有一个代表集合实体的类:它只有一个属性,一个数组。这个类实现了\Countable\IteratorAggregate,以及对这个问题最重要的\ArrayAccess

但是使用时:

        usort($collectionData, function($a, $b) 
            return ($a->getPosition() > $b->getPosition());
        );

我得到以下可捕获的异常:

警告:usort() 期望参数 1 是数组,对象在 /home/alain/workspace/(...)n.php 第 1057 行(500 内部服务器错误)

我可以使用中间变量来欺骗:

        $data = $collectionData->getData();
        usort($data, function($a, $b) 
            return ($a->getPosition() > $b->getPosition());
        );
        $collectionData->setData($data);

但是想知道有没有可以通过usort()的数组参数类型期望的SPL接口。

【问题讨论】:

【参考方案1】:

我真的认为你应该扩展的唯一类是ArrayIterator,因为它已经实现了

ArrayIterator 实现了 Iterator , Traversable , ArrayAccess , SeekableIterator , Countable , Serializable

也支持

 public void uasort ( string $cmp_function )
 public void uksort ( string $cmp_function )

And so many other methods

所以你的课就这么简单

class CollectionEntity extends ArrayIterator 

然后

$collectionData->uasort(function ($a, $b) 
    return ($a->getPosition() > $b->getPosition());
);

【讨论】:

是的,你可以实现offsetSet ....正如我所说的ArrayIterator也实现ArrayAccess 是的,我刚写完评论就看到了(这就是我删除它的原因)。【参考方案2】:

我不知道。没有接口会使您的对象也成为array,这就是您需要传递给usort() 的内容。但是,您可以通过将 usort() 方法添加到您的类中来将此行为封装在您的类中。

class CollectionEntity implements Countable, IteratorAggregate, ArrayAccess 

  private $data = array();

  /* other methods omitted for simplicity */

  public function usort(Closure $callback) 
    usort($this->data,$callback);
  



【讨论】:

这也是唯一的方法 当然你的方法比我的好。不幸的是,无法重载 array 类型,我们在 PHP 中有这么多原生数组操作函数。 顺便说一句:这看起来像是 traits 的一个很好的用例【参考方案3】:

没有这样的接口,数组函数只能在原生数组上工作。但是,您可以将 IteratorAggregate 等 Traversable 转换为带有 iterator_to_array 的数组

顺便说一句,这里解释了为什么特别是 ArrayAccess 没有帮助:PHP: how can I sort and filter an "array", that is an Object, implementing ArrayAccess?

【讨论】:

以上是关于我必须实现哪个 SPL 接口才能在对象上使用 usort() 函数?的主要内容,如果未能解决你的问题,请参考以下文章

在PHP中使用SPL库中的对象方法进行XML与数组的转换

在PHP中使用SPL库中的对象方法进行XML与数组的转换

设计模式——利用 SPL 快速实现观察者模式

java 为了实现自定义对象的序列化,该自定义对象必须实现哪个接口

spl_autoload_register

php SPL常用接口