谁能解释一下这段代码的输出?
为什么是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是它自己的变量,所以在循环中打印时得到正确的输出是有意义的。