先来了解什么是rss,rss也叫聚合内容,是Really Simple Syndication,是一种描述同步网站内容的格式。
打个比方,例如博客的更新,我们不知道博客什么时候更新,每次我们都要经历一些繁琐的链接才能点到某位好友的博客,查看是否有更新,这个取到我们想要的信息这个过程很繁杂。如果这个网站提供了rss服务,我们可以直接用rss阅读器,查看是否有更新,甚至更新的内容
rss阅读器,google reader是号称最纯粹的rss阅读器
那到底rss是什么呢?
其实rss就是一个有自己一套标准的xml数据,它就是一个xml文件。某个网站提供rss服务,其实就是这个网站提供了一个xml文件,rss阅读器要做的就是读取这个xml文件,把信息取出来,读取rss本质其实就是读取xml文件
php读取rss(其实就是读取xml),要准备的知识:对xml格式的理解(以前的博客有介绍过),php 对文件的读取,php对xml解释函数的理解
php中xml解释器函数:
$parser=xml_parser_create();//建立xml解释器
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);//对解释器进行设置
函数 xml_parser_create() 建立一个新的 XML 解析器并返回可被其它 XML 函数使用的资源句柄。
bool xml_parser_set_option ( resource parser, int option, mixed value )
parser
指向要设置选项信息的 XML 解析器的指针。
option
要设置的选项名称。请参考下文。
value
要给选项设置的新值。
option的选项:
XML_OPTION_CASE_FOLDING | integer | 控制在该 XML 解析器中 大小写折叠(case-folding) 是否有效。其默认值为有效。 |
XML_OPTION_SKIP_TAGSTART | integer | 指明在一个标记名前应略过几个字符。 |
XML_OPTION_SKIP_WHITE | integer | 是否略过由白空字符组成的值。 |
XML_OPTION_TARGET_ENCODING | string | 设置该 XML 解析器所使用的目标编码(target encoding)方式。其默认值和由xml_parser_create() 函数设置的源编码(source encoding)方式相同。支持的目标编码方式有ISO-8859-1、US-ASCII 和 UTF-8。 |
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
这个代码是对$parser这个解释器设置了XML_OPTION_SKIP_WHITE选项,值为1,即略过由空白字符组成的值
php的文件读取函数:
fopen
fopen可以打开一个文件或一个url
格式为
$fp=fopen("打开的文件或者url","打开方式");
打开的方法有如下:mode | 说明 |
---|---|
'r' | 只读方式打开,将文件指针指向文件头。 |
'r+' | 读写方式打开,将文件指针指向文件头。 |
'w' | 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 |
'w+' | 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 |
'a' | 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。 |
'a+' | 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。 |
'x' | 创建并以写入方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的open(2) 系统调用指定O_EXCL|O_CREAT 标记是等价的。此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。 |
'x+' | 创建并以读写方式打开,将文件指针指向文件头。如果文件已存在,则 fopen() 调用失败并返回FALSE,并生成一条 E_WARNING 级别的错误信息。如果文件不存在则尝试创建之。这和给 底层的open(2) 系统调用指定O_EXCL|O_CREAT 标记是等价的。此选项被 PHP 4.3.2 以及以后的版本所支持,仅能用于本地文件。 |
<?php
$handle = fopen("/home/rasmus/file.txt", "r");
$handle = fopen("/home/rasmus/file.gif", "wb");
$handle = fopen("http://www.example.com/", "r");
$handle = fopen("ftp://user:password@example.com/somefile.txt", "w");
?>
xml转为数组的函数
int xml_parse_into_struct ( resource parser, string data, array &values [, array &index] )
注意成功转换返回的是“1”,失败返回的是“0”
resource parser:xml解释器
string data:要转换的xml字符串数据
$array:要转换到的数组
还要准备一个php数组的遍历方法
foreach($array as $value);
foreach($array as $key=>$value)
第一种形式得到的只是数组的每个元素的值,存放在$value中,第二种形式得到的是数组下标和相应的元素值,分别存放在变量$key和$value中
好,准备好这些知识后,我们就可以来动手了
先来创建一个 xml文件(测试用)
test.xml
<?xml version="1.0" encoding="utf-8"?>
<msg>
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don't forget the meeting!</body>
</note>
<note>
<to>eqyun</to>
<from>jiao</from>
<heading>hi</heading>
<body>hell to you</body>
</note>
</msg>
测试的php文件test.php输出结果为:
<?php
//无效 xml 文件
$xmlfile = 'test.xml';
// 打开文件并读取数据
$fp = fopen($xmlfile, 'r');
$xmldata = fread($fp, 4096);
$parser=xml_parser_create();
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
xml_parse_into_struct($parser,$xmldata,$values);
xml_parser_free($parser);
$i=1;
foreach($values as $content){
echo "第".$i."条";
$i++;
echo "</br>";
print_r($content);
echo "</br>";
}
?>
第1条
Array ( [tag] => MSG [type] => open [level] => 1 )
第2条
Array ( [tag] => NOTE [type] => open [level] => 2 )
第3条
Array ( [tag] => TO [type] => complete [level] => 3 [value] => George )
第4条
Array ( [tag] => FROM [type] => complete [level] => 3 [value] => John )
第5条
Array ( [tag] => HEADING [type] => complete [level] => 3 [value] => Reminder )
第6条
Array ( [tag] => BODY [type] => complete [level] => 3 [value] => Don't forget the meeting! )
第7条
Array ( [tag] => NOTE [type] => close [level] => 2 )
第8条
Array ( [tag] => NOTE [type] => open [level] => 2 )
第9条
Array ( [tag] => TO [type] => complete [level] => 3 [value] => eqyun )
第10条
Array ( [tag] => FROM [type] => complete [level] => 3 [value] => jiao )
第11条
Array ( [tag] => HEADING [type] => complete [level] => 3 [value] => hi )
第12条
Array ( [tag] => BODY [type] => complete [level] => 3 [value] => hello to you )
第13条
Array ( [tag] => NOTE [type] => close [level] => 2 )
第14条
Array ( [tag] => MSG [type] => close [level] => 1 )
终于明白 xml转数组后是什么形式的了
基于这个理解,我们就可以处理rss了,开始前我们来看下rss标准
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
<channel>
<title>本站点频道的标题</title>
<link>链接地址</link>
<description>站点频道描述信息</description>
<item>
<title>文章1</title>
<link>文章1链接地址</link>
<description>文章1内容简介</description>
</item>
<item>
<title>文章2</title>
<link>文章2链接地址</link>
<description>文章2内容简介</description>
</item>
</channel>
</rss>
根节点<channel>,然后有若干<item>子节点,<item>里面有<title><link><description>子节点
好,我们开始吧,我就用我们的项目经理的博客做实验,sinceow的博客 rss地址是http://blog.youkuaiyun.com/sinceow/Rss.aspx
test_blog.php
<?php
header('Content-Type:text/html;charset= UTF-8');
if (!empty($_POST['name'])){
$name=$_POST["name"];
$url = "http://blog.youkuaiyun.com/".$name."/Rss.aspx";
$xmldata = "";
$fp = fopen($url,"r");
if($fp==false){
echo "没有此用户名";
}
else {
while ( !feof($fp) ) {
$xmldata .= fgets($fp,4096);
}
fclose($fp);
$parser = xml_parser_create();
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
xml_parse_into_struct($parser,$xmldata,$values,$idx);
xml_parser_free($parser);
$item = false;
$result=null;
$num=0;
foreach ($values as $val) {
$tag = $val["tag"];
$type = $val["type"];
$tag = strtolower($tag);
if ($tag == "item" && $type == "open") {
$item = true;
$num++;
} else if ($tag == "item" && $type == "close") {
$result .= "<a href='".$link."' target=_blank>".$title."</a><br />";
$item = false;
}
if($item){
if ($tag == "title") {$title = $val["value"];}
if ($tag == "link") {$link = $val["value"];}
}
}
echo "关于".$name."的博客:"."</br>";
echo $result."<br />";
echo '共'.$num.'篇';
}}
else {
echo "<form action='test_blog.php' method='post'>";
echo "</br>";
echo "<input type='text' name='name'/>";
echo "</br>";
echo "<input type='submit' value='提交'/>";
echo "</br>";
echo "</from>";
echo "提示各组员id:</br>";
echo "sinceow eqyun2012 qierjiang qq123407476";
}
?>
由前面的test.xml测试我们知道,foreach后的每一个数组都有"tag"和"type”标签,但未必有"value”标签,而我们要读的数据仅仅是item里面的数据,所以用一个$item来判断是不是item节点里面的内容,如果是,就赋值$title,link标签的内容"value“给输出结果集,用于输出
如果你对rss结构看不清楚的话,可以用以下函数看下输出内容
<?php
header('Content-Type:text/html;charset= UTF-8');
$xmlfile = "http://blog.youkuaiyun.com/sinceow/Rss.aspx";
// 打开文件并读取数据
$fp = fopen($xmlfile, 'r');
$xmldata = fread($fp, 4096);
$parser=xml_parser_create();
xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);
xml_parse_into_struct($parser,$xmldata,$values);
xml_parser_free($parser);
$i=1;
foreach($values as $content){
echo "第".$i."条";
$i++;
echo "</br>";
print_r($content);
echo "</br>";
}
?>
主要是rss结构的了解,xml 转数结构的了解,欢迎大家交流