在平常開發中,咱們常常碰到這樣的問題,即有些PHP問題看似簡單,一說就明,可是一到使用時就踩坑。好比,下面我所列的幾條:php
一、因爲使用單引號,以「 」爲分割符,使用PHP函數explode分割字符串,不能正常分割。html
緣由:這個涉及到單引號與雙引號的區別,在單引號中反斜槓不能被解析。所以,使用explode分割時,若是使用單引號, 會被看成字符串,而不是換行符,因此此時,不能正常分割。前端
相似問題還有字符串中包含{}的狀況。在字符串中,要想使使用了{}包含的變量成功解析,該字符串必須使用雙引號。linux
二、因爲BOM頭,使用PHP函數json_decode解析json字符串,不能解析成功。編程
緣由:UTF-8 編碼的文件能夠分爲無 BOM 和 BOM 兩種格式。何謂BOM? "EF BB BF" 這三個字節就叫BOM,BOM的全稱叫作"Byte Order Mard"。在utf-8文件中經常使用BOM來代表這個文件是UTF-8文件,而BOM的本意實在utf16中用來表示高低字節序列的。在字節流以前有 BOM表示採用低字節序列(低字節在前面),而utf8不用考慮字節序列,因此其實有無BOM均可以。UTF-8以字節爲編碼單元,沒有字節序的問題。 UTF-16以兩個字節爲編碼單元,在解釋一個UTF-16文本前,首先要弄清楚每一個編碼單元的字節序。例如收到一個「奎」的Unicode編碼是 594E,「乙」的Unicode編碼是4E59。若是咱們收到UTF-16字節流「594E」,那麼這是 「奎」仍是「乙」?json
若是文件保 存時,選擇了使用 BOM,會使頁面顯示不正常。通常來講,php是不支持有BOM的,php文件應該保存爲UTF-8無BOM類型,因此在保存 UTF8 編碼PHP文件時,不要使用 BOM。安全
三、因爲正反斜槓的緣由,PHP函數basename使用無效編程語言
咱們常用PHP函數basename,來從一個包含有指向一個文件的全路徑的字符串中獲取基本的文件名,可是因爲正反斜槓的緣由,有時你會發現basename函數沒法生效,特別是在window系統和linux系統中切換時。原來,basename函數受操做系統影響,用在 Windows 中,斜線(/)和反斜線()均可以用做目錄分隔符,而在其它環境下只能是斜線(/)。所以,若是你在window系統下使用的反斜線(),那到其餘系統時是有問題的。函數
爲避免此影響,最好都使用斜線(/)來做爲目錄分割符,對於使用了命名空間的狀況,最好先使用str_replace函數將反斜線()替換成斜線(/)。網站
四、trim系列函數的過多去除
trim函數的基本用法是去除最外邊的空格、換行符之類的。由於其可選參數,不少人也會將其用於去除UTF8BOM頭、文件擴展名等等,好比 ltrim($str, "\xEF\xBB\xBF"); rtrim($str, ".txt"); 。可是很快,就會發現這些函數會多去除了一些東西,好比原本是想去除後綴的,結果 logtext.txt 會變成了 logte 而不是 logtext。爲何呢?由於後面這個參數的意思不是一個完整字符串,而是字符列表,也就是說會一直檢查最左/最右是否符合此列表的其中一個。
五、htmlspecialchars 函數默認不轉義單引號
很多網站都是使用此函數做爲通用的輸入過濾函數,可是此函數默認狀況是不過濾單引號的。這是很是很是地容易形成XSS漏洞。這樣的作法和不過濾雙引號沒太大區別,只要前端寫得稍微有點不規範(用了單引號)就會中招。所以,咱們用的時候必定要給這個函數加上參數 htmlspecialchars( $data, ENT_QUOTES)
六、foreach的保留現象
使用 foreach($someArr as $someL){ } 之類的用法時,要注意最後的一個 $someL 會一直保留到該函數/方法結束。而當使用引用的時候 foreach($someArr as &$someL){ }這是以引用來保存,也就是說後面如有使用同一個名字的變量名,將會把原數據改變(就像一個亂用的C指針)。爲安全起見,建議每一個foreach(尤爲是引用的)結束以後都使用unset把這些變量清除掉。
七、小數(符點數)不能直接比較是否相等
好比 if( 0.5+0.2==0.7 ) 的結果是 false。究其緣由是由於,PHP是基於C語言的,而C語言因爲其二進制符點數的表示方式,致使不能精確表示大多數符點數。實際上,幾乎全部的編程語言都沒能精確表示小數(符點數),這是一個廣泛存在的現象,由於這個是 IEEE 754 的缺陷。想要解決此問題,只能另立標準,彷佛只有Mathematica解決了此問題。
八、字符串是否相同建議用 === 而非 ==
爲何呢?由於這個比較是弱類型。兩個比較時,PHP會先嚐試判別左右二者是否爲數字。而問題就在於什麼樣的字符串是數字,是單純的數字串嗎?遠遠不僅於此,還包括 0x 開頭的十六進制,XXeX類型的科學記數法 等等,如 '12e0'=='0x0C' 獲得的是true。而在數值類型與字符串比較時,甚至一些數字開頭的非數值串,好比 12=='12這個串' 獲得的值也會是 true。
因此這些狀況下,可能會使原本並不相同的字符串被斷定爲相等。而使用===比較則爲包含類型的比較,不會有任何轉換,因此是能夠準確比較字符串是否相同的。
另外吐槽一下JAVA,==竟然比較不了字符串是否相等,由於字符串是一個對象,==變成了判斷是否爲同一個對象……
九、不能把switch中的case看成if來使用
在PHP函數switch……case中,switch 匹配的是case語句的值,而不能把case當if用。同時,switch表達式優先匹配與其值類型一致的case語句,類型不一致的放在後面處理,以下:
十、strrchr函數是查找某個字符,而不是查找字符串
在PHP手冊上strrchr() 函數的解釋是查找字符串在另外一個字符串中最後一次出現的位置,並返回從該位置到字符串結尾的全部字符。若是成失敗,不然返回 false。實際上,這個函數是查找某個字符,而不是查找字符串。以下示例,不少人一開始確定覺得返回false,但實際上並非。
上面示例說明,若是$b是字符串,只使用第一個字符,後面的其它字符會忽略。