htmlspecialcharsを使う
度々話題にしているアンパサンドなどの特殊文字。これを、HTMLエンティティ(実体参照)に変換するhtmlspecialchars関数を使ってみました。
XMLには、既に何度か(1/2)書いたとおり、<、>、&、"、'を書くことができません。
RSS2.0もXMLですからこの制約を受けます。
▽エンティティ参照 (Entity reference)
http://gogodiet.net/z/xml/3_10.htm
そしてsimplexml_load_fileは、整形式XMLドキュメントをオブジェクトに変換する際、&を&に変換するという余計なお世話をするので、これをRSS2.0にはき出す場合には、実体参照への変換をかけなければいけません。
今までは、
$item->link = preg_replace('/&(?!(?:[a-zA-Z]+|#[0-9]+|#x[0-9a-fA-F]+);)/', '&', $item->link);
$item->link = str_replace('<', '<', $item->link);
$item->link = str_replace('>', '>', $item->link);
$item->link = str_replace('"', '"', $item->link);
と変換をかけてきたわけですが、はたと気付きました。
mysql_real_escape_stringみたいな関数があるんじゃないか?と。
▽PHPで、RSS等のXMLを取得し、パースしています...
http://q.hatena.ne.jp/1180743477
あぁ、先達が苦しんでおられる(><。。。
で、コメント欄にあるhtmlspecialcharsですね。
▽PHP: htmlspecialchars - Manual
http://jp.php.net/manual/ja/function.htmlspecialchars.php
ENT_QUOTESというオプションが事実上必須だったり、UTF-8で使うにはUTF-8を明示しないといけなかったり、既存の htmlエンティティをエンコードしないためにはfalseにしないといけなかったりします。
が、preg_replaceやstr_replaceを使うより圧倒的にすっきりするので、素晴らしい、の一言です。
MySQLの場合同様、脆弱性を生じさせないためには必要不可欠な関数のようなのでちゃんと(存在を)覚えておこうと思います。あれこれ読みましたが、なんか適切なリンクがないぽい(全部を理解しきれていない)ので省略(^^;
参考までにhtmlentitiesについて。
htmlspecialcharsは対象が5文字だけなのに対し、その他の実体参照に置き換えるべき文字についても置換するそうです。
▽PHP: htmlentities - Manual
http://jp.php.net/manual/ja/function.htmlentities.php
▽htmlentities() と htmlspecialchars() の違い (ウェブライフハック)
http://www.mapee.jp/wlh/htmlentities_htmlspecialchars.html
スピードにさほど差がないならこっちを使うべきでしょうが、差がないことはないでしょうね……(さすがに)