我必须实现哪个 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 中有这么多原生数组操作函数。
顺便说一句:这看起来像是 trait
s 的一个很好的用例【参考方案3】:
没有这样的接口,数组函数只能在原生数组上工作。但是,您可以将 IteratorAggregate
等 Traversable 转换为带有 iterator_to_array
的数组
顺便说一句,这里解释了为什么特别是 ArrayAccess
没有帮助:PHP: how can I sort and filter an "array", that is an Object, implementing ArrayAccess?
【讨论】:
以上是关于我必须实现哪个 SPL 接口才能在对象上使用 usort() 函数?的主要内容,如果未能解决你的问题,请参考以下文章