PHP-foreach的一些小坑
再PHP中,foreach是对数组遍历的一个方法,遍历也只用于数组,在编程的时候有一些小坑,记录如下。
foreach的两种语法结构
只遍历引用值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15foreach (array_expression as $value)
statement
//示例:
$arr = array(1, 2, 3, 4);
foreach ($arr as $value) {
echo $value;
}
echo "\n";
echo $value;
//显示结果:
1234
4遍历引用键和值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21foreach (array_expression as $key => $value)
statement
//示例:
$arr = array(1, 2, 3, 4);
foreach ($arr as $key => $value) {
echo "[$key] => $value\n";
}
echo "\n";
echo "[$key] => $value";
echo "\n";
//结果:
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[3] => 4
在foreach中是否使用&的区别:
不使用&,foreach的作用域只在当前循环中,不会改变外部数组的值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$arr = array(1, 2, 3, 4);
foreach ($arr as $value) {
$value = $value * 2;
echo "$value ";
}
echo "\n";
print_r($arr);
//结果:
2 4 6 8
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)使用&会使得作用域扩大到对应的数组,改变数组的值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
$value = $value * 2;
echo "$value ";
}
echo "\n";
print_r($arr);
//结果:
2 4 6 8
Array
(
[0] => 2
[1] => 4
[2] => 6
[3] => 8
)
在foreach中是否使用&的坑点:
这里和上面的作用域联系起来,没使用以后不会影响数组本身,所以两次foreach的结果互不影响:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$arr = array(1, 2, 3, 4);
foreach ($arr as $value) {
// $value = $value * 2;
echo "$value ";
}
echo "\n";
echo $value;
echo "\n";
foreach ($arr as $value) {
echo "$value ";
}
echo "\n";
echo $value;
//结果
1 2 3 4
4
1 2 3 4
4使用以后改变了作用域,这里&指向第一次foreach的最后一个地址,在PHP中它不会自动释放该地址:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
// $value = $value * 2;
echo "$value ";
}
echo "\n";
echo $value;
echo "\n";
foreach ($arr as $value) {
echo "$value ";
}
echo "\n";
echo $value;
//结果:
1 2 3 4
4
1 2 3 3
3查看它每次具体的变化:(这里可以验证每次改变的是&指向的最后一个地址)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {}
;
print_r($arr);
foreach ($arr as $key => $value) {
echo "{$key} => {$value} ";
print_r($arr);
}
//结果:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
0 => 1 Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 1
)
1 => 2 Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 2
)
2 => 3 Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 3
)
3 => 3 Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 3
)解决方法:在每次foreach后unset解除&的指定关系,或者在每次遍历中使用不同的变量名:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
echo "$value ";
}
unset($value);
echo "\n";
foreach ($arr as $value) {
echo "$value ";
}
//结果:
1 2 3 4
1 2 3 4
//使用不同的变量名
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
echo "$value ";
}
echo "\n";
foreach ($arr as $val) {
echo "$val ";
}
//结果:
1 2 3 4
1 2 3 4