2012-10-08 91 views
1

所以,我有这样的:添加新的索引到一个数组内的foreach

$abc = array('a','b','c'); 
foreach ($abc as $k => &$a) { 
    echo $a; 
    if ($k == 1) 
     $abc[] = 'd'; 
} 

工作的预期,通过在foreach迭代4次,给我:

abcd 

但是现在,当我有此:

$myvar = $this->someModel->return_an_array_as_result(); // returns array([0] => array('a' => 'b')) 

foreach ($myvar as $myvar_key => &$mv){ 
    $myvar[] = array('e' => 'f'); 
    var_dump($myvar); 
    if ($myvar_key == 5) die; 
} 

该foreach只运行一次。

重置内部指针时foreach如何工作的任何想法?

+0

是的,它会运行一次......你'$ myvar'返回'array([0] => array('a'=>'b'))' – Baba

+0

是的,但仔细看看第二个代码:'$ myvar []' – dmmd

+0

查看更新的答案...它应该使用'ArrayObject' Insted – Baba

回答

1

我明白你的意思,你可以使用ArrayObject这将允许追加到数组,而你仍然遍历数组

$myvar = new ArrayObject(array('a' => 'b')); 
$x = 0; 
foreach ($myvar as $myvar_key => $mv) { 
    $myvar->append(array('e' => 'f')); 
    if (($x >= 4)) 
     break; 
    $x ++; 
} 
var_dump($myvar); 

输出

object(ArrayObject)[1] 
    public 'a' => string 'b' (length=1) 
    array 
     'e' => string 'f' (length=1) 
    array 
     'e' => string 'f' (length=1) 
    array 
     'e' => string 'f' (length=1) 
    array 
     'e' => string 'f' (length=1) 
    array 
     'e' => string 'f' (length=1) 
+0

不完美,因为现在我有一个对象而不是数组来处理。但仍然是一个很好的解决方案。谢谢! :) – dmmd

+0

@jlcd'(array)$ myvar'会将它转换为数组..简单,因为 – Baba

+2

确实,'ArrayObject'实现了一个动态的Enumerable接口,它认识到'next'调用之间的变化。 +1为另一种方法。 –

1

这是因为foreach实际上是在一个副本阵列的工作。如果您计划在迭代阵列时修改阵列,请使用传统的for循环。

欲了解更多信息,请参阅foreach上的PHP文档。另外,如果您想要在迭代时修改元素,则可以使用&$reference(有关此内容的更多信息也可在foreach文档中找到)。

+0

但是第一次实现如何RK? – dmmd

+0

你并不依赖于退出的条件(在第二次迭代中已经满足条件,添加了附录,退出了循环)。第二个例子没有5个元素(在循环的持续时间内也不是这样),因为当foreach采用快照时,它只有3个元素。而且因为它是一个副本而不是参考,所以'foreach'在它意识到有5个元素之前会长时间退出。 –

+0

但是'$ myvar []'应该为'$ myvar'数组添加无限的新索引,因此在某些时候应该有5个元素。发生什么事是通过所谓的“快照”迭代一次,忽略新的位置。我找不到第一个例子和第二个例子之间的区别。 – dmmd

相关问题