PAGE TOP


htmlspecialchars() 特定のタグを許可する。kses関数

2017年2月10日PHP

データを表示する際に、htmlspecialchars()でエスケープすることは、一般的ですが、時には、特定のタグだけ許可したい場合があります。そのような時には、replacement()やhtmlspecialchars_decode()などを併用して、正規表現で特定の文字だけ、許可することは可能ですが、慣れていないとかなり嵌ってしまうものです。(一度作ってしまえば簡単ですが)

例えばブログ等で、ユーザーの入力値の際に、<a><img>タグなどだけ許可したい場合は、htmlspecialchars()で全て変換してしまうと、不都合が生じます。

今回紹介するのは、GitHubで見つけたちょっと便利な関数です。オブジェクトに使用するタグ情報をセットして、それを関数の引数に渡して利用することで簡単に特定のタグだけ許可できてしまいます。

ダウンロードはこちらから、
kses 0.2.2 https://github.com/Inndy/kses

使い方は、任意の場所に、kses.phpファイルを設定して、それを関数を利用するファイルで読み込みます

下記の例では、フォームより投稿したら、自分自身でpost値を受け取り、それを関数に入れて、返り値を表示するというようになっています。

オブジェトの設定では、keyにタグ名と、valueに細かな設定をすることができます。公式サイトをみてみると、必要のないくらいに他にもいろいろできるようですが、今回は、ただ単に表示にとどめます。

他には、get_magic_quotes_gpc()関数は、PHPの設定のmagic_quotes_gpcの値をBoolean型で返すので、それによって、不都合が生じるので、stripslashes()関数で元に戻す処理を加えていますが、php5.4.0より、マジッククォート機能は削除され、常に FALSE 返すようになったようなので、こちらは、コメントアウトしました。php5.4以前の方は、ひょっとすると設定が必要な場合もあるので、コメントインしてください。

<?php
//me.php
include 'kses.php';

$allowed = array('b' => array(),
                 'i' => array(),
                 'a' => array('href'  => array('minlen' => 3, 'maxlen' => 50),
                              'title' => array('valueless' => 'n')),
                 'p' => array('align' => 1,
                              'dummy' => array('valueless' => 'y')),
                 'img' => array('src' => 1), # FIXME
                 'font' => array('size' =>
                                         array('minval' => 4, 'maxval' => 20)),
                 'br' => array());

$val = $_POST['val'];
/*
if (get_magic_quotes_gpc()){
  $val = stripslashes($val);
  }
*/

?>

出力する為のkses関数の引数は、(出力する文字列、オプション、許可するプロトコル)になります。
kses($string, $allowed_html = null, $allowed_protocols = array(‘http’, ‘https’, ‘ftp’, ‘news’, ‘nntp’, ‘telnet’,’gopher’, ‘mailto’))

これらを表示したい部分で出力してください。

//me.php
<html>
<head>
<title>kses example: HTML filter</title>
</head>

<body>

<h1>Input</h1>

<pre><?= htmlspecialchars($val); ?></pre>

<h1>Output</h1>

<pre><?php

$val = kses($val, $allowed, array('http', 'https'));

echo $val;

?></pre>


<h1>Type something</h1>

<form method="POST" action="me usb3oyz.php">
<textarea name="val" rows=5 cols=50><?= $val; ?></textarea>
<br>
<input type="submit" value="Send it!">
</form>


</body>
</html>

おそらく、使用する際は、なんらかのフレームワーク等の中に組み込むと思いますので、
データベースよりオブジェクトに入ったデーター一覧を出力する際には、ループでまわして、出力値だけをテンプレート側に渡すようにしてください。

(補足)
第2引数のオブジェクトのタグの細かい設定に関しては、

//ないものは追加
'h1' => array(),
'h2' => array(),
'h3' => array(),
'h4' => array(),
'h5' => array(),

//URLの文字数の制限 3-50までの範囲
'a' => array('href'  => array('minlen' => 3, 'maxlen' => 50), 
//kses.phpにない要素の追加。'n'で表示 'y'で非表示
'title' => array('valueless' => 'n'),
 'data' => array('valueless' => 'n')   


また、すべては確認していませんが、kses.phpでデフォルト設定されているもの意外に、設定を追加すると、全て初期化されるようで、必要なものは、自分で追加する必要があるようです。