分享
 
 
 

使用Zend_Feed+Cron打造Feed Reader

王朝other·作者佚名  2006-11-29
窄屏简体版  字體: |||超大  

相信对于很多人来说,通过Bloglines,Google Reader这些阅读器订阅和浏览Blog已经是网络生活的一部份。如果你打算自己打造一个好用的Feed Reader,不妨试试Zend_Feed这个好用的类库。

首先大概的原理是读取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。解析XMLRSS文件遵循一定规范,你可以自己写个函数来解析,没什么难度,但有点繁琐。

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>

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有