时间:2022-6-29来源:本站原创作者:佚名
点击进入免费获取进阶面试题、文档、视频资源

PHP语言让WEB端程序设计变得简单,这也是它能流行起来的原因。但也是因为它的简单,PHP也慢慢发展成一个相对复杂的语言,层出不穷的框架,各种语言特性和版本差异都时常让搞的我们头大,不得不浪费大量时间去调试。这篇文章列出了十个最容易出错的地方,值得我们去注意。易犯错误#1:在foreach循环后留下数组的引用还不清楚PHP中foreach遍历的工作原理?如果你在想遍历数组时操作数组中每个元素,在foreach循环中使用引用会十分方便,例如

$arr=array(1,2,3,4);foreach($arras$value){$value=$value*2;}//$arr现在是array(2,4,6,8)

问题是,如果你不注意的话这会导致一些意想不到的负面作用。在上述例子,在代码执行完以后,$value仍保留在作用域内,并保留着对数组最后一个元素的引用。之后与$value相关的操作会无意中修改数组中最后一个元素的值。

你要记住foreach并不会产生一个块级作用域。因此,在上面例子中$value是一个全局引用变量。在foreach遍历中,每一次迭代都会形成一个对$arr下一个元素的引用。当遍历结束后,$value会引用$arr的最后一个元素,并保留在作用域中这种行为会导致一些不易发现的,令人困惑的bug,以下是一个例子

$array=[1,2,3];echoimplode(,,$array),"\n";foreach($arrayas$value){}//通过引用遍历echoimplode(,,$array),"\n";foreach($arrayas$value){}//通过赋值遍历echoimplode(,,$array),"\n";

以上代码会输出

1,2,31,2,31,2,2

你没有看错,最后一行的最后一个值是2,而不是3,为什么?在完成第一个foreach遍历后,$array并没有改变,但是像上述解释的那样,$value留下了一个对$array最后一个元素的危险的引用(因为foreach通过引用获得$value)这导致当运行到第二个foreach,这个"奇怪的东西"发生了。当$value通过赋值获得,foreach按顺序复制每个$array的元素到$value时,第二个foreach里面的细节是这样的

第一步:复制$array[0](也就是1)到$value($value其实是$array最后一个元素的引用,即$array[2]),所以$array[2]现在等于1。所以$array现在包含[1,2,1]

第二步:复制$array[1](也就是2)到$value($array[2]的引用),所以$array[2]现在等于2。所以$array现在包含[1,2,2]

第三步:复制$array[2](现在等于2)到$value($array[2]的引用),所以$array[2]现在等于2。所以$array现在包含[1,2,2]

为了在foreach中方便的使用引用而免遭这种麻烦,请在foreach执行完毕后unset()掉这个保留着引用的变量。例如

$arr=array(1,2,3,4);foreach($arras$value){$value=$value*2;}unset($value);//$value不再引用$arr[3]

常见错误#2:误解isset()的行为尽管名字叫isset,但是isset()不仅会在变量不存在的时候返回false,在变量值为null的时候也会返回false。

这种行为比最初出现的问题更为棘手,同时也是一种常见的错误源。看看下面的代码:

$data=fetchRecordFromStorage($storage,$identifier);if(!isset($data[keyShouldBeSet]){//dosomethinghereifkeyShouldBeSetisnotset}

开发者想必是想确认keyShouldBeSet是否存在于$data中。然而,正如上面说的,如果$data[keyShouldBeSet]存在并且值为null的时候,isset($data[keyShouldBeSet])也会返回false。所以上面的逻辑是不严谨的。我们来看另外一个例子:

if($_POST[active]){$postData=extractSomething($_POST);}if(!isset($postData)){echopostnotactive;}

上述代码,通常认为,假如$_POST[active]返回true,那么postData必将存在,因此isset($postData)也将返回true。反之,isset($postData)返回false的唯一可能是$_POST[active]也返回false。然而事实并非如此!如我所言,如果$postData存在且被设置为null,isset($postData)也会返回false。也就是说,即使$_POST[active]返回true,isset($postData)也可能会返回false。再一次说明上面的逻辑不严谨。顺便一提,如果上面代码的意图真的是再次确认$_POST[active]是否返回true,依赖isset()来做,不管对于哪种场景来说都是一种糟糕的决定。更好的做法是再次检查$_POST[active],即:

if($_POST[active]){$postData=extractSomething($_POST);}//获取更多视频教程,
转载请注明原文网址:http://www.coolofsoul.com/phptx/phptx/24204.html

------分隔线----------------------------