那些年咱们踩过的php坑(持续更新)

考虑一下代码输出结果:

$arr = array(555);
var_dump(in_array('555a', $arr));

按照常理理解,应该打印false
可实际的返回结果倒是bool(true)
缘由:php会强制的把字符串555a转为数字555,因此返回true

考虑以下代码的输出结果:
if(0 == 'had')
{
	echo "1";
}
else 
{
	echo "2";
}

初步一看,如此简单,固然输出2,其实结果输出为1
缘由:php字符串和数字比较时,会将字符串转化为数字进行比较,因此上面的结果had转为数字为0,因此返回1.
解决方法:===进行比较

考虑以下代码输出结果:
$a = array(
	1,
	2,
	3
);
foreach ($a as $v)
{
	echo current($a);
}
理论上输出应为23false,可实际结果倒是222
缘由:在第一次循环时,数组的指针指向下一个元素,获得的数组值为2,这个时候,php数组内部会复制一份临时的数组$tmp, $tmp的指针指向第二个元素,后续调用current($a),其实是取的临时数组$tmp的当前值,而$tmp的指针始终指向第二个元素,因此输出结果永远是2

考虑以下代码输出结果:
$a = array(
	1,
	2,
	3
);
foreach ($a as &$v)
{
	echo current($a);
}
跟上面的示例代码略有不一样,此时的$v使用了&引用
最终输出结果为23false
缘由:跟上面稍微不一样的是,使用引用不会复制一份临时的数组,因此循环时$a的指针将指向下一个元素

考虑以下代码结果:
$a = array(
	1,
	2,
	3
);
$a = $b;
foreach ($a as $v)
{
	echo current($a);
}
输出结果为:111
缘由:在遍历数组$a以前,数组已经发生了拷贝,此时拷贝的数组指针指向第一个元素,因此,因为遍历是使用的拷贝数组,因此结果输出为111

考虑以下代码结果:
$a = array(
	1,
	2,
	3
);
$a = &$b;
foreach ($a as $v)
{
	echo current($a);
}
输出结果为2,3,false
缘由:在遍历以前数组$a有引用,因此$a 的is_ref=1, 在有引用的时候,php遍历数组不会拷贝,因此最终结果为2,3,false



考虑以下代码输出:
$arr = array(
	1,
	2,
	3
);
foreach($arr as $k => &$v)
{
	$v = $v * 2;
}
foreach($arr as $k => $v)
{
	echo $v;
}

输出的最终结果为244,并非咱们期待的246
缘由:
第一个循环体中:
第1遍循环,因为$v是一个引用,所以$v = &$arr[0],$v=$v*2至关于$arr[0]*2,所以$arr变成2,2,3
第2遍循环,$v = &$arr[1],$arr变成2,4,3
第3遍循环,$v = &$arr[2],$arr变成2,4,6
那么在第一个循环体结束后$arr = array(2,4,6)

第二个循环体中:
第1遍循环,隐含操做$v=$arr[0]被触发,因为此时$v仍然是$arr[2]的引用,即至关于$arr[2]=$arr[0],$arr变成2,4,2
第2遍循环,$v=$arr[1],即$arr[2]=$arr[1],$arr变成2,4,4
第3遍循环,$v=$arr[2],即$arr[2]=$arr[2],$arr变成2,4,4
因此最终结果为244