2008/02/17(日)
ある複数のブログの更新状態をブログとは別の HTML ページでまとめて表示したい(例えば、ある企業のブログの更新状況を、その企業のサイトのトップページに自動で表示したいといった場合)。欲しいのは、エントリーのタイトルと日付とサマリー。
というようなとき、最も手っ取り早いのは、ブログが吐き出す RSS を利用することだろう。でも XML を扱うのってちょっと面倒くさい。パースだのハンドラーだの、なんじゃそれは? いやちょっと待ってくれ、欲しい情報はほんのわずかなんだ。最新のエントリーひとつ分の上記の内容だけ。
だったら、単純に文字列として取り込んで、必要なものだけ抜き出した方が早くないか? 使用する RSS のタイプも最初から決めてしまえば、RSS のバージョンに振り回される必要もない。別に汎用のリーダを作ろうってわけじゃないんだから。
というわけで、文字コード UTF-8、データ形式は Atom、日付は降順になっていることを前提に、やってみた。以下がそのコード。
<?php
// Get Entry Value of RSS Feed
function getEntVal ($URL) {
// 保存/読込用のファイル名を準備
$Path = pathinfo($URL);
$DirName = $Path["dirname"];
$DirName = str_replace('http://XXXXX.weblogs.jp/', '', $DirName);
$FileName = $Path["basename"];
$NewFileName = $DirName . '_' . $FileName;
$NewPath = './rss/' . $NewFileName;
$RemoteFile = fopen($URL, 'r');
$FirstLine = fgets($RemoteFile); // 先頭の1行を読込
$EntTitle = '';
$EntDate = '';
$EntSummary = '';
$Flag = 0;
// 読み込んだファイルが正しいか確認
// OK の場合、1行ずつ配列に読み込み、条件が揃ったら終了し、ファイルに保存
// 注)最初の設置時点では正規ファイルを自分でコピーしておくこと
if (strpos($FirstLine, '<?xml ') !== FALSE) {
$ForCopy = '';
for ($i = 0; $LVal = fgets($RemoteFile); $i ++) {
// entory 開始タグに当たるまではスルー
if (strpos($LVal, '<entry>') !== FALSE) {
for ($j = 0; $LVal2 = fgets($RemoteFile); $j ++) {
$LVal2 = trim($LVal2);
if (strpos($LVal2, '<title>') !== FALSE) { $EntTitle = strip_tags($LVal2); }
if (strpos($LVal2, '<published>') !== FALSE) { $EntDate = strip_tags($LVal2); }
if (strpos($LVal2, '<summary>') !== FALSE) { $EntSummary = strip_tags($LVal2); }
$ForCopy .= $LVal2 . "\n";
// 変数が3つとも埋まるか、entry が閉じられたら終了
if (
($EntTitle != '' && $EntDate != '' && $EntSummary != '')
|| (strpos($LVal2, '</entry>') !== FALSE)
) {
$Flag = 1;
break;
}
}
break; // 処理完了、ループを抜ける
}
}
// 文字列をファイルに保存
//file_put_contents($NewPath, $ForCopy);
$CopyFile = fopen($NewPath, 'w');
fwrite($CopyFile, $ForCopy);
fclose($CopyFile);
// NG の場合、既存のファイルを読込んで処理
} else {
if (file_exists($NewPath)) {
$LineAry = file($NewPath);
foreach ($LineAry as $LVal2) {
$LVal2 = trim($LVal2);
if (strpos($LVal2, '<title>') !== FALSE) { $EntTitle = strip_tags($LVal2); }
if (strpos($LVal2, '<published>') !== FALSE) { $EntDate = strip_tags($LVal2); }
if (strpos($LVal2, '<summary>') !== FALSE) { $EntSummary = strip_tags($LVal2); }
// 変数が3つとも埋まるか、entry が閉じられたら終了
if (
($EntTitle != '' && $EntDate != '' && $EntSummary != '')
|| (strpos($LVal2, '</entry>') !== FALSE)
) {
$Flag = 1;
break;
}
}
}
}
if ($Flag) {
// 日時の整形
$EntDate = trim($EntDate, '+09:00');
$EntDate = str_replace('T', ' ', $EntDate);
$EntDate = date('Y年m月d日 H:i', strtotime($EntDate));
$Return['Title'] = $EntTitle;
$Return['Date'] = $EntDate;
$Return['Summary'] = $EntSummary;
return $Return;
} else {
return FALSE;
}
}
$NewEnt = getEntVal('http://XXXXX.weblogs.jp/DDDDD/atom.xml');
var_dump($NewEnt);
?>
日時の整形をちょこちょことやっているのは、例にした TypePad の Atom の出力が 2008-02-17T15:14:22+09:00 というような形式だったからだが、こころへんは読み込む RSS によっては違うのかもしれないので、その場合は適宜改良が必要。もっとも、関数内にしたって用途に応じて改良は必要になるだろう。しかし短いスクリプトだから変更も容易なはずだ。
上記コード修正。リモートのファイルは file 関数で読み込むより fopen で読み込んだ方が、表示が早くなるようだ。また、保存ファイルも、必要な情報のみ抜きだして保存するよう変更した。
TypePad限定なら、もっと簡単な方法がある。上級者テンプレートで、フォーマット済みのインデックスファイルを新規に作成し、Webページ側からはそのファイルをただ読込んで表示すればよい。別にフィードを解析する必要はない。TypePadの扱いに慣れてきて、ようやく思いついた方法。
MovableTypeでも同様のことは可能だろうし、他のブログやCMS系でも、テンプレートを追加自作できるものなら、このアイディアで応用できる筈だ。
この方法だと、上記コードの大部分(読込み後)の処理が不要になる。orz
結局、自分が管理していないサイトのフィードを取得しなければならない場合に限って、上記コードが応用できる。(そういう状況って、あまりないよね、きっと)
Filed under: CMS,Sample | タグ: PHP, RSS, TypePad
Tail-Lagoon @ 19:51
コメントおよびトラックバック受付中です。
TB : http://weblogs.tail-lagoon.com/WebPC/2008/02/17/8/trackback/
この投稿へのコメントは RSS 2.0 フィードで購読できます。