我只是在编写一个简单的php脚本时有了一些非常奇怪的行为.我将其减少到了重新创建错误所需的最低限度:

<?php

$arr = array("foo",
             "bar",
             "baz");

foreach ($arr as &$item) { /* do nothing by reference */ }
print_r($arr);

foreach ($arr as $item) { /* do nothing by value */ }
print_r($arr); // $arr has changed....why?

?>

这将输出:

Array
(
    [0] => foo
    [1] => bar
    [2] => baz
)
Array
(
    [0] => foo
    [1] => bar
    [2] => bar
)

这是一个错误还是应该发生的一些非常奇怪的行为?

推荐答案

在第一个foreach循环之后,$item仍然是对$arr[2]也在使用的某个值的引用.因此,第二个循环中的每个foreach调用(不是通过引用调用)都会用新值替换该值,从而替换$arr[2].

So loop 1, the value and $arr[2] become $arr[0], which is 'foo'.
Loop 2, the value and $arr[2] become $arr[1], which is 'bar'.
Loop 3, the value and $arr[2] become $arr[2], which is 'bar' (because of loop 2).

值"baz"实际上在第二个foreach循环的第一次调用中丢失.

调试输出

对于循环的每次迭代,我们将 echo 值$item,并递归打印数组$arr.

当运行第一个循环时,我们会看到以下输出:

foo
Array ( [0] => foo [1] => bar [2] => baz )

bar
Array ( [0] => foo [1] => bar [2] => baz )

baz
Array ( [0] => foo [1] => bar [2] => baz )

在循环结束时,$item仍然指向与$arr[2]相同的位置.

当运行第二个循环时,我们会看到以下输出:

foo
Array ( [0] => foo [1] => bar [2] => foo )

bar
Array ( [0] => foo [1] => bar [2] => bar )

bar
Array ( [0] => foo [1] => bar [2] => bar )

您将注意到,每次数组如何将一个新值放入$item,它还会用相同的值更新$arr[3],因为它们仍然指向相同的位置.当循环到达数组的第三个值时,它将包含值bar,因为它刚刚由该循环的前一次迭代设置.

是虫子吗?

不.这是引用项的行为,而不是错误.这与运行类似:

for ($i = 0; $i < count($arr); $i++) { $item = $arr[$i]; }

foreach循环在本质上并不特殊,它可以忽略引用的项.只需每次将该变量设置为新值,就像在循环之外一样.

Php相关问答推荐

自定义通知在Woocommerce我的帐户自定义端点页面上不起作用

以编程方式更改新订单、已取消订单和失败订单的邮箱WooCommerce通知

WooCommerce产品按特定元数据的自定义数字排序选项

在WooCommerce产品中按类型对产品属性术语进行分类以供显示

WooCommerce:在 checkout 审核单和发票中显示定制产品数据

如何在WooCommerce产品子类别中显示特定内容

在Symfony 6.4中将工作流动态添加到服务

Symfony5:如何在不登录的情况下使API路由可访问?

如何在laravel中使用script type= text/html/script

在WooCommerce存档页面中显示可变产品的库存变化属性

将一个表中的行连接为不同表MYSQL中的一列

PHP 解析 XML 以获取多个深度的所有字符串值

通过ajax发送数据到下拉列表未完全设置为所选

如何通过帖子自定义元数据进行查询

基于WooCommerce中的产品变体自定义感谢页面跳转

为什么在解压缩具有混合字符串和 int 键的关联数组时出现错误消息无法使用位置参数...?

在全局安装 Composer 包后运行命令

我正在使用 Baryryvdh/laravel-snappy 从 HTML 导出 PDF 它正在工作但缩小了 pdf 文件

用于多态服务的 Symfony setter 注入

检测字符串是否包含Letter with Tilde或Letter + Combining Tilde