2007年10月13日土曜日

[PHP] RSSファイル内の最新itemの日付を探す

Podcastingを始めて1年ほどになります。最近、Podcastのページへのリンクのところに(12/10/06更新)などのように表示できたらいいなと思いました。さらに、更新日付が自動的に生成できたらいいなと考え、PHPのプログラミング開始。次のような関数を書くにいたりました。

まず全体を紹介して、後で少しずつ解説します。

このコードを使うには、HTMLのヘッダのところに以下の関数宣言を挿入します。

<?php

function Find_Latest_From_RSS($filename) {
$str=file_get_contents($filename);
$p = xml_parser_create();
xml_parse_into_struct($p, $str, $vals, $index);
xml_parser_free($p);
for ($i=0; $i<count($vals); $i++) { // skip over stuff before <ITEM>
if ($vals[$i][tag]=="ITEM") {
break;
}
}
$latest="January 1 1970 00:00:00 GMT"; // initialize
for (; $i<count($vals); $i++) { // start looking for PUBDATEs
if ($vals[$i][level]==4 && $vals[$i][tag]=="PUBDATE") {
$dateTime=strtotime($vals[$i][value]);
if ($latest<$dateTime) {
$latest=$dateTime;
}
}
}
return date("n/j/y",$latest);
}

?>

そして更新日付を表示したいところに以下を挿入します。

<?php echo Find_Latest_From_RSS("your_RSS_file"); ?>

例えば、

(<?php echo Find_Latest_From_RSS("your_RSS_file"); ?>更新)

とすれば、
 
(12/11/06更新)

のように表示されます。

日付の表示形式を変えたい場合は、この部分を変更します。

date("n/j/y",$latest)

さて、ここからコードの解説をします。

まず関数の宣言です。

function Find_Latest_From_RSS($filename) {

RSSファイル名を引き渡せるようになっていますので、一つのHTMLファイルの中で複数のRSSファイルを処理する事が可能です。この関数は、戻り値として日付(文字列)を返します。

ここではRSSファイルを一気に読み込みます。
 
$str=file_get_contents($filename);

次の三行はセットになっています。

$p=xml_parser_create();
xml_parse_into_struct($p, $str, $vals, $index);
xml_parser_free($p);

一行目でパーサーオブジェクトを作り、二行目で解析をして、三行目で不要になったパーサーオブジェクトをメモリから消します。解析結果は、$valsの中に入れてくれます。

次に最初の<ITEM>タグを探します。

for ($i=0; $i<count($vals); $i++) { // skip over stuff before <ITEM>
if ($vals[$i][tag]=="ITEM") {
break;
}
}

見つかったらループから抜けます。これは、<ITEM>以前に記述されているRSS feed全体に関する情報を飛び越すためです。

最新のPUBDATEを探すために、$latestという変数を、1970年1月1日に初期化します。

$latest="January 1 1970 00:00:00 GMT";

またforループに入りますが、今度は$iを初期化しません。以前のループを抜けた時の$iの値から繰り返しが始まります。

for (; $i<count($vals); $i++) {

$vals配列内の個々の要素を調べて、「その要素のレベルが4で、タグがPUBDATEだったら」という条件になっています。

if ($vals[$i][level]==4 && $vals[$i][tag]=="PUBDATE") {

レベル4とは、ITEMのPUBDATEが<rss><channel><item>の下に来るから4なのです。レベル3にもPUBDATEがあり、これはRSS feed全体の公開日です。ITEM以前のデータは飛び越していますから、レベルチェックは本当は必要ありませんが、念のためというのと、データ構造を見ていただくために入れました。

上の条件に合った配列要素は、itemの公開日です。これは文字列データですから、比較ができるようにするためにstrtotimeで日付時間データに変換します。

$dateTime=strtotime($vals[$i][value]);

変換後なら、以下のように不等号を使って比較ができます。

if ($latest<$dateTime) {
$latest=$dateTime;
}

より新しい日付が見つかるたびに、$latestを更新していきます。

このように処理していけば、ループが終わった時点で、$latestには、もっとも最近公開されたitemの公開日付が入っているはずです。

最後にこの日付データを好みの形式の文字列に変換してやります。

return date("n/j/y",$latest);

この文字列が、この関数の戻り値となります。

0 件のコメント: