在生活中,好多人疑惑PHP語言難不難呢?那麼,小編來解答PHP程式設計中10個最常見的錯誤,歡迎來閱讀!
錯誤1:foreach迴圈後留下懸掛指標
在foreach迴圈中,如果我們需要更改迭代的元素或是為了提高效率,運用引用是一個好辦法: $arr = array(1,2,3,4);
foreach($arr as&$value){ $value = $value *2; } // $arr is now
array(2, 4, 6, 8)這裡有個問題很多人會迷糊。
錯誤1:foreach迴圈後留下懸掛指標
在foreach迴圈中,如果我們需要更改迭代的元素或是為了提高效率,運用引用是一個好辦法:
A $arr=array(1,2,3,4);
foreach($arras&$value){
$value=$value*2;
}
// $arr is now array(2, 4, 6, 8)
這裡有個問題很多人會迷糊。迴圈結束後,$value並未銷燬,$value其實是陣列中最後一個元素的引用,這樣在後續對$value的使用中,如果不知道這一點,會引發一些莫名奇妙的錯誤:)看看下面這段程式碼:
$array=[1,2,3];
echoimplode(',',$array),"n";
foreach($arrayas&$value){}// by reference
foreach($arrayas$value){}// by value (i.e., copy)
上面程式碼的執行結果如下:
1,2,3
1,2,3
1,2,2
你猜對了嗎?為什麼是這個結果呢?
我們來分析下。第一個迴圈過後,$value是陣列中最後一個元素的引用。第二個迴圈開始:
第一步:複製$arr[0]到$value(注意此時$value是$arr[2]的引用),這時陣列變成[1,2,1]
第二步:複製$arr[1]到$value,這時陣列變成[1,2,2]
第三步:複製$arr[2]到$value,這時陣列變成[1,2,2]
綜上,最終結果就是1,2,2
避免這種錯誤最好的辦法就是在迴圈後立即用unset函式銷燬變數:
$arr=array(1,2,3,4);
$value=$value*2;
}
unset($value);// $value no longer references $arr[3]
錯誤2:對isset函式行為的錯誤理解
對於isset函式,變數不存在時會返回false,變數值為null時也會返回false。這種行為很容易把人弄迷糊。。。看下面的程式碼:
$data=fetchRecordFromStorage($storage,$identifier);
if(!isset($data['keyShouldBeSet']){
// do something here if 'keyShouldBeSet' is not set
}
寫這段程式碼的人本意可能是如果$data[‘keyShouldBeSet’]未設定,則執行對應邏輯。但問題在於即使$data[‘keyShouldBeSet’]已設定,但設定的值為null,還是會執行對應的邏輯,這就不符合程式碼的本意了。
下面是另外一個例子:
if($_POST['active']){
$postData=extractSomething($_POST);
}
// ...
if(!isset($postData)){
echo'post not active';
}
上
面的程式碼假設$_POST[‘active’]為真,那麼$postData應該被設定,因此isset($postData)會返回true。反之,上
面程式碼假設isset($postData)返回false的唯一途徑就是$_POST[‘active’]也返回false。
真是這樣嗎?當然不是!
即使$_POST[‘active’]返回true,$postData也有可能被設定為null,這時isset($postData)就會返回false。這就不符合程式碼的本意了。
如果上面程式碼的本意僅是檢測$_POST[‘active’]是否為真,下面這樣實現會更好:
}
// ...
}
判斷一個變數是否真正被設定(區分未設定和設定值為null),array_key_exists函式或許更好。重構上面的第一個例子,如下:
if(!array_key_exists('keyShouldBeSet',$data)){
// do this if 'keyShouldBeSet' isn't set
}
另外,結合get_defined_vars函式,我們可以更加可靠的檢測變數在當前作用域內是否被設定:
if(array_key_exists('varShouldBeSet',get_defined_vars)){
// variable $varShouldBeSet exists in current scope
}
錯誤3:混淆返回值和返回引用
考慮下面的程式碼:
classConfig
{
private$values=;
publicfunction getValues{
return$this->values;
}
}