PHPとXMLの連携のときにアットライズのサーバーで起こったバグ的なPHPの処理の不具合メモだよ。
デフォルトのデータ処理
デフォルトのデータ処理はなぜか途中で終わってしまうものが
あったので、$tmp[$name]に追加する形で入れる。
途中で終わった場合でも終了タグがきたわけではないので、
再びデフォルトの処理に戻ってくる。
その後、終了タグが来たときに$tmp[$name]をその要素の配列に
入れて、$tmp[$name]を初期化してあげる
という処理をしてあげると良いということがわかったよ。
詳しくは続きを読むをクリック!
//開始要素
function start_el($ps,$name,$atr){
global $map_array,$tag,$depth,$parent,$first_child,$second_child;
$first_child = 2;
$second_child = 3;
if(isset($map_array[$name])){
//echo “[".$depth[$ps].”]”;
//深度が1だった場合は$parentに$nameを代入
if($depth[$ps] == $first_child):
$parent = $name;
endif;
//echo $name.”<br>”;
$tag = $name;
}else{
$tag = “”;
}
$depth[$ps]++;
}
//終了要素
function end_el($ps,$name){
global $map_array,$depth,$tmp,$parent,$blog,$first_child,$second_child,$blog_title,$blog_url,$link_url;
$depth[$ps]–;
if(isset($map_array[$name])){
if($depth[$ps] == $first_child):
if($name == “TITLE”):
$blog_title = mb_convert_encoding($tmp[$name],”SJIS”,”auto”);
$tmp[$name] = “”;
elseif($name == “LINK”):
$blog_url = $tmp[$name];
$tmp[$name] = “”;
endif;
elseif($depth[$ps] == $second_child):
if($name == “TITLE”):
$blog[blog_title][] = $blog_title;
$blog[blog_url][] = $blog_url;
$blog[entry_title][] = $tmp[$name];
$tmp[$name] = “”;
elseif($name == “LINK”):
$blog[entry_url][] = $tmp[$name];
$tmp[$name] = “”;
elseif($name == “PUBDATE”):
$blog[entry_date][] = date(“Y/m/d”,strtotime($tmp[$name]));
$tmp[$name] = “”;
endif;
endif;
//endif;
}
}
//デフォルトデータ処理
function char_data($ps,$data){
global $tmp,$tag,$depth,$link_url;
if($tag != “”):
$tmp[$tag] .= mb_convert_encoding($data,”SJIS”,”auto”);
endif;
}
//XMLの処理
//XMLパーサ作成
$xml = xml_parser_create();
//開始要素、終了要素の処理を指定
xml_set_element_handler($xml,”start_el”,”end_el”);
//デフォルトの処理を指定する
xml_set_character_data_handler($xml,”char_data”);
//XMLファイルを展開して処理する
while ($data = fread($file,1000)):
if(!xml_parse($xml,$data,feof($file))):
die(“<p>エラー行番号:”.xml_get_current_line_number($xml));
endif;
endwhile;
いろんなところからパクっ。。。もとい、たくさんの親切な方々のソースを参考にさせていただいたのでつぎはぎだらけで、自分でもよくわからないところが多 々あるのだけども要するにXMLの開始タグがきたら、start_elを実行、終了タグが着たらend_elを実行、それ以外は、デフォルトの処理であ る、char_dataを実行するという感じらしい。
で、問題のデフォルトデータの処理だけれども、RSSのXMLを読み込む時にLINKの中身がなぜか途中で終わってしまうような形のもの がたまに出てきてしまうので、それを回避するために、$tmp[$tag]に一時的に保存をしてあげる。デフォルトの処理が途中で終わっても、終了タグは まだ来ないからデータを表示するための配列$blog[element名]にはまだデータは入らないので、一時保存の$tmp[$tag]に追加をするよ うに$tmp[$tag] .= データ;としてあげる。
終了タグが来たら一時保存のデータを表示用の配列に入れてあげて、一時保存の配列を初期化してあげる。
というようにしてあげることで、まんまとうまくいくのでした。
ちなみに、不具合が見られたのは、LINKとPUBDATEのところで、実はRDFのフィードしか読んでいないのだけども、RSSやATOMフィードの場合はブログタイトルだとか、 エントリータイトルにも同じような現象が見られた。
おそらくPHPのバージョンが影響していると思われるのだけども、念のためのメモ。
[関連性があるかもしれない記事]
