Php foreach-为什么它不';是否在迭代时覆盖数组值?

Php foreach-为什么它不';是否在迭代时覆盖数组值?,php,foreach,Php,Foreach,我对php的每次迭代都有疑问 请看我下面的代码 代码: $arr=array(1,2,3); echo '$arr value : '. $arr; echo '<br>'; foreach($arr as $arr){ echo $arr.'<br>'; } echo '$arr value : '. $arr; $arr value : Array 1 2 3 $arr value : 3 在迭代

我对php的每次迭代都有疑问

请看我下面的代码

代码:

   $arr=array(1,2,3);

    echo '$arr value : '. $arr;

    echo '<br>';

    foreach($arr as $arr){
        echo $arr.'<br>';
    }
    echo '$arr value : '. $arr;
$arr value : Array
1
2
3
$arr value : 3
在迭代数组时,我使用了相同的数组名为key
foreach($arr as$arr)
赋值,但效果很好。它是如何工作的

为什么它在迭代时不重写数组值

我想知道foreach迭代是如何工作的

请帮帮我

提前谢谢 Logan在迭代元素之前首先计算左侧。因此,对名称$arr的重新分配不会修改$arr

此外,循环变量泄漏到外部上下文中,如下所示:

即使在foreach循环之后,
$value
和最后一个数组元素的引用仍然保留。建议通过unset()将其销毁

当然,为了避免混淆,只需为循环变量使用与正在循环的数组不同的名称:

$arr=array(1,2,3);
foreach($arr as $a) { // Note the "as $a", not "as $arr"
    echo $a.'<br>';
}
echo '$arr value : '. $arr;
$arr=数组(1,2,3);
foreach($arr as$a){//注意“as$a”,而不是“as$arr”
回声$a.“
”; } 回显“$arr值:”$arr;
为什么它在迭代时不重写数组值


将处理原始数组的副本,以便在foreach循环中更改的内容不会更改正在循环的值。

$arr和$arr在代码中是相同的。源数组和引用变量具有相同的名称。因此foreach保留上次接收的值,而不会放弃该变量。

Hmm,经过一番调查,我得出了以下代码:

<?php
$arr=array(1,2,3);

echo '$arr value : '. $arr;

echo '<br>';

foreach($arr as $arr){
    echo $arr.'<br>';
}

foreach($arr as $key) {
    echo $key.'<br>';
}
echo '$arr value : '. $arr;

我对这一点的理解是,第二个
$arr
foreach
循环中隐藏着第一个,但一旦退出
foreach
循环,它就会在内部取消符号设置(
$arr

foreach
使用原始数组的副本,这样您就可以认为代码

foreach($arr as $arr){
    echo $arr.'<br>';
}
foreach($arr作为$arr){
回音$arr.
; }
如下所示:

for ($i = 0, $arr_tmp = $arr, $len = count($arr_tmp); $i < $len; $i++) {
  $arr = $arr_tmp[$i];
  echo $arr.'<br>';
}
for($i=0,$arr\u tmp=$arr,$len=count($arr\u tmp);$i<$len;$i++){
$arr=$arr_tmp[$i];
回音$arr.
; }

这解释了为什么
$arr
最终是
3

PHP使用
写时拷贝
延迟拷贝
机制来处理内存

在foreach迭代的第一阶段,
$arr
是“软拷贝的”(没有实际拷贝,只有
$array
zval
refcount
增加)。PHP变量的签出

就我们而言

  • 它首先保留对实际
    $arr
    变量的引用,数组的第一个值从引用点获取
  • 为了以后使用,第一个数组元素被分配给第二个
    $arr
    foreach($arr as$arr
  • 在下一次迭代中,从先前保存的参考点获取第二个数组值,并将该值分配给相同的
    $arr
    ,然后继续
  • 由于循环内部更改了
    $arr
    的值,因此不能使用
    $arr
    变量在循环外部打印该数组
希望你能理解

进行深入研究和检验

有趣的是,你也可以玩这个

current()

代码

$source = array(10, 20, 30);
foreach ($source as $value) {
    echo 'Value is ', $value, ', and current() is ', current($source), '<br>';
}

当您获取记录时,您是在过度写入数组,您要求代码从$arr获取记录并将其放入名为$arr的数组中,因此您是在使用单个参数过度写入整个数组 之前 $arr={1,2,3}; 在这一行和第一次迭代之后 foreach($arr as$arr)现在$arr等于3,这是数组的最后一个元素,我希望您理解这个问题

foreach ($arr as $arr) {
    // code
}
这可能会让你感到困惑,因为你的思维模式是:

  • PHP从
    $arr
    中取出当前元素,并前进数组指针
  • 它将值分配给
    $arr
  • 它执行
    //code
  • 它从第一步开始重复
  • 但它实际上是这样做的(或者至少是一种近似的简化):

  • PHP启动
    foreach
    操作,获取与
    $arr
  • 它将这个数组放在内部的某个地方,比如说一个
    var迭代器
  • 它从
    var迭代器
    获取当前元素并推进迭代器
  • 它为脚本中的
    $arr
    赋值
  • 它执行
    //code
  • 它从步骤3开始重复
  • 换句话说,它不会在每次迭代时从
    $arr
    获取下一个值,它只使用一次来获取初始迭代器。它迭代的实际内容存储在内部,不再与
    $arr
    关联。这意味着
    $arr
    对于脚本中的其他用途是免费的,PHP很乐意在每次迭代中重用它。循环完成后,最后一个元素保留在
    $arr

    如果您了解匿名函数,也许这可以更好地说明为什么它是这样工作的:

    foreach($arr, function ($arr) {
        // code
    });
    
    这样的
    foreach
    功能的实现可以简单如下:

    function foreach(array $array, callable $code) {
        while (list(, $value) = each($array))  {
            $code($value);
        }
    }
    

    这绝对是一个令人惊讶的输出。php是否会以某种方式缓存原始$arr(数组)的内容,然后在循环时更改并显示$arr(1、2和3),最后$arr保留为“3”,因为它不会将缓存的值保存回原始文件中,因为php不希望你覆盖它。@PraveenKumar请仔细检查我的question@loganphp我也看到了。嗯,呃P我没有答案。它处理PHP解释器本身的内部工作。:)“我想这就是问题所在——当变量同名时,为什么它会这样工作呢?”MarekKarbarz用这句话修正了答案
    foreach($arr, function ($arr) {
        // code
    });
    
    function foreach(array $array, callable $code) {
        while (list(, $value) = each($array))  {
            $code($value);
        }
    }