首先大概的原理是讀取Blog的RSS或Atom Feed,得到XML文件,解析該文件得到數據。爲了加快瀏覽速度,我們通常需要把得到數據保存到本地數據庫中。
以上目的分解成技術步驟有以下三步:
1。讀取RSS。 你可以使用現成的函數或者專業的RSS類庫(這種類庫一般還提供更多豐富的功能),也可以自己模擬HTTP來抓取;
在PHP中,使用簡單的比如file_get_contents()函數就可以方便而且高效地抓取文件,但有時候可能RSS文件是不能直接獲取的,比如獲取你的Bloglines帳號中訂閱的RSS,那麼可能你還需要提交一些參數或者通過HTTP認證之類,這時可用模擬HTTP的方法,比如下面代碼使用了PEAR::Http_Request:
function getRSS($username,$password,$s,$n=0){
$url = "http://rpc.bloglines.com/getitems?s=".$s."&n=".$n;
$req = & new HTTP_Request($url);
$req->setBasicAuth($username,$password);
$req->sendRequest();
$blogContent = $req->getResponseBody();
return $blogContent;
}
填入你的Bloglines帳號和密碼,利用這個函數你就可以得到RSS文件。
2。解析XML RSS文件遵循一定規範,你可以自己寫個函數來解析,沒什麼難度,但有點繁瑣。
3。將解析得到的數據入庫。
好了,大概知道了要做的工作,你會發現雖然都不難,但是自己一個個實現比較麻煩,呵呵。這就是本文要介紹Zend_Feed的原因。
Zend_Feed是Zend Framework中的一個類庫,我們完全可以把它單獨拿出來使用。Zend_Feed高度封裝,使用非常方便,例如讀取一個RSS Feed:
$channel = new Zend_Feed_Rss('http://rss.example.com/channelName');
echo $channel->title();
//遍歷記錄
foreach ($channel as $item) {
echo $item->title() . "/n";
}
是不是非常簡單? 讀取和解析總共5行代碼。
好,下面我們開始完成一個真正的Feed Reader:
FeedReader.php
<?php
set_time_limit(0);
define('ZEND_DIR','/www/lib');
set_include_path(get_include_path().PATH_SEPARATOR.ZEND_DIR);
require_once('Zend.php');
Zend::loadClass('Zend_Feed');
Zend::loadClass('Zend_Filter_Input');
$link = mysql_connect('localhost', 'user', 'pwd')
or die('Could not connect: ' . mysql_error());
//echo 'Connected successfully';
mysql_select_db('phpeye') or die('Could not select database');
$feedChannel = array(
'http://www.phpdeveloper.org/phpdev.rdf',
'http://www.planet-php.net/rss/'
);
foreach ($feedChannel as $channel) {
readRssFeed($channel);
}
echo "Done!";
function readRssFeed($feedAddress){
try {
$rss = Zend_Feed::import($feedAddress);
} catch (Zend_Feed_Exception $e) {
// Feed 導入失敗
//echo "Exception caught importing feed: {$e->getMessage()}/n";
$msg = "Exception caught importing feed: {$e->getMessage()}/n ";
$dateTime = date("Y-m-d H:i:s",time());
$errMsg = $msg.' '.$dateTime."/n/n";
echo $errMsg;
file_put_contents('FeedReader.log',$errMsg,FILE_APPEND);
exit;
}
// 初始化保存 channel 數據的數組,$rss內部數據只能通過調用類方法才能訪問
$channel = array(
'title' => $rss->title(),
'link' => $rss->link(),
'description' => $rss->description(),
'items' => array()
);
$count=0;
// 循環獲得channel的item並存儲到相關數組中
foreach ($rss as $item) {
$channel['items'][] = array(
'title' => $item->title(),
'link' => $item->link(),
'description' => $item->description()
);
//標題和內容都需要轉義
$title = strip_tags(mysql_real_escape_string($item->title()));
$link = strip_tags($item->link());
$description = mysql_real_escape_string($item->description());
//先查詢數據庫看記錄是否已經存在,存在則不操作,否則向數據庫添加新記錄
$query = "select * from feedentry where entitle = '$title'";
//echo "<HR>SQL: ".$query."<P>/n/r";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$num_rows = mysql_num_rows($result);
if($num_rows > 0) {
//echo "The record already exists! ";
//do nothing...
}else{
$query = "insert into feedentry (entitle,link,endescription,addtime) values ('$title','$link','$description',NOW())";
//echo "<HR>SQL: ".$query."<P>/n/r";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$count++;
}
}
//zend::dump($channel);
$dateTime = date("Y-m-d H:i:s",time());
if($count>0){
$Msg = $count." entrys read successfully! ".$dateTime."/n/n";
echo $Msg;
file_put_contents('FeedReader.log',$Msg,FILE_APPEND);
}else{
$Msg = 'read nothing...'.$dateTime."/n/n";
echo $Msg;
file_put_contents('FeedReader.log',$Msg,FILE_APPEND);
}
}
?>
文件中除了RSS讀取,解析和入庫外,還有DEBUG和日誌功能。
數據表結構如下:
CREATE TABLE `feedentry` (
`id` int(11) NOT NULL auto_increment,
`entitle` varchar(200) NOT NULL default '',
`link` varchar(200) NOT NULL default '',
`endescription` mediumtext NOT NULL,
`category` varchar(50) NOT NULL default '',
`comments` text NOT NULL,
`publishtime` datetime NOT NULL default '0000-00-00 00:00:00',
`addtime` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) TYPE=MyISAM ;
呵呵
,把這個文件保存。然後利用Linux的Cron腳本讓它定時在命令行下運行,下面讓它每小時的40分運行一次:crontab -e
40 * * * * /usr/local/bin/php -q /www/phpeye/FeedReader.php
一個好用的Feed Reader就打造完成了。如果你想添加RSS頻道,可以自己在
$feedChannel這個數組中添加元素,非常方便,當然如果你有興趣,可以寫一個WEB界面來管理,那樣就更方便了。
改進:
這個Reader已經具備了核心功能,但是沒有完成頻道管理功能,你可以再建一個feedchannel數據表,並且在feedentry表中增加一個channelID字段,這樣就可以隨意增添管理Feed頻道了。
效果請看:http://www.phpeye.com
本文介紹的程序屬於PHPEye Blog中英翻譯平臺的一部份,該平臺尚在開發當中。
<END>