PHP 易錯知識點整理

Sandy發表於2019-03-02

1. 注意echo和print的區別

PHP中echo和print都是輸出的作用,但是兩者之間還是有細微的差別。echo輸出後沒有返回值,但print有返回值,當其執行失敗時返回flase。因此可以作為一個普通函式來使用,例如執行$r = print “Hello World”; 變數$r的值將為1。而且程式碼中echo語句的執行效率要略快於print語句。

2. 注意空字串(“)和NULL的區別

PHP中空字串和NULL都是以值為0儲存的,但是他們的型別並不一樣,前者是string,而後者是NULL,可見字串(“)、NULL值相等但型別不等。

3. 分清==(等與)和===(全等與)的區別

兩者都屬於比較運算子,==(等於)只比較值是否相等,而===(全等於)則不但比較值是否相等,還會比較型別是否相等,它更為嚴格。

4. 分清include與require的區別

include()與require()的功能也基本相同,但在用法上也有一些不同,include()是有條件包含函式,而require()則是無條件包含函式。例如在下面程式碼中,如果變數$a為真,則將包含檔案a.php:
if($a){
include(“a.php”);
}
而require()則和include()不同,不管$a取何值,下面的程式碼都會把檔案a.php包含:
if($a){
require(“a.php”);
}
在錯誤處理方面,使用include語句,如果發生包含錯誤,程式將跳過include語句,雖然會顯示錯誤資訊但是程式還是會繼續執行。但是,requre語句會提示一個致命錯誤。

5. 注意isset和 empty的區別

empty是判斷一個變數是否為“空”,而isset則是判斷一個變數是否已經被設定。

6. 分清self :: 和 this–> 的區別

在訪問PHP類中的成員變數或方法時,如果被引用的變數或者方法被宣告成const(常量)或者static(靜態屬性),那麼就必須使用域操作符::,而如果被引用的變數或者方法沒有被宣告成const或者static,那麼就使用指向操作符->。

7. foreach迴圈後留下懸掛指標

  在foreach迴圈中,如果我們需要更改迭代的元素或是為了提高效率,運用引用是一個好辦法:

$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr is now array(2, 4, 6, 8)

  這裡有個問題很多人會迷糊。迴圈結束後,$value並未銷燬,$value其實是陣列中最後一個元素的引用,這樣在後續對$value的使用中,如果不知道這一點,會引發一些莫名奇妙的錯誤:)看看下面這段程式碼:

$array = [1, 2, 3];
echo implode(`,`, $array), "
";

foreach ($array as &$value) {} // by reference
echo implode(`,`, $array), "
";

foreach ($array as $value) {} // by value (i.e., copy)
echo implode(`,`, $array), "
";

  上面程式碼的執行結果如下:

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);
foreach ($arr as &$value) {
$value = $value * 2;
}
unset($value);
// $value no longer references $arr[3]

8.忽略Unicode/UTF-8問題

  php程式設計中,在處理非ascii字元時,會遇到一些問題,要很小心的去對待,要不然就會錯誤遍地。舉個簡單的例子,strlen($name),如果$name包含非ascii字元,那結果就有些出乎意料。在此給出一些建議,儘量避免此類問題:
如果你對unicode和utf-8不是很瞭解,那麼你至少應該瞭解一些基礎。推薦閱讀這篇文章。
最好使用mb_*函式來處理字串,避免使用老的字串處理函式。這裡要確保PHP的“multibyte”擴充套件已開啟。
資料庫和表最好使用unicode編碼。
知道jason_code()函式會轉換非ascii字元,但serialize()函式不會。
php程式碼原始檔最好使用不含bom的utf-8格式。
  在此推薦一篇文章,更詳細的介紹了此類問題: UTF-8 Primer for PHP and MySQL
  

相關文章