我開始想知道當我在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_HTML401
和ENT_XHTML
和ENT_XML1
,
被解碼爲不可讀/無效字符。然而,對於ENT_HTML5
,這被認爲是無效字符,因此它保持爲
。 (C function unicode_cp_is_allowed)
- 隨着
ENT_SUBSTITUTE
啓用,無效的代碼單元,用於指定字符集與�
被替換序列。 (不取決於憑證類型!)
- 啓用
ENT_DISALLOWED
後,對指定憑證類型不允許使用的代碼點替換爲�
。 (不依賴於字符集!)
- 隨着
ENT_IGNORE
,從ENT_SUBSTITUTE
相同的無效代碼單元序列被去除並且沒有替換完成(取決於「文檔類型」的選擇,例如ENT_HTML5
) - 不允許

爲ENT_HTML5
( line 976) ENT_XHTML
與ENT_HTML401
共享實體映射。唯一的區別是,'
將被轉換爲與ENT_XHTML
而ENT_HTML401
不轉換它撇號(見this line) ENT_HTML401
和ENT_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_HTML401
,ENT_HTML5
相同等
只需使用ENT_COMPAT
或ENT_QUOTES
代替。後者也適用於使用撇號屬性(value='foo'
)。如果您只有兩個參數htmlspecialchars
,請不要包含參數,因爲它是默認參數(ENT_HTML401
爲0,請記住?)。
當您想打印的頁面上的東西(標籤之間,沒有屬性),它並沒有在所有哪一個你選擇,因爲它會具有同等效力關係。甚至可以使用ENT_NOQUOTES | ENT_HTML401
等於數字值0
。
也見下文,約ENT_SUBTITUTE和ENT_DISALLOWED。
什麼ENT_ *應該用於htmlentities?
如果你的文本編輯器或數據庫是如此糟糕,你不能包含非US-ASCII字符(如UTF-8),你可以使用ヶ輛。否則,請保存一些字節並改爲使用htmlspecialchars(請參見上文)。
無論您需要使用ENT_HTML401
,ENT_HTML5
還是其他內容都取決於您的網頁的投放方式。當您有HTML5頁面(<!doctype html>
)時,請使用ENT_HTML5
。 XHTML或XML?使用相應的ENT_XHTML
或ENT_XML1
。如果沒有文檔或純文本格式的HTML4,請使用ENT_HTML401
(這是省略時的默認設置)。
我應該使用ENT_DISALLOWED,ENT_IGNORE還是ENT_SUBSTITUTE?
默認情況下,刪除給定字符集無效的字節序列。要使用�
代替無效的字節序列,請指定ENT_SUBSTITUTE
。 (請注意,&#FFFD;
顯示爲非UTF-8字符集)。但是,如果指定了ENT_IGNORE
,即使指定了ENT_SUBSTITUTE
,也不會顯示這些字符。
爲文檔類型無效字符由當指定ENT_DISALLOWED
上述相同的替換字符(或它的實體)取代。無論是否有ENT_IGNORE
設置(與doctype的無效字符無關),都會發生這種情況。
用例實際上非常簡單:使用適當的標誌,取決於您將該值放入哪個XML/HTML方言。這個問題歸結爲:HTML/XML方言轉義規則有什麼區別?這是一個很好的問題。 – deceze
謝謝@deceze,在我的具體情況下,(因爲創作就是這樣)所聲明的和被審查的文本多次不匹配。我正在調查這些標誌,看看他們是否能夠以某種方式提供幫助。 –