173
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

「何故htmlspecialcharsを通すのか?」を一言でどうぞ

結論

Content-Type: text/plain な入力を Content-Type: text/html な環境の中に正しく出力させるため。

もう議論され尽くした内容だが、このような言い回しの人は見たことがなかったので敢えて記事にしてみる。

解説

  • ユーザがテキストボックスを通じて入力するのは text/plain、つまりただのテキスト。ただのテキストであるから装飾する機能は無い。
  • プログラマがユーザ入力を元にPHPで出力するのは text/html、つまりHTML。HTMLには見出しを示したり、太字にしたり、下線を引いたり、CSSやJavaScriptを呼び出す機能もある。
  • htmlspecialcharstext/plaintext/html に変換する。< >&lt; &gt;に変換するというのはあくまで一例に過ぎない、と考えるべきである。

通常、ユーザ入力は text/plain であるべきだ。但し、一部のタグや一部の属性のみを許可するといった処理を厳重なコーディングのもとに行っている場合、ユーザ入力がtext/htmlであると見なすことも許されるであろう。実績のある代表的なライブラリとしては HTML Purifier が挙げられる。

余談

  • 上記では簡略化のため説明を割愛したが、htmlspecialcharsは事実上第3引数の文字コード指定までは必須と言われる。以下のコードは text/plain; charset=UTF-8 から text/html; charset=UTF-8 への変換を行う。
$out = htmlspecialchars($in, ENT_QUOTES, 'UTF-8');
  • Content-Typeのうちcharsetのみを変換する場合も考えられる。以下のコードは text/plain; charset=Shift_JIS から text/plain; charset=UTF-8、あるいは text/html; charset=Shift_JIS から text/html; charset=UTF-8 への変換を行う。
$out = mb_convert_encoding($in, 'UTF-8', 'SJIS');
  • SQL文にユーザ入力を埋め込む際にhtmlspecialcharsを用いるのは不適切である。求められる変換は text/plain から text/html ではなく、text/plain から application/sql(における文字列リテラル) だ。この処理はプリペアドステートメントとそれに付随するプレースホルダが役割として担うものである。
$stmt = $pdo->prepare('SELECT * FROM table WHERE name = :name');
$stmt->bindValue(':name', $name);
$stmt->execute();
  • PHPで作るWebページは必ずtext/htmlになるのか?と言われればそうではなく、text/plainとして出力することも可能である。この場合htmlspecialcharsは不要になる。
<?php
header('Content-Type: text/plain; charset=UTF-8');
echo '<script>alert(1)</script>'; // IE以外ではJavaScriptは実行されない (コメント欄参照)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
173
Help us understand the problem. What are the problem?