深入详解PHP中的foreach
发布时间:2022-07-16 15:55:31 所属栏目:PHP教程 来源:互联网
导读:语言基础 foreach 语法结构提供了遍历数组的简单方式。 php5之前, foreach仅能用于数组 php5+, 利用foreach可以遍历对象 foreach仅能够应用于数据和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。 有两种语法: /* 遍历给定的
|
语言基础 foreach 语法结构提供了遍历数组的简单方式。 php5之前, foreach仅能用于数组 php5+, 利用foreach可以遍历对象 foreach仅能够应用于数据和对象,如果尝试应用于其他数据类型的变量,或者未初始化的变量将发出错误信息。 有两种语法: /* 遍历给定的 array_expression 数据。每次循环中, 当前单元的值被赋给$value并且数组内部的指针向前移一步(因此下次循环中将会得到下一个单元) */ foreach (array_expression as $value) { foreach (array_expression as $key => $value) : // statement endforeach; 还能够自定义遍历对象! 当foreach开始执行时, 数组内部的指针会自动指向第一个单元. 这意味着不需要在foreach循环之前调用reset()由于foreach依赖内部数组指针, 在循环中修改其值将可能导致意外的行为 可以很容易通过在 $value 之前加上 & 来修改数组元素. 此方法将以引用 赋值, 而不是拷贝一个值. <?php $arr = [1, 2, 3, 4]; foreach($arr as &$value) { $value = $value * 2; } // $arr is now [2, 4, 6, 8] unset($value); // 最后取消掉引用 $value的引用仅在被遍历的数组可以被引用时才可用(例如是个变量)。 以下代码无法运行: <?php /* 此段代码可以运行 运行结果: 1-2 2-4 3-6 4-8 */ foreach (array(1, 2, 3, 4) as &$value) { echo $value, '-'; $value = $value * 2; echo $value, PHP_EOL; } Warning: 数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。 Note: foreach 不支持用 @ 来抑制错误信息的能力 foreach 虽然简单, 不过它可能出现一些意外行为, 特别是代码涉及到引用的时候。 <?php $arr = [1, 2, 3]; foreach ($arr as $k => &$v) { $v = $v * 2; } foreach ($arr as $k => $v) { echo $v, PHP_EOL; } <?php foreach ($arr as $k => $v) { $k = currentKey(); $v = currentVal(); // 继续运行用户代码 } 根据上述理论, 现在我们重新来分析下第一个foreach: 循环 备注 $arr值 循环 1-1 由于$v是一个引用, 因此 $v = &$arr[0], $v = $v * 2 相当于 $arr[0] * 2 [2, 2, 3] 循环 1-2 $v = &$arr[1] [2, 4, 3] 循环 1-3 $v = &$arr[2] [2, 4, 6] 循环 2-1 隐含操作 $v = $arr[0] 被触发, 由于此时 $v 仍是 $arr[2] 的引用, 相当于 $arr[2] = $arr[0] [2, 4, 2] 循环 2-2 $v = $arr[1], 即$arr[2] = $arr[1] [2, 4, 4] 循环 2-3 $v = $arr[2], 即$arr[2] = $arr[2] [2, 4, 4] 如何解决此类问题呢? PHP手册上有一段提醒: Warning: 数组最后一个元素的 $value 引用在 foreach 循环之后仍会保留。建议使用 unset() 来将其销毁。 <?php $arr = [1, 2, 3]; foreach ($arr as $k => &$v) { $v = $v * 2; } unset($v); foreach ($arr as $k => $v) { echo $v, PHP_EOL; } <?php $arr = ['a', 'b', 'c']; foreach ($arr as $k => $v) { echo key($arr), "=>", current($arr), PHP_EOL; } foreach ($arr as $k => &$v) { echo key($arr), "=>", current($arr), PHP_EOL; } ➜ demo /usr/local/Cellar/php/7.2.7/bin/php -dvld.active=1 a.php Finding entry points Branch analysis from position: 0 Jump found. (Code = 77) Position 1 = 2, Position 2 = 15 Branch analysis from position: 2 Jump found. (Code = 78) Position 1 = 3, Position 2 = 15 Branch analysis from position: 3 Jump found. (Code = 42) Position 1 = 2 Branch analysis from position: 2 Branch analysis from position: 15 Jump found. (Code = 62) Position 1 = -2 Branch analysis from position: 15 filename: /Users/jianyong/demo/a.php function name: (null) number of ops: 17 compiled vars: !0 = $arr, !1 = $v, !2 = $k line #* E I O op fetch ext return operands ------------------------------------------------------------------------------------- 2 0 E > ASSIGN !0, <array> 4 1 > FE_RESET_R $4 !0, ->15 2 > > FE_FETCH_R ~5 $4, !1, ->15 3 > ASSIGN !2, ~5 5 4 INIT_FCALL 'key' 5 SEND_VAR !0 6 DO_ICALL $7 7 ECHO $7 8 ECHO '%3D%3E' 9 INIT_FCALL 'current' 10 SEND_VAR !0 11 DO_ICALL $8 12 ECHO $8 13 ECHO '%0A' 14 > JMP ->2 15 > FE_FREE $4 7 16 > RETURN 1 branch: # 0; line: 2- 4; sop: 0; eop: 1; out1: 2; out2: 15 branch: # 2; line: 4- 4; sop: 2; eop: 2; out1: 3; out2: 15 branch: # 3; line: 4- 5; sop: 3; eop: 14; out1: 2 branch: # 15; line: 5- 7; sop: 15; eop: 16; out1: -2 path #1: 0, 2, 3, 2, 15, path #2: 0, 2, 15, path #3: 0, 15, 0=>a 0=>a 0=>a (编辑:应用网_丽江站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |



浙公网安备 33038102330468号