web-dev-qa-db-ja.com

html_entity_decodeのENT_HTML5、ENT_HTML401、...修飾子は何をしますか?

PHP 5.4以降html_entity_decodeは、最小限の説明で4つの新しいフラグを導入します

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にも同じ最小限の説明があり、例もありません。私は運が悪いとググった。

52
Luis Siquot

これらの定数をhtmlspecialcharsページで見たとき、私はこれらの定数がどのような振る舞いをするのか疑問に思い始めました。ドキュメントがゴミだったので、PHPのソースコードを掘り始めました。

基本的に、これらの定数は、特定のエンティティがエンコードされているかどうか(またはhtml_entity_decodeに対してデコードされているかどうか)に影響します。最も明白な効果は、アポストロフィ(')が'ENT_HTML401の場合)または'(その他の場合)にエンコードされているかどうかです。同様に、'を使用するときにhtml_entity_decodeがデコードされるかどうかを決定します。 ('は常にデコードされます)。

すべての使用法はext/standard/html.cとそのヘッダーファイルにあります。 ext/standard/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_HTML_DOC_ENT_に置き換えて、PHP定数名を取得します)

私はこれらの定数のすべての出現を探し始め、ENT_*定数の動作について以下を共有できます。

  • どの数値エンティティがデコードされるかどうかに影響します。たとえば、は、ENT_HTML401、およびENT_XHTMLENT_XML1の読み取り不可または無効な文字にデコードされます。ただし、ENT_HTML5の場合、これは無効な文字と見なされるため、のままになります。 ( C関数unicode_cp_is_allowed
  • ENT_SUBSTITUTEを有効にすると、無効なコード単位シーケンス指定された文字セットの場合に置き換えられます。 (ドキュメントの種類には依存しません!)
  • ENT_DISALLOWEDを有効にすると、コードポイント指定されたドキュメントタイプでは許可されませんに置き換えられます。 (文字セットには依存しません!)
  • ENT_IGNOREを使用すると、ENT_SUBSTITUTEからの同じ無効なコードユニットシーケンスが削除され、置き換えは行われません(「ドキュメントタイプ」の選択に応じて、たとえばENT_HTML5
  • 
ENT_HTML5を許可しない( 976行目
  • ENT_XHTMLENT_HTML401とエンティティマップを共有します。唯一の違いは、'ENT_XHTMLでアポストロフィに変換されますが、ENT_HTML401は変換しません( この行 を参照)。
  • ENT_HTML401ENT_XHTMLは、まったく同じエンティティマップを使用します(前のポイントとの差を差し引いたもの)。 ENT_HTML5は独自のマップを使用します。その他(現在ENT_XML1)のデコードマップは非常に限られています(>&<'"およびそれらに相当する数値) 。 ( C関数unescape_inverse_map を参照)
  • 前の点に注意してください:エスケープする必要があるエンティティが少ない場合(htmlspecialcharsと考えると)、ENT_XML1を除いて、すべてのエンティティマップはENT_HTML401と同じものを使用します。それは'ではなく'を使用します。

それはほとんどすべてをカバーします。すべてのエンティティの違いをリストするつもりはありませんが、代わりに https://github.com/php/php-src/tree/php-5.4.11/ext/standard/html_tables をポイントしたいと思います。 =各タイプのマッピングを含む一部のテキストファイル。

HtmlspecialcharsにはどのENT_ *を使用すればよいですか?

ENT_COMPAT(デフォルト)またはENT_NOQUOTESでhtmlspecialcharsを使用する場合、どれを選択してもかまいません(以下を参照)。私はここでいくつかの答えを見ましたSOこれは要約すると:

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

これはinsecureです。デフォルト値ENT_HTML401 | ENT_COMPATをオーバーライドします。これには、HTML5エンティティが使用されるという違いがありますが、引用符はエスケープされなくなりますalso!さらに、これは冗長なコードです。 htmlspecialcharsでエンコードする必要があるエンティティは、すべてのENT_HTML401ENT_HTML5などで同じです。

代わりにENT_COMPATまたはENT_QUOTESを使用してください。後者は、属性(value='foo')にアポストロフィを使用する場合にも機能します。 htmlspecialcharsの引数が2つしかない場合は、その引数がデフォルトであるため、含めないでください(ENT_HTML401は0です。覚えていますか?)。

ページ上(属性間ではなくタグ間)に何かを印刷する場合は、どちらを選択しても問題はありません。効果は同じです。数値ENT_NOQUOTES | ENT_HTML401に等しい0を使用するだけでも十分です。

ENT_SUBTITUTEおよびENT_DISALLOWEDについては、以下も参照してください。

HTMLエンティティにはどのENT_ *を使用すればよいですか?

テキストエディターまたはデータベースが非常に不安定で、US-ASCII以外の文字(UTF-8など)を含めることができない場合は、htmlentitiesを使用できます。それ以外の場合は、バイトをいくつか節約し、代わりにhtmlspecialcharsを使用します(上記を参照)。

ENT_HTML401ENT_HTML5などを使用する必要があるかどうかは、ページの配信方法によって異なります。 HTML5ページ(<!doctype html>)がある場合は、ENT_HTML5を使用します。 XHTMLまたはXML?対応するENT_XHTMLまたはENT_XML1を使用します。 doctypeまたはプレーンなHTML4がない場合は、ENT_HTML401(省略時のデフォルト)を使用します。

ENT_DISALLOWED、ENT_IGNORE、またはENT_SUBSTITUTEを使用する必要がありますか?

デフォルトでは、指定された文字セットに対して無効であるバイトシーケンスは削除されます。無効なバイトシーケンスの代わりにを使用するには、ENT_SUBSTITUTEを指定します。 (&#FFFD;は、UTF-8以外の文字セットに対して表示されることに注意してください)。ただし、ENT_IGNOREを指定すると、ENT_SUBSTITUTEを指定してもこれらの文字は表示されません。

ドキュメントタイプの無効な文字は、ENT_DISALLOWEDが指定されている場合、上記と同じ置換文字(またはそのエンティティ)に置き換えられます。これは、ENT_IGNOREが設定されているかどうかに関係なく発生します(Doctypeの無効な文字とは関係ありません)。

86
Lekensteyn