简单了解PHP编程中数组的指针的使用


Posted in PHP onNovember 30, 2015

要使用数组中的元素,就需要数组的定位。定位的实现需要借助数组指针来完成。PHP中有很多函数可以移动数组指针。下面将给大家介绍几个。

将指针移动到下一个数组位置next()

next()函数返回紧接着放在当前数组指针下一个位置的数组值。其形式如下:

mixed next(array array)

以下是一个例子:

$fruits = array("apple", "banana", "orange", "pear");

echo next($fruits);

echo next($fruits);

// banana

// orange

还可以将指针前移,也可以直接移动到数组的开始和结尾位置。

将指针移动到前一个数组位置prev()

prev()函数返回位于当前指针前一个位置的数组值,如果指针本来就位于数组的第一个位置,则返回false。其形式如下:

mixed prev(array array)

prev()的用法与next()相同,例子就省略了。

将指针移到第一个数组位置reset()

reset()函数用于将数组指针设置回数组的开始位置。其形式如下:

mixed reset(array array)

如果需要在脚本中多次查看或处理一个数组,就经常使用这个函数,另外这个函数还经常在排序结束时使用。

将指针移动到最后一个数组位置end()

end()函数将指针移动到数组的最后一个位置,将返回最后一个元素。其形式如下:

mixed end(array array)

下面的例子展示了如果获取第一个和最后一个数组值:

$fruits = array("apple", "banana", "orange", "pear");

echo current($fruits);

echo end($fruits);

// apple

// pear

对于数组作为参数在函数间传递时又存在这样一个规律:我们知道,函数调用时,系统会将实参copy一份赋值给形参(引用调用除外),而对于数组,不仅仅 copy了实参的值,而且还copy了实参数组当前内部指针的位置。如果实参内部指针的位置指向了数组末尾,那么系统会将形参的内部指针重置,指向形参数 组的第一个单元;如果实参内部指针的位置不在数组末尾,即指向了有效的单元,那么系统会将形参的数组指针位置与实参的数组指针指向值相同的数组单元。

如果不做 $arr['var6'] = 6 这一步操作,6个变量($var1-$var6)都将有值,因为在each之后,数组指针已经指向了数组的末尾,那么在调用函数 func()时,系统会重置 $arrtmp的数组指针,将其指向第一个元素。但是在进行 $arr['var6'] = 6这步操作之后,一切就改变了,这一个操作让$arr的数组指针由原来指向一个NULL变成了一个有效值(说明一下,赋值前后,数组指针指向的地址单元一 直是没有变化的,只不过是赋值前,那个地址单元什么也没有,而赋值之后变成了6)。这就使得$arr的数组指针指向了一个有效的单元,那么在调用函数 func()时,系统是不会重置$arrtmp的数组指针的,$arrtmp的数组指针将会跟$arr的数组指针一样,指向他自己的最后一个单元。而 each函数又是从当前数组指针的位置开始工作的。因此each函数操作的第一个结果的返回值就是数组$arrtmp的最后一个元素了,它将数组指针再向下移动一位,while循环到此结束,因此$arrtmp['var1']-$arrtmp['var5']都没有被遍历到,最终导致$var1-$var6为NULL。

数组在赋值的过程中,赋值数组和被赋值数组各自数组指针的变化情况。 先给出一条结论,然后我们在用代码来证明这个结论吧。$arrtmp=$arr;在这个赋值表达式中我把$arr叫做赋值数组,把$arrtmp叫做被赋值数组。数 组在赋值时,如果赋值数组的数组指针已经指向了数组末尾,则赋值之后赋值数组的数组指针会被重置,指向数组第一个元素;如果在赋值时,赋值数组的数组指针 没有指向数组末尾,而是指向了任何一个有效的数组元素,那么在赋值之后赋值数组的数组指针是不会被重置的,而是保留其原来指向的元素。在赋值之后,被赋值 数组不仅有了赋值数组的值,而且赋值数组的数组指针指向了那个元素,被赋值的数组也会指向自己中值相同的那个元素。

demo1:

<?php
 $arr = array('var1'=>1,'var2'=>2,'var3'=>3,'var4'=>4,'var5'=>5);
 while( list($key,$value) = each($arr) )
 {
 if($value == 4) break;
 }
 var_dump(current($arr));
 
 $arr1 = $arr;
 
 var_dump(current($arr));
 var_dump(current($arr1));
?>

demo1 的执行结果是:int(5) int(5) int(5) 。从这个结果可以看出,赋值前后$arr的数组指针位置没有发生任何变化,$arr1不仅值跟$arr相同,而且数组指针所指向的元素值也是相同的。现在 用上述结论来解释这个结果,在while循环中,有一个if判断语句,目的是不让$arr的数组指针指向数组末尾,而是保留在一个有效的位置。 在$value=4时会跳出循环,而each这个函数会将数组指针向前移动一位,这就导致了$arr的数组指针指向了第5个元素,所以在赋值之 前,current($arr)的结果是5,赋值之后,由于在赋值之前$arr的当前指针并没有指向末尾,因此在赋值之后不会将$arr的数组指针进行重 置,而是保留了其原有的位置,因此在赋值之后使用current($arr)的结果仍然是5。赋值时$arr1不仅获得了$arr的值,而且数组指针指向 的元素和$arr的相同,二者都是5。

<?php
$arr = array('var1'=>1,'var2'=>2,'var3'=>3,'var4'=>4,'var5'=>5);
while( list($key,$value) = each($arr) )
{
  //if($value == 4) break;
}
var_dump(current($arr));
$arr1 = $arr;
var_dump(current($arr));
var_dump(current($arr1));
?>

demo2中我们将 if($value == 4) break; 这一句注释掉了,目的很简单,就是通过each将$arr的数组指针位置指向数组末尾。

demo2 的执行结果:bool(false) int(1) bool(false) 。如果数组指针对应的元素为0,"",或者不是一个有效的值时,current函数会返回false,$arr的值中没有为0或者""的情况,因此可以断 定是因为数组指针指向了一个无效的元素而导致current返回了一个false。换句话说就是可以确定在while循环完成之后,$arr的数组指针已 经指向了数组的末尾。所以我们看到在赋值之前current($arr)的值是false,而赋值之后current($arr)的值变成了1,说明赋值 之后$arr的数组指针被重置了,指向了数组的第一个元素。current($arr1)的值为false,说明赋值之后$arr1让然保留了赋值之 前$arr的数组指针指向的元素。

通过demo1和demo2就可以证明上述结论了。

因此为了在遍历数组时不受数组指针的影响,最好在使用each()函数之前或者之后调用函数reset()将数组指针重置。这样就可以避免上述问题的发生了。另外还有一个操作数组指针的函数prev(),它的作用是将数组指针当前的位置后退一位,它也需要注意一点,就是如果数组指针已经指向数组末尾,那么使它就得不到想要的结果了。

顺便说一下foreach这个函数,使用foreach函数来遍历数组时,它会重置数组指针,将其指向数组的第一个元素。必须注意的是foreach操作的对象是对你要遍历的数组的copy值,而不是遍历数组本身。

PHP 相关文章推荐
PHP日期时间函数的高级应用技巧
May 16 PHP
PHP session有效期session.gc_maxlifetime
Apr 20 PHP
php下利用curl判断远程文件是否存在的实现代码
Oct 08 PHP
基于php验证码函数的使用示例
May 03 PHP
thinkphp实现面包屑导航(当前位置)例子分享
May 10 PHP
php使用ereg验证文件上传的方法
Dec 16 PHP
迪菲-赫尔曼密钥交换(Diffie?Hellman)算法原理和PHP实现版
May 12 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
Aug 16 PHP
php代码架构的八点注意事项
Jan 25 PHP
php实现背景图上添加圆形logo图标的方法
Nov 17 PHP
解决PHP上传非标准格式的图片pjpeg失败的方法
Mar 12 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
Jun 20 PHP
PHP 微信支付类 demo
Nov 30 #PHP
PHP CURL或file_get_contents获取网页标题的代码及两者效率的稳定性问题
Nov 30 #PHP
php curl抓取网页的介绍和推广及使用CURL抓取淘宝页面集成方法
Nov 30 #PHP
PHP curl模拟登录带验证码的网站
Nov 30 #PHP
PHP可变函数学习小结
Nov 29 #PHP
PHP可变变量学习小结
Nov 29 #PHP
PHP中对数组的一些常用的增、删、插操作函数总结
Nov 27 #PHP
You might like
php 用checkbox一次性删除多条记录的方法
2010/02/23 PHP
20个PHP常用类库小结
2011/09/11 PHP
typecho插件编写教程(六):调用接口
2015/05/28 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
php给数组赋值的实例方法
2019/09/26 PHP
Javascript打印网页部分内容的脚本
2008/11/17 Javascript
jquery 实现的全选和反选
2009/04/15 Javascript
利用JQuery为搜索栏增加tag提示
2009/06/22 Javascript
Mootools 1.2教程 同时进行多个形变动画
2009/09/15 Javascript
把jquery 的dialog和ztree结合实现步骤
2013/08/02 Javascript
jquery实现省市select下拉框的替换(示例代码)
2014/02/22 Javascript
jQuery插件pagination实现分页特效
2015/04/12 Javascript
jQuery实现首页顶部可伸缩广告特效代码
2015/04/15 Javascript
浅谈javascript的Touch事件
2015/09/27 Javascript
jQuery实用技巧必备(下)
2015/11/03 Javascript
jQuery EasyUI中的日期控件DateBox修改方法
2016/11/09 Javascript
JavaScript仿微博输入框效果(案例分析)
2016/12/06 Javascript
浅谈React Native 中组件的生命周期
2017/09/08 Javascript
pm2 部署 node的三种方法示例
2017/10/20 Javascript
微信小程序缓存过期时间的使用详情
2019/05/12 Javascript
JS/jQuery实现超简单的Table表格添加,删除行功能示例
2019/07/31 jQuery
在vue项目中promise解决回调地狱和并发请求的问题
2020/11/09 Javascript
使用Python进行稳定可靠的文件操作详解
2013/12/31 Python
Python实现的数据结构与算法之双端队列详解
2015/04/22 Python
详解Python中expandtabs()方法的使用
2015/05/18 Python
Python使用ffmpy将amr格式的音频转化为mp3格式的例子
2019/08/08 Python
djano一对一、多对多、分页实例代码
2019/08/16 Python
python并发编程多进程 模拟抢票实现过程
2019/08/20 Python
django自带serializers序列化返回指定字段的方法
2019/08/21 Python
Python 实现向word(docx)中输出
2020/02/13 Python
Happy Plugs官网:瑞典无线耳机品牌
2020/07/16 全球购物
大学本科毕业生求职信范文
2013/12/18 职场文书
2014年化工厂工作总结
2014/11/25 职场文书
行政文员岗位职责
2015/02/04 职场文书
2016年离婚协议书范文
2016/03/18 职场文书
Win11右下角图标点了没反应怎么办?Win11点击右下角图标无反应解决方法汇总
2022/07/07 数码科技