使用多维数组Foreach循环作用域



谁能解释一下这段代码的输出?

为什么是fb而不是100100 ?

$items = array();
$items[] = "foo";
$items[] = "bar";
foreach($items as $item) {
    $item['points'] = 100;
}
foreach($items as $item) {
    echo $item['points']; //output: "fb"
}

循环遍历包含两个元素的$items数组。

第一:foo,第二:bar。例如

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

现在你像这样访问它们:

echo $item['points'];

PHP将把points(字符串)转换为整数,正如您可以从手动警告中看到的那样:

警告:[…非整数类型被转换为整数。[…]

在你的例子中是0。

所以你访问这两个值(字符串)作为数组:

string: f o指数: 0  1 2//美元指数("点")——>美元指数[0]字符串:b a r指数: 0  1 2//美元指数("点")——>美元指数[0]之前

打印两个字符串的第一个字符(例如foo和bar),它们是:

fb
编辑:

这里还值得注意的是,PHP只会从较新版本的PHP <5.4中将其静默地转换为

,您将得到一个警告,如手册中的:

PHP 5.4开始字符串偏移量必须是整数或类整数字符串,否则将抛出警告。以前,像"foo"这样的偏移量被无声地强制转换为0

在PHP>=5.4的情况下,你会得到:

警告:非法字符串偏移'points'…

我觉得这个问题很有趣。

我有我自己的演练,这是结果。

$items定义如下:

$items = [
  0 => "foo",
  1 => "bar"
];

然后,进入foreach循环

foreach($items as $item) {
    $item['points'] = 100;
}

开头的$item包含一个字符串"foo"[]语法主要用于关联数组,因此它使我们误以为$item可能是一个数组,而事实并非如此。[]的一个不太为人所知的用法是通过[int]{int}表达式在字符串中获取/设置单个字符,正如@Rizier123在他的回答中指出的那样。例如,"string"[0]给出"s"。因此,下面的代码

$item['points'] = 100;

实际上与

相似
"foo"['points'] = 100;

现在,一个非整数值作为字符串的字符位置给出,会引发PHP警告,并且位置(这里是'points')将被强制转换为整数。

// Converting a string to integer:
echo intval('points'); // gives 0
结果,"foo"['points']"语句变成了"foo"[0],所以
"foo"[0] = 100;

现在是赋值部分。[]语法对单个字符进行操作。首先将数字100转换为字符串"100",然后只取出第一个字符进行赋值操作(=)。表达式现在类似于

"foo"[0] = "1"; // result: "1oo"

为了使事情变得有点扭曲,$item的修改值(即"1oo")没有被保留。这是因为$item不是一个参考。详见https://stackoverflow.com/a/9920684/760211

因此,就最终结果而言,所有前面的操作都可以忽略不计。$items在原始状态下是完整的。

现在,在最后一个循环中,我们可以看到$item['point']语句试图以错误的方式从字符串中读取一个字符。

foreach($items as $item) {
    echo $item['points']; //output: "fb"
}
echo "foo"[0]; // "f"
echo "boo"[0]; // "b"

您实际上并没有通过将$items作为$item来修改数组。$item是它自己的变量,所以在循环中打印时得到正确的输出是有意义的。

最新更新