嗯,因為是純小白,這個問題可能有點菜,各位大神見諒……
就是在寫php時,需要echo特殊字元,比如"這個符號,寫入php時是用轉義\"好還是用html代碼
"好呢?
請教各位,謝謝!
謝謝各位!已經大致明白了,非常感謝各位的耐心解答!
PS.php大神果然不一樣,回答都是那麼的詳細~~在此感謝了!
回複內容:
嗯,因為是純小白,這個問題可能有點菜,各位大神見諒……
就是在寫php時,需要echo特殊字元,比如"這個符號,寫入php時是用轉義\"好還是用html代碼"好呢?
請教各位,謝謝!
謝謝各位!已經大致明白了,非常感謝各位的耐心解答!
PS.php大神果然不一樣,回答都是那麼的詳細~~在此感謝了!
要明白哪個好的話首先我們就要搞清楚兩者之間的區別:
使用轉義的話就是相當於輸出原字元,既然特殊字元原字元輸出了的話就必須和頁面的編碼方式和瀏覽器的編碼方式有關係。如果頁面的編碼(如GBK)中不包含該特殊字元的話,或者瀏覽器的編碼方式不包含該特殊字元的話,就會出現亂碼。
你所說的HTML代碼的正統名字叫做HTML 字元實體,英文名字叫做HTML Entities。使用字元實體的話瀏覽器會自己將代碼轉換為正確的字元,就少了對編碼方式的要求。關於字元實體的內容你可以多看看這些頁面:HTML 字元實體 | HTML Entities
總結來說,使用轉義的話方便書寫和閱讀,但是對頁面的編碼方式有要求。使用HTML字元實體雖然少了編碼方式的顯示,但是不便於書寫和閱讀源碼。所以我個人的建議是例如"這種稍微福士平常一點的字元還是轉義輸出比較好,而特殊的,可以獨立於頁面的特殊字元(如 等)則使用字元實體的形式表現。字元實體這塊雖然使用實體號來寫會有更大的相容性,但是個人傾向於用字元實體的名稱,原因還是方便閱讀。
轉義和轉義不一樣
感性的來看,但凡在字串本身當中,出現包裹字串的分隔字元(或其他直接使用有特殊意義的字元),都必須轉義。但是不同的語言的轉義,雖然目的一致,但要轉的東西往往完全不同。
“轉義\"好還是用html代碼"好”?前者是PHP字串的轉義,後者是HTML語言的轉義。使用場合都不同,所以千萬不要混為一談——完全不是等價討論的概念。
題主問題中,前者使用的PHP字串轉義,就是雙引號包裹的字串當中,允許轉義\"="、\n=LF(0x0A)等字元。後者涉及的HTML轉義就是用HTML實體(HTML Entities)表示字元,比如&=&。
什麼轉義都不能省略
PHP的轉義不能省略,不用多說(多數時候,不轉義明顯解析出錯啊!)
但這裡的問題是:PHP = Hypertext Preprocessor,PHP的輸出就是HTML頁面。在PHP中寫的字串常量,經常送給瀏覽器的HTML解析器。題主問的問題也是如此。
所以必須明確:題主的需求很可能涉及二次轉義:先寫出合法的PHP字串常量,然後保證瀏覽器解析HTML後,輸出的仍然是字串的原樣,而不會:
- 特殊字元失效
- 破壞HTML DOM結構
- 被注入代碼,產生安全問題
PHP和HTML,兩個的轉義都是不能省略的。題主問題的結論是:前者只做了PHP的轉義,這個放在HTML本文中可以,但放在標籤的屬性值裡不行。後者是做了HTML的轉義,而PHP無需轉義(視同已轉義),OK。但重要的是:要知道“為什麼”可以,而不是亂試最後“湊巧”可以。
我贊成的做法
雖然第二種可以,但我認為echo '"';這絕對是一種極其不良的實踐。如果評一個“PHP最差編程習慣”,這個絕對有上榜的實力。
因為PHP先構造字串,再處理成HTML的格式輸出,這是一個有先後順序的需求。如果直接把HTML實體寫在PHP的字串常量裡,那就是把兩個階段轉義的邏輯混雜在了一起。
在PHP中我比較贊成的方法,是將字串的內容保持原樣,在輸出之前用htmlentities或htmlspecialchars函數包裹之:(注意這兩個函數略有區別,網上資料很多)
header("Content-Type: text/html; charset=utf-8");echo htmlentities("\"M&M\""); # 顯示:"M&M" 查看原始碼:"M&M"
這樣,寫原始碼的時候只需關心PHP的邏輯。最後由機器保證前台的輸出,和字串本身一致。
你可能總會在網上見到莫名其妙的真的出現一個“&”的情況——這就是不單點轉義,而是把轉義過程自以為是的到處亂放,最終造成重複做兩遍HTML轉義的錯誤。
資料可能到處輸出,但資料的原樣只有一個。不要把資料的原貌混雜到自己都認不清,這也很重要。
如何對付特殊符號?
對付等特殊符號,以及中文等涉及編碼方式的地方,我和 @怡紅公子 的看法是不太一致的。我的想法是:
- 出現任何特殊符號,都真的原樣寫到字串中去。中文也一樣。
- 轉義仍然使用htmlentities來做。
- PHP檔案儘可能使用UTF-8無BOM格式儲存。
- 如果輸出的編碼不是UTF-8,則在HTML轉義的後邊,再加一層iconv轉換。
因為我認為轉義和編碼方式還是一個事情的兩個階段,不宜混在一起談。這個模型就像俄羅斯套娃一樣,安裝者一定是先裝小的再套大的,而拆解者必然是先拆外邊再拆裡邊。以GBK為例的邏輯就是:
- 先有原資料。——
公司"2014"
- 做成PHP的字串常量。——
"公司\"2014\"" 以這個樣子寫進PHP指令檔中
- 轉義HTML實體。——
©公司"2014" 此處PHP知道:字串中有這些字元,這就行了,內部應該是Unicode存的但是我們可以不關心
- 轉成GBK編碼。——
©+B9ABCBBE+"2014"中間的一段是4個位元組的GBK碼原始值
- 瀏覽器解開GBK編碼:——
©公司"2014"
- 再解開HTML實體————
公司"2014"
- 原樣輸出。
去掉編碼,無非就是去掉了步驟4和5,和轉義一點關係都不涉及到。
輸出HTML的東西都必須轉義(空格-> )。
永遠不要相信一切輸入。