PHP迭代器不能通过引用与foreach一起使用
我有一个实现迭代器的对象,它包含两个数组:“条目”和“页面”。每当我循环遍历这个对象时,我都想修改entries数组,但是我得到了一个错误PHP迭代器不能通过引用与foreach一起使用,php,arrays,foreach,Php,Arrays,Foreach,我有一个实现迭代器的对象,它包含两个数组:“条目”和“页面”。每当我循环遍历这个对象时,我都想修改entries数组,但是我得到了一个错误迭代器不能用于foreach by reference,我在中看到了这个错误 我的问题是,在对循环对象使用foreach时,如何使用Iterator类来更改循环对象的值 我的代码: //$flavors = instance of this class: class PaginatedResultSet implements \Iterator { p
迭代器不能用于foreach by reference
,我在中看到了这个错误
我的问题是,在对循环对象使用foreach
时,如何使用Iterator
类来更改循环对象的值
我的代码:
//$flavors = instance of this class:
class PaginatedResultSet implements \Iterator {
private $position = 0;
public $entries = array();
public $pages = array();
//...Iterator methods...
}
//looping
//throws error here
foreach ($flavors as &$flavor) {
$flavor = $flavor->stdClassForApi();
}
这样做的原因是,有时
$flavors
不是我的类的实例,而是一个简单的数组。我希望能够轻松地修改此数组,而不管它是什么类型。我刚刚尝试创建一个迭代器,它使用:
public function ¤t() {
$element = &$this->array[$this->position];
return $element;
}
但这仍然不起作用
我建议您最好实现\ArrayAccess
,这将允许您执行以下操作:
foreach ($flavors as $key => $flavor) {
$flavors[$key] = $flavor->stdClassForApi();
}
使用生成器:
根据生成器上的标记注释进行更新,以下内容将允许您迭代结果,而无需实现\Iterator
或\ArrayAccess
class PaginatedResultSet {
public $entries = array();
public function &iterate()
{
foreach ($this->entries as &$v) {
yield $v;
}
}
}
$flavors = new PaginatedResultSet(/* args */);
foreach ($flavors->iterate() as &$flavor) {
$flavor = $flavor->stdClassForApi();
}
这是PHP5.5中提供的一个功能。扩展Flosculus的解决方案,如果您不想每次使用迭代变量时都引用该键,可以在foreach的第一行将对该键的引用分配给新变量
foreach ($flavors as $key => $f) {
$flavor = &$flavors[$key];
$flavor = $flavor->stdClassForApi();
}
这在功能上与在基本对象上使用键相同,但有助于保持代码整洁,并缩短变量名。。。如果您在Cals中实现了迭代器函数,我建议您在类“setCurrent()”中添加另一个方法: 然后您可以在foreach循环中使用此函数:
foreach ($flavors as $flavor) {
$newFlavor = makeNewFlavorFromOldOne($flavor)
$flavors -> setCurrent($newFlavor);
}
如果您在其他类中需要此函数,还可以定义一个新的迭代器并扩展迭代器接口以包含setCurrent()为什么不先检查它是类还是数组,然后适当地处理它?@MuppetGrinder因为我在很多地方使用这些方法,我不想每次都要进行检查,也可以“通过引用”访问生成器的元素,因此这可能是一种替代方法。我最终实现了\ArrayAccess和\Iterator,然后使用$key=>$val样式而不是通过引用。这工作得很好。@MarkBaker我仍然需要研究它们是如何工作的,当它们说函数的状态在每次调用时都不会改变时,我对它们的意思有点困惑。@Flosculus-这意味着在对生成器进行迭代时,生成器中的变量不会超出范围,只有在它终止时才会超出范围(不再有效)…我目前正在写一本关于发电机的书PHP@MarkBaker对发电机进行了更新。谢谢,很有教育意义。
foreach ($flavors as $flavor) {
$newFlavor = makeNewFlavorFromOldOne($flavor)
$flavors -> setCurrent($newFlavor);
}