PHP7.1与PHP5.6的版本中foreach的差异

时间:2020-01-09
本文章向大家介绍PHP7.1与PHP5.6的版本中foreach的差异,主要包括PHP7.1与PHP5.6的版本中foreach的差异使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

刚用指针解答一到算法题,联想到一些问题,在此记录

$arr = array( 1 => "start", 'wd' =>111, 3 => 333, "lz" => 4444, 55 =>"end" );

// foreach循环是通过指针的移动实现的遍历
foreach($arr as $key => $value){
    echo "<br />$key =>$value";
}
$k = key($arr);          // foreach结束后,指针的位置
$v = current($arr);      // foreach结束后,指针的位置所指向的值
$res = next($arr);       // foreach结束后,通过next()向下移动指针

echo "<br />此时(遍历之后),“位置”为:"; var_dump($k);
echo "<br />此时(遍历之后),对应“值”为:"; var_dump($v);
echo "<br />此时(遍历之后),指针移向相下一个位置 :"; var_dump($res);
exit;

PHP5.6的输出如下:

// $arr = array( 1 => "start", 'wd' =>111, 3 => 333, "lz" => 4444, 55 =>"end" );  // 参考原数组

1 =>start        // 键值对    
wd =>111            
3 =>333
lz =>4444
55 =>end

此时(遍历之后),“位置”为:NULL
此时(遍历之后),对应“值”为:bool(false)
此时(遍历之后),指针移向相下一个位置 :bool(false)

PHP7.1的输出如下:

1 =>start
wd =>111
3 =>333
lz =>4444
55 =>end
此时(遍历之后),“位置”为:int 1

此时(遍历之后),对应“值”为:string 'start' 

此时(遍历之后),指针移向相下一个位置 :int 111

区别

  • PHP5.6中数组遍历后,指针已经不在数组的有效范围内了。故此,执行各种操作都是NULL或false
  • PHP7.1中,遍历后指针又回到了数组的头部,故此可以继续执行指针操作。

再看是如何实现的

  • 抛开一切主观意识, 有两种实现可能,
    1、双向链表且有环,即首尾相连
    2、foreach之后通过reset()重置了指针的位置

  • 数组是双向链表这个都知道,那么是否有环呢?好像并没有确切的提过,通过实验即可知道。代码如下:

$arr = array( 1 => "start", 'wd' =>111, 3 => 333, "lz" => 4444, 55 =>"end" );
foreach($arr as $key => $value){
    echo "<br />$key =>$value";
}
$k = key($arr);
$v = current($arr);
$res = next($arr);
echo "<br />此时(遍历之后),“位置”为:"; var_dump($k);
echo "<br />此时(遍历之后),对应“值”为:"; var_dump($v);
echo "<br />此时(遍历之后),移向相下一个位置是否成功:"; var_dump($res);
$res = next($arr);  // 仅加入几行next()和一行输出,其他代码一样
$res = next($arr);
$res = next($arr);
$res = next($arr);
echo "<br />此时(next移动到数组尾端后),移向相下一个位置是否成功:"; var_dump($res);
exit;

PHP7.1输出如下

1 =>start
wd =>111
3 =>333
lz =>4444
55 =>end
此时(遍历之后),“位置”为:
D:\workspace\gitlab\water.service.klagri.com.cn\dev\index.php:10:int 1

此时(遍历之后),对应“值”为:
D:\workspace\gitlab\water.service.klagri.com.cn\dev\index.php:11:string 'start' (length=5)

此时(遍历之后),移向相下一个位置是否成功:
D:\workspace\gitlab\water.service.klagri.com.cn\dev\index.php:12:int 111

此时(next移动到数组尾端后),移向相下一个位置是否成功:
D:\workspace\gitlab\water.service.klagri.com.cn\dev\index.php:17:boolean false
  • 由结果可以看出来,next()到数组最后一个位置后,再进行next()返回false,说明了数组的底层虽然是双向链表,但并没有环,因为如果有环的话,就会回到第一个位置。
  • 同样,可以知道foreach后指针回到数组第一个位置,是由于foreach进行了优化,在遍历后进行了一次reset()操作。

原文地址:https://www.cnblogs.com/lz0925/p/12171331.html