PHPでのXMLパースエラー出力は必須だね
日本語 | English
PHPでXMLパースを
$xml = simplexml_load_string($data);
で終わらせていて痛い目にあった。
失敗したらfalseが返ってくるし大丈夫だと思っていたが、
- 制御文字コードが含まれていると失敗してしまう
- 他パースエラーが発生した場合の原因がわからない
上記2つが懸念点。
制御文字コードが含まれていると失敗してしまう
※ 制御文字コードとは? → 制御コード表
私の場合、以下の2つの方法で制御文字コードの存在を確認できた。
1. chromeでファイルを開いた際に、エラーが表示された。
2. sublime text にて制御文字コードが記号として表示された。
ちなみに、制御文字コードの出力はバイナリエディタを使用しました。
私が使っているのは、0xED というエディタ。
以下の様に16進数で入力し、保存すれば制御文字を出力できます。
これが含まれているとパースエラーとなるので、
パース前に置換する必要がある
$search = array("\0", "\x01", "\x02", "\x03", "\x04", "\x05","\x06", "\x07", "\x08", "\x0b", "\x0c", "\x0e", "\x0f"); $data = str_replace($search, '', $data); $xml = simplexml_load_string($data);
他パースエラーが発生した場合の原因がわからない
上記の制御文字コードをエラーとして試しに出力しようとしたら、
try catchで例外としてキャッチできなかった。
どうやら warning エラー。
参考:How do I handle Warning: SimpleXMLElement::__construct()?
set_error_handler を使う。
set_error_handler(function($errno, $errstr, $errfile, $errline) { throw new Exception($errstr, $errno); }); try { $search = array("\0", "\x01", "\x02", "\x03", "\x04", "\x05","\x06", "\x07", "\x08", "\x0b", "\x0c", "\x0e", "\x0f"); $data = str_replace($search, '', $data); $xml = simplexml_load_string($data); restore_error_handler(); //追記:2014.05.05 }catch(Exception $e) { restore_error_handler(); echo $e; }
これで回避出来なかったパースエラーを出力できる
---- 追記 (2014/05/05) ----
set_error_handler()を使用することで
一時的にwarningをfatalへとエラーレベルを上げることとなる。
これだと他の箇所でwarningがあると引きずられてfatalになってしまうので、
catch時以外もパース後にrestore_error_handler()をしてやり
エラーレベルを戻すようにしました。
(php5.5以上ならfinallyとかでもいいかもしれない)