【PHP8.x】html_entity_decode関数の使い方

作成日: 更新日:

html_entity_decode関数は、HTMLエンティティを対応する文字に変換する関数です。htmlspecialchars関数や htmlentities関数によって変換された文字列を元に戻す際に使用されます。例えば、&lt;< に、&amp;& に変換されます。

この関数は、文字列を受け取り、変換された文字列を返します。オプションで、変換に使用する文字セット(エンコーディング)を指定できます。文字セットを指定しない場合は、デフォルトの文字セットが使用されます。

htmlspecialchars関数などと組み合わせて使用することで、Webアプリケーションにおけるクロスサイトスクリプティング(XSS)攻撃のリスクを軽減するために重要です。htmlspecialchars関数でエスケープされた文字列を、表示する直前に html_entity_decode関数で元の文字に戻すことで、データベースや設定ファイルなどに安全に保存されたデータを正しく表示できます。

ただし、html_entity_decode関数を使用する際には、エンコーディングの指定に注意する必要があります。誤ったエンコーディングを指定すると、文字化けが発生する可能性があります。特に、UTF-8環境で開発している場合は、UTF-8エンコーディングを指定するようにしてください。

また、html_entity_decode関数は、すべてのHTMLエンティティを変換するわけではありません。変換可能なエンティティの種類については、PHPのマニュアルを参照してください。htmlspecialchars関数および htmlentities関数と合わせて使用することで、より安全なWebアプリケーション開発を行うことができます。システムエンジニアを目指す上で、この関数を理解し、適切に利用することは非常に重要です。

基本的な使い方

構文(syntax)

html_entity_decode ( string $string , int $flags = ENT_COMPAT , string|null $encoding = null ) : string

引数(parameters)

string $string, int $flags = ENT_COMPAT | ENT_HTML401, ?string $encoding = null

  • string $string: デコードしたいHTMLエンティティが含まれる文字列
  • int $flags = ENT_COMPAT | ENT_HTML401: エンティティのデコード方法を指定するフラグ
  • ?string $encoding = null: 文字エンコーディングを指定する文字列

戻り値(return)

string

HTMLエンティティ(例: &amp;, &lt;)を元の文字(例: &, <)に変換した文字列を返します。

サンプルコード

PHP html_entity_decode の挙動を修正する

<?php

declare(strict_types=1);

/**
 * html_entity_decode() が期待通りに動作しない一般的な原因と解決策を示します。
 *
 * キーワード「php html_entity_decode not working」で検索される問題の多くは、
 * シングルクォート(')のような特定のHTMLエンティティがデコードされないケースです。
 * これは、関数の第2引数である`flags`の指定が不適切な場合に発生します。
 */
function demonstrateHtmlEntityDecodeFix(): void
{
    // シングルクォート(&apos;)とダブルクォート(&quot;)を含むHTMLエンティティ文字列
    $encodedString = 'It&apos;s a &quot;test&quot; &amp; an example.';

    echo "元の文字列:\n";
    echo $encodedString . "\n\n";

    // --- ケース1: デフォルトのフラグ(期待通りに動作しない例)---
    // デフォルトのフラグは ENT_COMPAT | ENT_HTML401 です。
    // この設定では、&quot; はデコードされますが、&apos; はデコードされません。
    // (&apos; はHTML4.01の仕様には含まれていないためです)
    $decoded_case1 = html_entity_decode($encodedString);

    echo "【失敗例】デフォルトのフラグでの結果:\n";
    echo $decoded_case1 . "\n\n";

    // --- ケース2: 適切なフラグを指定(期待通りに動作する例)---
    // シングルクォートもデコードするには ENT_QUOTES を、
    // &apos; のようなHTML5エンティティを正しく扱うには ENT_HTML5 を指定します。
    // また、文字化けを避けるため、第3引数でエンコーディングを明示することが推奨されます。
    $flags = ENT_QUOTES | ENT_HTML5;
    $encoding = 'UTF-8';
    $decoded_case2 = html_entity_decode($encodedString, $flags, $encoding);

    echo "【成功例】ENT_QUOTES | ENT_HTML5 を指定した結果:\n";
    echo $decoded_case2 . "\n";
}

// 関数を実行して結果を表示します
demonstrateHtmlEntityDecodeFix();

html_entity_decode関数は、HTMLエンティティ(例: &amp;, &quot;, &lt;)でエンコードされた文字列を、元の文字(例: &, ", <)に戻すために使用されます。

この関数は、最初の引数$stringにデコードしたい文字列を受け取ります。2番目の引数$flagsは、デコードの挙動を制御するオプションです。例えば、引用符をどのように扱うか、どのHTMLバージョンに準拠するかなどを指定できます。デフォルトではENT_COMPAT | ENT_HTML401が設定されており、HTML4.01の仕様にないエンティティ(例: シングルクォートを表す&apos;)はデコードされません。これが「php html_entity_decode not working」という問題が発生する主な原因となります。3番目の引数$encodingでは、入力文字列の文字エンコーディングを指定します。文字化けを防ぐため、'UTF-8'のように明示的に指定することが推奨されます。関数はデコードされた文字列を返します。

サンプルコードでは、シングルクォートの&apos;が含まれる文字列を例に、この問題と解決策を示しています。デフォルトのflagsでは&apos;がデコードされずに残ってしまいますが、flags引数にENT_QUOTES | ENT_HTML5を指定することで、&apos;を含む全ての引用符エンティティやHTML5で追加されたエンティティが正しくデコードされます。これにより、意図した通りの結果が得られるようになります。

html_entity_decode関数でHTMLエンティティが期待通りにデコードされない場合、主な原因は第2引数のflags指定が不適切なことです。特にシングルクォート(&apos;)をデコードするには、デフォルトのENT_COMPAT | ENT_HTML401では不十分なため、ENT_QUOTESENT_HTML5フラグを組み合わせて明示的に指定する必要があります。これにより、&apos;のようなHTML5エンティティや引用符が正しくデコードされます。また、文字化けを防ぎ、コードを安全に利用するためには、第3引数でエンコーディング(通常はUTF-8)を常に指定することを強く推奨します。

PHP: html_entity_decodeとhtmlspecialchars_decodeの比較

<?php

/**
 * html_entity_decode と htmlspecialchars_decode の違いを比較する関数。
 *
 * システムエンジニアを目指す初心者向けに、それぞれの関数がどのようなHTMLエンティティを
 * デコードするかを理解できるように設計されています。
 *
 * htmlspecialchars_decode:
 *   - 主にHTMLの特殊文字(&amp;, &lt;, &gt;, &quot;, &#039;)のみをデコードします。
 *   - 名前付きエンティティ(&copy;, &reg;)や数値文字参照(&#123;)はデコードしません。
 *
 * html_entity_decode:
 *   - HTMLエンティティ全般(特殊文字、名前付きエンティティ、数値文字参照)をデコードします。
 *   - より広範なデコードが必要な場合に使用します。
 */
function compareHtmlDecoders(): void
{
    // 比較に使用するエンコードされた文字列
    // - &lt;p&gt; はHTMLタグの一部をエスケープした特殊文字
    // - &amp;, &lt;, &gt;, &quot;, &#039; もHTML特殊文字
    // - &copy;, &reg;, &euro; は名前付きHTMLエンティティ
    // - &#123;, &#x2665; は数値文字参照 ({ と ♥)
    $encodedString = "これは &lt;p&gt;タグ&lt;/p&gt; です。" . PHP_EOL
                   . "HTML特殊文字: &amp; &lt; &gt; &quot; &#039;" . PHP_EOL
                   . "名前付きHTMLエンティティ: &copy; &reg; &euro;" . PHP_EOL
                   . "数値文字参照: &#123; &#x2665;";

    echo "--- 元のエンコードされた文字列 ---" . PHP_EOL;
    // 出力時にHTMLとして解釈されないよう、文字列をhtmlspecialcharsでエスケープして表示します。
    // (例: &lt;p&gt;はブラウザ上で &lt;p&gt; と表示され、<p>タグとしてはレンダリングされません)
    echo htmlspecialchars($encodedString) . PHP_EOL . PHP_EOL;

    // --- htmlspecialchars_decode の結果 ---
    // htmlspecialchars_decode はHTML特殊文字 (&amp;, &lt;, &gt;, &quot;, &#039;) のみをデコードします。
    // その他の名前付きエンティティ (&copy;, &reg;) や数値文字参照 (&#123;, &#x2665;) はそのまま残ります。
    $decodedBySpecialChars = htmlspecialchars_decode($encodedString);

    echo "--- htmlspecialchars_decode の結果 ---" . PHP_EOL;
    // デコードされた文字列をHTMLとして解釈されないよう、再度htmlspecialcharsでエスケープして表示します。
    echo htmlspecialchars($decodedBySpecialChars) . PHP_EOL;
    echo "(注: &lt;p&gt;, &amp;, &lt;, &gt;, &quot;, &#039; のみがデコードされ、" . PHP_EOL
       . "     &copy;, &reg;, &euro;, &#123;, &#x2665; はそのまま残ります)" . PHP_EOL . PHP_EOL;

    // --- html_entity_decode の結果 ---
    // html_entity_decode はすべてのHTMLエンティティ (特殊文字、名前付きエンティティ、数値文字参照) をデコードします。
    // 第2引数の $flags はENT_COMPAT | ENT_HTML401がデフォルト値です。
    $decodedByHtmlEntity = html_entity_decode($encodedString);

    echo "--- html_entity_decode の結果 ---" . PHP_EOL;
    // デコードされた文字列をHTMLとして解釈されないよう、再度htmlspecialcharsでエスケープして表示します。
    echo htmlspecialchars($decodedByHtmlEntity) . PHP_EOL;
    echo "(注: すべてのHTMLエンティティがデコードされます)" . PHP_EOL . PHP_EOL;
}

// 関数を実行し、結果を出力します。
compareHtmlDecoders();

PHP 8で利用できるhtml_entity_decode関数は、HTMLエンティティでエンコードされた文字列を、元の通常の文字形式にデコードするために使用されます。例えば、ウェブページから取得したデータに含まれる&amp;&に、&lt;<に変換する際に役立ちます。

この関数は、デコード対象の文字列を$string引数として受け取ります。$flags引数ではデコードの挙動を制御でき、デフォルトではENT_COMPAT | ENT_HTML401が設定されています。また、$encoding引数で文字エンコーディングを指定できますが、省略した場合はPHPのデフォルトエンコーディングが使用されます。デコード処理が完了すると、変換された文字列がstring型で戻り値として返されます。

特にhtml_entity_decodeは、htmlspecialchars_decode関数とは異なるデコード範囲を持ちます。htmlspecialchars_decodeは主にHTMLの特殊文字(例: &amp;, &lt;, &gt;, &quot;, &#039;)のみをデコードするのに対し、html_entity_decodeは、これらの特殊文字に加えて、&copy;のような名前付きエンティティや、&#123;のような数値文字参照といった、より広範なHTMLエンティティをデコードします。

提供されたサンプルコードでは、様々な種類のエンティティを含む文字列を使用して、これら二つの関数の違いを具体的に示しています。htmlspecialchars_decodeを実行した結果では特殊文字のみが元の文字に戻っているのに対し、html_entity_decodeを実行した結果では、すべてのHTMLエンティティがデコードされた状態で出力されることが確認できます。これにより、デコードしたいエンティティの種類に応じて、適切な関数を選択することの重要性が理解できます。

htmlspecialchars_decode&amp;などのHTML特殊文字のみをデコードします。一方、html_entity_decodeは特殊文字に加えて、&copy;のような名前付きエンティティや&#123;のような数値文字参照もデコードするため、より広範な用途で利用できます。どちらの関数を使うかは、デコードしたいエンティティの種類によって適切に使い分ける必要があります。デコード後の文字列をWebページに出力する際は、XSS攻撃などを防ぐため、必ずhtmlspecialcharsなどで再度エスケープし、意図しないHTMLとして解釈されないように十分注意してください。html_entity_decode$flags$encoding引数はデフォルト値があるため省略可能です。

【PHP8.x】html_entity_decode関数の使い方 | いっしー@Webエンジニア