PHP中使用foreach和引用导致程序BUG的问题介绍

foreach 循环实例用法
在PHP中的foreach是用来进行循环对一个数组的所有元素。作者的foreach基本语法如下:

 代码如下 复制代码

FOREACH ($array_variable as $value)
{
  [code to execute]
}

or

FOREACH ($array_variable as $key => $value)
{
  [code to execute]
}

在这两种情况下,多次[代码执行]将被处死是等于在$ array_variable数组元素的个数。

让我们来看一个例子。假设我们有下面的代码段:

 

 代码如下 复制代码
$array1 = array(1,2,3,4,5);
FOREACH ($array1 as $abc)
{
  print "new value is " . $abc*10 . "<br>";
}

输出结果

 代码如下 复制代码

new value is 10
new value is 20
new value is 30
new value is 40
new value is 50

上面是我们对foreach常常使用的方法,下面再看实例

 代码如下 复制代码

$a = array(1, 2);
$b = array(11, 12);
foreach($a as &$r){
}
foreach($b as $r){
}
echo $a[1]; // 输出 12

两个的循环的本意可能是: 第一个循环需要在循环中修改元素的内容, 所以使用引用; 但第二个循环只是把 $r 当作一个临时变量. 可是, 为什么 $a[1] 的值发生了改变呢?

当对 $a 的迭代完成后, $r 是 $a[1] 的引用, 改变 $r 的值, 就是改变 $a[1]. 这时, 你可以会奇怪, 代码中并没有修改 $r, 也没有修改 $a[1] 呀?

其实, foreach 是操作的是数组的拷贝, 所以, 后一个迭代相当于:

 代码如下 复制代码
for($i=0; $i<count($b); $i++){
$r = $b[$i]; // 修改了 $r! 相当于 $a[1] = $b[$i];
}

为了避免这种情况, 应该在第一个迭代之后, 执行

 代码如下 复制代码
unset($r);

从当前环境中删除 $r 这个变量(引用变量).

即使不是前面的例子, 在第一个迭代之后, 仍然十分可能再执行类似的语句:

 代码如下 复制代码
$r = 123;

循环变量一般是临时变量, 同一个变量名在代码不同的地方表示不同的东西, 但变量的作用域又存在于循环之外. 这就是这种作用域规则的坏处, 加上”变量不声明即使用”的坏外, 再加上变量无类型的坏处.

所以, 在 PHP 中使用引用变量, 应该在引用使用完之后, 应该 unset(). 所有变量在使用之前应该先 unset().

总结:

PHP 引用有些类似 C 语言指针, 但一些重要的特性和 C 语言指针不一样, 如果不注意, 会导致程序 BUG. foreach 操作的是数组或对象的拷贝, 但 PHP5, 可以使用引用操作对象元素本身

时间: 2024-08-30 09:54:48

PHP中使用foreach和引用导致程序BUG的问题介绍的相关文章

PHP中使用foreach和引用导致程序BUG的问题介绍_php技巧

复制代码 代码如下: $a = array(1, 2); $b = array(11, 12); foreach($a as &$r){ } foreach($b as $r){ } echo $a[1]; // 输出 12 两个的循环的本意可能是: 第一个循环需要在循环中修改元素的内容, 所以使用引用; 但第二个循环只是把 $r 当作一个临时变量. 可是, 为什么 $a[1] 的值发生了改变呢? 当对 $a 的迭代完成后, $r 是 $a[1] 的引用, 改变 $r 的值, 就是改变 $a[1

javaweb项目中jar包相互引用导致tomcat不能正常发布

问题描述 javaweb项目中jar包相互引用导致tomcat不能正常发布 现在做一个项目是用到结构如下: web项目 A 引用了普通java项目B,我在B里重写了Myservlet,结果两者都引用了j2ee.jar. 项目在tomcat发布时老是报"tomcat/webapps/testweb is locked"大体是这样. 想了解下在这种情况下,如何配置project

浅谈PHP中关于foreach使用引用变量的坑

写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: <?php $arr = ['a', 'b', 'c', 'd', 'e']; foreach ($arr as $i=>&$a) { $a = $a.'_'. $a; echo $a .'<br>'; } echo '<hr>'; foreach ($arr as $i=>$a) { echo $a .'<br>'; } e

在项目中添加对ASA .NET数据程序的引用

1.启动 Visual Studio .NET 并打开您的项目. 2.在 " 解决方案资源管理器 " 窗口中,右击 " 引用 " 文件夹,然后从弹出式菜单中选择 " 添加引用 ". 即显示 " 添加引用 " 对话框. 3.在 ".NET" 选项卡上,单击 " 浏览 " 找到iAnywhere.Data.AsaClient.dll.(缺省位置为\Program Files\Sybase\S

Android中引用其他程序的文本资源超简单方法

在Android中引用其他程序的文本资源并不是很常见,但是有时候还是很是有需要的,通常引用的多半是系统的程序的文本资源. 下面以一个超简单的例子,来展示以下如何实现. 复制代码 代码如下: public void testUseAndroidString() { Context context = getContext();     Resources res = null;     try {         //I want to use the clear_activities strin

Python中由于logging模块误用导致的内存泄露的解决方法

  Python中由于logging模块误用导致的内存泄露的解决方法         这篇文章主要介绍了解决Python中由于logging模块误用导致的内存泄露,针对由于过多的UDP连接所产生的问题,需要的朋友可以参考下 首先介绍下怎么发现的吧, 线上的项目日志是通过 logging 模块打到 syslog 里, 跑了一段时间后发现 syslog 的 UDP 连接超过了 8W, 没错是 8 W. 主要是 logging 模块用的不对 我们之前有这么一个需求, 就是针对每一个连接日志输出当前连接

深入解析php中的foreach问题

php4中引入了foreach结构,这是一种遍历数组的简单方式.相比传统的for循环,foreach能够更加便捷的获取键值对.在php5之 前,foreach仅能用于数组:php5之后,利用foreach还能遍历对象(详见:遍历对象).本文中仅讨论遍历数组的情况. foreach虽然简单,不过它可能会出现一些意外的行为,特别是代码涉及引用的情况下. 下面列举了几种case,有助于我们进一步认清foreach的本质.问题1: 复制代码 代码如下: $arr = array(1,2,3); fore

详解C++编程中向函数传递引用参数的用法_C 语言

引用类型的函数参数向函数传递引用而非大型对象的效率通常更高. 这使编译器能够在保持已用于访问对象的语法的同时传递对象的地址. 请考虑以下使用了 Date 结构的示例: // reference_type_function_arguments.cpp struct Date { short DayOfWeek; short Month; short Day; short Year; }; // Create a Julian date of the form DDDYYYY // from a G

深入解析php中的foreach问题_php技巧

前言:php4中引入了foreach结构,这是一种遍历数组的简单方式.相比传统的for循环,foreach能够更加便捷的获取键值对.在php5之前,foreach仅能用于数组:php5之后,利用foreach还能遍历对象(详见:遍历对象).本文中仅讨论遍历数组的情况. foreach虽然简单,不过它可能会出现一些意外的行为,特别是代码涉及引用的情况下.下面列举了几种case,有助于我们进一步认清foreach的本质.问题1: 复制代码 代码如下: $arr = array(1,2,3);fore