aタグとemタグを除いてHTMLのエスケープ処理する : PHP

Pocket

テキストエリアのHTMLタグは<a href="URL可能文字">sample</a>と<em>sample</em>の形式だけ許可する場合のエスケープ処理。

  1. すべてをエスケープする。
  2. aタグのHTMLエンティティ<, >を&lt;, &gt;へデコードする。
  3. emタグのHTMLエンティティ<, >を&lt;, &gt;へデコードする。
  4. a href="…"のHTMLエンティティ"を&quot;へデコードする。

escapeutility.php

<?php
/**
* HTMLエンティティへエンコード(エスケープ)及びデコード
*/
class EscapeUtility {

    /**
* 文字列をHTMLエスケープする
*
* @param string $string エスケープする文字列
* @return string エスケープされた文字列
*/
    public static function escape($string)
    {
        return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
    }

    /**
* aタグとemタグを除いてエスケープする。
*/
    public static function escapeTextarea($text) {
        // aタグとemタグだけ許可する
        $result = htmlspecialchars($text, ENT_QUOTES, 'UTF-8');
        $result = self::decodeA($result);
        $result = self::decodeEm($result);
        $result = self::decodeQuoteA($result);
        return $result;
    }
    /**
* aタグのHTMLエンティティ &lt;, &gt;を<,>へデコード
*
* @param string $text デコードする文字列
* @return string デコードした文字列
*/
    private static function decodeA($text) {
        // 正規表現は最小マッチ
        // &gt;a...&lt;, &gt;/a&lt; は<a...>, </a>へ置換
        return preg_replace('/&lt;(\/?a.*?)&gt;/i', '<$1>', $text);
    }

    /**
* emタグのHTMLエンティティ &lt;, &gt;を<,>へデコード
*
* @param string $text デコードする文字列
* @return string デコードした文字列
*/
    private static function decodeEm($text) {
        // 正規表現は最小マッチ
        // &gt;em&lt;, &gt;/em&lt;は<em>, </em>へ置換
        return preg_replace('/&lt;(\/?em*?)&gt;/i', '<$1>', $text);
    }

    /**
* aタグのhref属性値の引用符&quotを"デコード
*
* @param $text デコードする文字列
* @return string デコードした文字列
*/
    private static function decodeQuoteA($text) {
        // a href=&quotehttp://...&quoteをデコード
        // URL構成文字 [^;/?:@&=+\$,A-Za-z0-9\-_.!~*'()%]
        // パターンにiオプションを付けているので[^;/?:@&=+\$,a-z0-9\-_.!~*'()%]でよい。
        $pattern = "/(a href=)&quot;(https?:\/\/[a-z0-9_,.:;&=+*%$#!?@()~\'\/-]+?)&quot;/i";
        $replacement = '$1"$2"';
        return preg_replace($pattern, $replacement, $text);
    }

}

index.php

<?php
// エスケープ処理
require_once('escape.php');
// textareaで使用可能なタグa, em。
$result = EscapeUtility::escapeTextarea($_POST['textarea']);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>EscapeUtilityの確認</title>
<meta name="description" content="">
<meta name="keywords" content="">
    <style>
        form {
            margin-bottom: 2em;
        }
        textarea {
            width: 800px;
        }
        #output {
            width: 760px;
            padding: 20px;
            margin-bottom: 2em;
            background: #E4E4E4;
        }
    </style>
</head>
<body>
<form action="index.php" method="POST">
    <textarea id="input" name="textarea"></textarea><br>
    <input type="submit" value="送信">
</form>
<div id="output"><?php echo $result; ?></div>
</html>

» Gist

コメント

No comments yet.

コメントの投稿

改行と段落タグは自動で挿入されます。
メールアドレスは表示されません。