2012-12-06 54 views
41

自PHP 5.4 html_entity_decode推出四款新的標誌,用最少的解釋html_entity_decode上的ENT_HTML5,ENT_HTML401,...修飾符是做什麼的?

ENT_HTML401 Handle code as HTML 4.01. 
ENT_XML1 Handle code as XML 1. 
ENT_XHTML Handle code as XHTML. 
ENT_HTML5 Handle code as HTML 5. 

我想了解什麼是他們的。在哪些情況下它們很重要?

我的猜測(但我可能是錯的)是,任何不同的標準,編碼一些不尋常的字符,但任何其他標準,所以爲了尊重他們,他們在這裏。

我的研究:htmlentities具有相同的最小解釋,沒有例子。我沒有運氣Google搜索。

+1

用例實際上非常簡單:使用適當的標誌,取決於您將該值放入哪個XML/HTML方言。這個問題歸結爲:HTML/XML方言轉義規則有什麼區別?這是一個很好的問題。 – deceze

+0

謝謝@deceze,在我的具體情況下,(因爲創作就是這樣)所聲明的和被審查的文本多次不匹配。我正在調查這些標誌,看看他們是否能夠以某種方式提供幫助。 –

回答

73

我開始想知道當我在htmlspecialchars頁面看到這些常量時,這些常量有什麼行爲。文檔是垃圾,所以我開始挖掘PHP的源代碼。

基本上,這些常量影響某些實體是否被編碼(或解碼爲html_entity_decode)。最明顯的影響是撇號(')是否編碼爲'(對於ENT_HTML401)或'(對於其他人)。同樣,它使用html_entity_decode確定是否解碼'。 ('始終解碼)。

所有用法可以在ext/standard/html.c及其頭文件中找到。從EXT /標準/ html.h:

#define ENT_HTML_DOC_HTML401   0 
#define ENT_HTML_DOC_XML1      16 
#define ENT_HTML_DOC_XHTML      32 
#define ENT_HTML_DOC_HTML5      (16|32) 

(由ENT_更換ENT_HTML_DOC_得到他們的PHP常量名)

我開始尋找這些常量的所有出現,並且可以共享的行爲如下ENT_*常量:

  • 它影響哪些數字實體將被解碼或不解碼。例如,對於ENT_HTML401ENT_XHTMLENT_XML1被解碼爲不可讀/無效字符。然而,對於ENT_HTML5,這被認爲是無效字符,因此它保持爲。 (C function unicode_cp_is_allowed
  • 隨着ENT_SUBSTITUTE啓用,無效的代碼單元,用於指定字符集與被替換序列。 (不取決於憑證類型!)
  • 啓用ENT_DISALLOWED後,對指定憑證類型不允許使用的代碼點替換爲。 (不依賴於字符集!)
  • 隨着ENT_IGNORE,從ENT_SUBSTITUTE相同的無效代碼單元序列被去除並且沒有替換完成(取決於「文檔類型」的選擇,例如ENT_HTML5
  • 不允許
ENT_HTML5line 976
  • ENT_XHTMLENT_HTML401共享實體映射。唯一的區別是,'將被轉換爲與ENT_XHTMLENT_HTML401不轉換它撇號(見this line
  • ENT_HTML401ENT_XHTML使用完全相同的實體地圖(減去前一個點的差異)。 ENT_HTML5使用它自己的地圖。其他(目前ENT_XML1)具有非常有限的解碼圖(>&<'"和它們的數字等同物)。 (見C function unescape_inverse_map
  • 註上一個點:當只有少量的實體必須進行轉義(想想htmlspecialchars),所有實體映射將使用相同的一個爲ENT_XML1,除了ENT_HTML401。那一個不會使用',而是'

這幾乎涵蓋了一切。我不打算列出所有的實體差異,而是我想指向https://github.com/php/php-src/tree/php-5.4.11/ext/standard/html_tables中的某些包含每種類型映射的文本文件。

我應該使用什麼ENT_ *爲用htmlspecialchars?

當使用htmlspecialchars與ENT_COMPAT(默認)或ENT_NOQUOTES時,選擇哪一個並不重要(見下文)。我看到這裏SO一些答案是歸結爲:

<input value="<?php echo htmlspecialchars($str, ENT_HTML5);?>" > 

這是不安全。它將覆蓋默認值ENT_HTML401 | ENT_COMPAT,它與HTML5實體的使用有所不同,但引號不再逃脫!另外,這是多餘的代碼。必須由htmlspecialchars編碼的實體是所有ENT_HTML401ENT_HTML5相同等

只需使用ENT_COMPATENT_QUOTES代替。後者也適用於使用撇號屬性(value='foo')。如果您只有兩個參數htmlspecialchars,請不要包含參數,因爲它是默認參數(ENT_HTML401爲0,請記住?)。

當您想打印的頁面上的東西(標籤之間,沒有屬性),它並沒有在所有哪一個你選擇,因爲它會具有同等效力關係。甚至可以使用ENT_NOQUOTES | ENT_HTML401等於數字值0

也見下文,約ENT_SUBTITUTE和ENT_DISALLOWED。

什麼ENT_ *應該用於htmlentities?

如果你的文本編輯器或數據庫是如此糟糕,你不能包含非US-ASCII字符(如UTF-8),你可以使用ヶ輛。否則,請保存一些字節並改爲使用htmlspecialchars(請參見上文)。

無論您需要使用ENT_HTML401ENT_HTML5還是其他內容都取決於您的網頁的投放方式。當您有HTML5頁面(<!doctype html>)時,請使用ENT_HTML5。 XHTML或XML?使用相應的ENT_XHTMLENT_XML1。如果沒有文檔或純文本格式的HTML4,請使用ENT_HTML401(這是省略時的默認設置)。

我應該使用ENT_DISALLOWED,ENT_IGNORE還是ENT_SUBSTITUTE?

默認情況下,刪除給定字符集無效的字節序列。要使用代替無效的字節序列,請指定ENT_SUBSTITUTE。 (請注意,&#FFFD;顯示爲非UTF-8字符集)。但是,如果指定了ENT_IGNORE,即使指定了ENT_SUBSTITUTE,也不會顯示這些字符。

文檔類型無效字符由當指定ENT_DISALLOWED上述相同的替換字符(或它的實體)取代。無論是否有ENT_IGNORE設置(與doctype的無效字符無關),都會發生這種情況。

+5

哇,PHP確實設法搞砸了這一個。雖然很好的答案! – Mahn

+1

請注意,雖然文檔不鼓勵使用ENT_IGNORE作爲安全隱患(http://php.net/manual/en/function.htmlspecialchars.php),但其他常量只能從PHP 5.4.0開始使用,而ENT_IGNORE是已經在PHP 5.3.0中。 – JeromeJ

相關問題