PHP で HTML をエンコードする

Habdul Hazeez 2023年1月30日
  1. htmlspecialchars() でエンコードする
  2. htmlentities() でエンコードする
  3. htmlentities() と HTML5 エンコーディングでエンコードする
  4. カスタムメソッドでエンコードする
PHP で HTML をエンコードする

HTML エンコーディングは、ユーザーが提供したデータを処理するときに、PHPWeb アプリケーションでクロスサイトスクリプティング XSSを防止する試みです。このチュートリアルでは、htmlentities()htmlspecialchars()、およびカスタムメソッドを使用してデータをエンコードする方法を説明します。

htmlspecialchars() でエンコードする

PHP htmlspecialchars() は、特殊文字を HTML エンティティに変換できる組み込み関数です。構文は次のとおりです。

htmlspecialchars( $string, $flags, $encoding, $double_encode )

パラメータの説明:

  • $string:入力文字列
  • $flags:関数が文字列内の引用符を処理する方法を指示するフラグ
  • $encoding:関数で使用されるエンコーディングを指定します。このパラメーターはオプションです
  • $double_encode:PHP が既存のエンティティをエンコードするかどうかを指定するブール属性。false に設定すると、PHP は既存のエンティティをエンコードしません

すべての関数と同様に、htmlspecialchars() は値を返します。その値は変換された文字列です。ただし、関数が文字列を無効と見なすと、空の文字列が返されます。

次の例は、htmlspecialchars() を使用して文字列を変換する方法を示しています。この関数がフラグとともに使用されていないことがわかります。

<?php
    $stringToEncode = "A <b>bold text</b> a'nd á <script>alert();</script> tag";

    $encodedString = htmlspecialchars($stringToEncode);

    echo $encodedString;
?>

出力:

A <b>bold text</b> a'nd á <script>alert();</script> tag

Web ページのソースを表示すると、アポストロフィとá文字がエンコードされていないことがわかります。

A &lt;b&gt;bold text&lt;/b&gt; a'nd á &lt;script&gt;alert();&lt;/script&gt; tag

ここで、htmlspecialchars() にフラグとエンコード形式を指定すると、アポストロフィはエンコードされますが、áはエンコードされません。

<?php
    $stringToEncode = "A <b>bold text</b> a'nd á <script>alert();</script> tag";

    $encodedString = htmlspecialchars($stringToEncode, ENT_QUOTES, 'UTF-8');
    
    echo $encodedString;
?>

出力:

A <b>bold text</b> a'nd á <script>alert();</script> tag

ページのソースを表示すると、ブラウザがアポストロフィを&#039; としてエンコードしていることがわかります。

A &lt;b&gt;bold text&lt;/b&gt; a&#039;nd á &lt;script&gt;alert();&lt;/script&gt; tag

htmlentities() でエンコードする

htmlentites() も組み込みの PHP 関数です。htmlentities() を使用すると、該当するすべての文字が HTML エンティティに変換されます。その構文は次のとおりです。

htmlentities( $string, $flags, $encoding, $double_encode )

以下は、パラメーターの説明です。

  • $string:入力文字列
  • $flags:関数が文字列内の引用符を処理する方法を指示するフラグ
  • $encoding:関数で使用されるエンコーディングを指定します。このパラメーターはオプションです
  • $double_encode:PHP が既存のエンティティをエンコードするかどうかを指定するブール属性。false に設定すると、PHP は既存のエンティティをエンコードしません

この関数の戻り値は、エンコードされた文字列です。

以下は、htmlentities() を使用して文字列を変換する例です。ここでは、htmlentities() はフラグとともに使用されていません。

<?php    
    $stringToEncode = "A <b>bold text</b> ánd a <script>alert();</script> tag's";

    $ecodedString = htmlentities($stringToEncode);

    echo $ecodedString;
?>

出力:

A <b>bold text</b> ánd a <script>alert();</script> tag's

ページのビューソースは、関数がフラグなしでá文字をエンコードしていることを示していますが、アポストロフィはエンコードされていません。

A &lt;b&gt;bold text&lt;/b&gt; &aacute;nd a &lt;script&gt;alert();&lt;/script&gt; tag's

コードを変更すると、関数でアポストロフィをエンコードできるようになります。

<?php
    $stringToEncode = "A <b>bold text</b> ánd a <script>alert();</script> tag's";

    $ecodedString = htmlentities($stringToEncode, ENT_QUOTES, 'UTF-8');

    echo $ecodedString;
?>

出力:

A <b>bold text</b> ánd a <script>alert();</script> tag's

ページのソースを表示します。

A &lt;b&gt;bold text&lt;/b&gt; &aacute;nd a &lt;script&gt;alert();&lt;/script&gt; tag&#039;s

htmlentities() と HTML5 エンコーディングでエンコードする

文字列に英語以外の文字が含まれている場合は、HTML 5 フラグと UTF-8 エンコーディングを使用できます。

HTML5 フラグは、文字列を HTML5 として扱うように関数に指示し、UTF-8 フラグは、関数が標準の Unicode 文字を理解できるようにします。

以下は、HTML5 フラグと UTF-8 エンコーディングで htmlentities() を使用する方法の例です。

<?php
    $stringToEncode = "àéò ©€ ♣♦ ↠ ↔↛ āžšķūņ ↙ ℜ℞ ∀∂∋ rūķīš ○";

    $ecodedString = htmlentities($stringToEncode, ENT_HTML5, 'UTF-8');
    
    echo $ecodedString;
?>

ページのソースを表示します。

&agrave;&eacute;&ograve; &copy;&euro; &clubs;&diamondsuit;
&twoheadrightarrow; &harr;&nrarr; &amacr;&zcaron;&scaron;
&kcedil;&umacr;&ncedil; &swarr; &Rfr;&rx; &forall;&part;&ReverseElement;
r&umacr;&kcedil;&imacr;&scaron; &cir;

カスタムメソッドでエンコードする

エンコーディングスキームをロールしたい場合は、カスタムメソッドが便利です。このメソッドは、入力文字列を受け取り、文字列操作を適用します。最後に、エンコードされた文字列を取得します。

次の HTML には、テキスト領域と 1つの送信ボタンがあります。フォーム action は、フォーム入力に渡された文字列をエンコードするファイルを指します。

<main>
    <h1>Enter and HTML code and click the submit button</h1>
    <form action='encodedoutput.php' method='post'>
        <div class="form-row">
            <textarea rows='15' cols='50' name='texttoencode' required></textarea>
        </div>
        <div class="form-row">
            <input type='submit'>
        </div>
    </form>
</main>

次のコードブロックは、エンコードを実行する PHP コードです。encodeoutput.php として保存します。

<?php
    if (isset($_POST['texttoencode']) && !empty($_POST)) {
        // Check for empty text
        if ($_POST['texttoencode'] == "") {
            echo "Invalid text";
            die();
        }

        $inputHTML = bin2hex($_POST['texttoencode']); 
        $spiltHTML = chunk_split($inputHTML, 2 ,"%");
        $HTMLStringLength = strlen($spiltHTML);
        $HTMLSubLength = $HTMLStringLength - 1;
        $HTMLSubString = substr($spiltHTML,'0', $HTMLSubLength);

        $encodedOutput="<script>document.write(unescape('%$HTMLSubString'));</script>";

    } else {
        echo "Not allowed";
        die();
    }
?>

<textarea rows='15' cols='60'>
    <?php
        if ($encodedOutput) {
            echo $encodedOutput;
        } else {
            echo "";
            die();
        }
    ?>
</textarea>

<script>alert("Hello world");</alert> の出力例:

<script>document.write(unescape('%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%22%48%65%6c%6c%6f%20%77%6f%72%6c%64%22%29%3b%3c%2f%61%6c%65%72%74%3e'));</script>
著者: Habdul Hazeez
Habdul Hazeez avatar Habdul Hazeez avatar

Habdul Hazeez is a technical writer with amazing research skills. He can connect the dots, and make sense of data that are scattered across different media.

LinkedIn

関連記事 - PHP Encode