2

我有一个实现 ArrayableInterface 的对象(顺便说一句,它来自 Laravel 的 Eloquent ORM)。

这个对象是 $articles。所以很自然,我可以这样做:

foreach ($articles as $article)
    echo $article->title . "<br/>";

我不能这样做:

shuffle($articles);

我得到shuffle() expects parameter 1 to be array, object given警告。

4

2 回答 2

3

不,这不是错误。

PHP 5 允许您使用foreach()循环遍历不是数组的对象。这些对象称为Iterators.

不幸的是,旧的基于数组的函数,比如shuffle()不能处理迭代器。

这样做的主要原因是迭代器甚至可能无法排序——例如,您可以让迭代器直接从文件或 URL 中读取,并在每次foreach()循环循环时读取新的数据行。这显然无法排序,因为它是在foreach()过程中读取的。

iterator_to_array()您可以使用巧妙命名的函数将 Iterator 转换为数组。但是,如果您不知道迭代器要处理多少数据,这可能不是一个好主意,因为您可能会发现它使用了大量内存。

一些迭代器可能会在迭代器对象本身内提供用于对数据进行排序或过滤的方法。如果是这样,这是一个比尝试将其作为数组排序更好的解决方案。

如果您正在使用 ORM,那么这意味着您的 Iterator 对象正在从数据库中读取数据。在这种情况下,通过 DB 查询(即ORDER BY或 ORM 提供的任何方法)对其进行排序可能比在 PHP 中对数据进行排序更好。

于 2013-02-04T17:32:39.777 回答
2

我不知道接口做了什么..但洗牌功能也不会,因为它只识别数组。你需要这样做:

$array = iterator_to_array($articles);
$shuffled = shuffle($array);

从 OOP 的角度来看,实际上,您的对象应该包含 shuffle 实现:

 $articles->shuffle();
于 2013-02-04T17:26:57.570 回答