|
php在开发效率很高,这是无可厚非的,但是却是在牺牲执行效率的。php数组功能非常强大,但是也要多加考虑,多试几种情况情况,以防万一,这里,就简单的说两个遇到的坑,以后如果有发现更多的,再补上吧! 1. foreach 提供了的简单方式,可以很方便的读取到数据或对象的内容,但是官方文档说了,由于 foreach 依赖内部数组指针,在循环中修改其值将可能导致意外的行为。所以,基本上, 1、不要想在循环内部修改里面的值,否则结果将超出你想要的; 2、使用'&'是一个安全的方式,虽然很少用到,但是在用到时,在引用结束后,应立即调用unset函数销毁该变量,否则,在接下来的代码里,如果有再次使用到此变量,那么循环的最后一次值就将被修改了,从而得到了意外的值,比如:在列表循环输出时,最后一行输出将会出现许多乱七八糟的值或者空值。使用unset可解决此问题。 我们来看个示例 <?php
/*-------------------------------------------------------------------------*/
/* foreach example 1: value only */
echo "foreach example 1: value only ".'<br />';
$a = array(1, 2, 3, 17);
foreach ($a as $v) {
echo "Current value of ".$a.":". $v."<br />";
}
?>
// 运行结果
foreach example 1: value only
Current value of $a: 1
Current value of $a: 2
Current value of $a: 3
Current value of $a: 172. ,其含义是检查前一个是否存在于后一个数组当中,而且大多数情况下,它也是这么工作的,但是当后面的数组是整数时,如array(0,1,2,3)时,就出问题了,php会将前的字符串进行intval,从而都会得到0这个值,那么如果恰巧,你的数组当中有这个值,那么等式就成立了,是不是又超出了预期呢?
所以,当确定后面的数据是整数时,尤其是还有可能为0(这个可能代替所有的字符串了),你就千万不能再使用这个函数了,可使用key_exists来代替,但是后面的数据则需要使用进行倒转操作了。 我们再来看个示例 function search($keyWord, $stack) {//此处判断是应该更新还是插入
foreach ($stack as $key => $val) {
if (in_array($keyWord, $val)) {
return TRUE;
}
}
return FALSE;
} 当一个字符串被当作数组来去取值时,又会发生什么呢?php是一门容错性很强的语言,它会尽量帮你改正错误,所以很聪明地将你的引用下标转化为整数,当然就得到0了,那么字符串下标为0取值则又会得到第一个字符串的值,是不是又超出了你的预期呢?解决方法是,在引用下标之前,还是确认一下这个变量是不是一个数组吧,is_array。 3. foreach中引用变量遇到的问题 写PHP好多年,但仍然会犯低级错误,今天遇到个 中引用时的问题,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>';
}
echo '<hr>';
print_r($arr);输出结果 开始看到第二个 foreach 输出的结果感觉很是莫名其妙,怎么会输出两个 d_d 呢?
仔细想了想,原来因为PHP foreach 中的 $a 的作用域是整个的局部变量,在外部仍然有效,而不是被封闭在循环内的, 所以当执行第二个foreach 时的 $a 并不是新的变量,而是仍然指向 $arr 第5个元素的地址引用, 当第二个 foreach 在循环时实际上是在不停的给 $arr 数组的第5个元素赋值, 具体赋值情况, 第一次:a_a 赋值给第5个元素, 结果为: [a_a, b_b, c_c, d_d,a_a] 第二次:b_b 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,b_b] 第三次:c_c 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,c_c] 第四次:d_d 赋值给第5个元素,结果为: [a_a, b_b, c_c, d_d,d_d] 第五次:此时因为第五个元素已经变成 d_d 又重新把 d_d 赋值给第5个元素,结果还是为: [a_a, b_b, c_c, d_d,d_d] 解决办法: 1.尽量不使用相同的循环; 2.每次使用完或再次使用前进行 unset($a); 处理,解除地址应用 还是用上面代码示例: $arr = ['a', 'b', 'c', 'd', 'e'];
foreach ($arr as $i=>&$a) {
$a = $a.'_'. $a;
echo $a .'<br>';
}
echo '<hr>';
echo $a;
echo '<hr>';
// 这里 unset 掉
unset($a);
echo $a = 'ccc';
echo '<hr>';
print_r($arr);
echo '<hr>';
foreach ($arr as $i=>$a) {
echo $a .'<br>';
}
echo '<hr>';
print_r($arr);输出结果: 现在就正常了,这些小细节一定要注意了。 |