PHP

htmlspecialcharsとFILTER_SANITIZE_SPECIAL_CHARS

経緯

ぼく「POSTされた値を受け取るときのフィルタってなにがええんやろな~」
ぼく「お、FILTER_SANITIZE_SPECIAL_CHARS安全そうでええやん!」
~数日後~
ぼく「POSTで来た値をHTMLに出力するときにはhtmlspecialchars!常識だよね!」
~半年後~
お客様「'って入力したら'に文字化けするんだけど!!」
ぼく「ふええええ」

原因

FILTER_SANITIZE_SPECIAL_CHARS
'"<>& および ASCII 値が 32 未満の文字を HTML エスケープします。オプションで、 特殊文字を取り除いたりエンコードしたりします。

ENT_QUOTES
シングルクオートとダブルクオートを共に変換します。

つまり、

$input = filter_input(INPUT_POST,"hoge",FILTER_SANITIZE_SPECIAL_CHARS);
echo htmlspecialchars($input,ENT_QUOTES,'UTF-8');

とすると、
'"<>&が多重エスケープされてしまいます。

本来なら、入力の受け取り時はバリデーションのみ、出力時にエスケープとするのが妥当(らしい)なのですが、
PHPの除去フィルタのうちの一部が除去するだけでなくエスケープまで行っているので、こうなってしまいました。

僕は今回FILTER_SANITIZE_SPECIAL_CHARSを使うべきでなかったですが、ヌル文字とか弾くのに便利だと思うので使い所さんを見極めてちゃんと使いましょう。