php

位置:IT落伍者 >> php >> 浏览文章

基于PHP和AJAX创建RSS聚合器


发布日期:2023年06月11日
 
基于PHP和AJAX创建RSS聚合器

想象使用一个简单HTML文件来把一个请求发送到一个服务器端脚本收到一个基于该请求的定制XML文件然后把它显示给用户而几乎不需要刷新浏览器!本文作者将同你一起探讨怎样在普通Web应用程序中联合PHP和AJAX技术来创建实时的数据传输而不需要进行浏览器刷新

尽管本文所使用的是PHP语言但是请记住任何服务器端语言都会正常工作为了理解本文我假定你基本理解JavaScript和PHP或一类似服务器端语言

本文示例使用AJAX来把一请求从一个RSS馈送发送到一定制的PHP对象该PHP对象复制一份在本地服务器上的该馈送并返回这一路径该请求对象收到这一路径分析它并且把数据以HTML形式显示给用户这听起来涉及很多步骤其实它仅由个小文件组成之所以使用了个小文件是为了平衡它们各自特定的力量而使整个系统的处理极富效率性

有些读者可能会问为什么你要创建在本地服务器上的馈送的一个副本而不是简单分析最原始的馈送原因是这样以来可以允许绕过XML HTTP Request对象所强加的跨域限制后面我还会解释怎样创建这个定制的PHP对象但是首先让我们从表单创建开始

创建发出请求的表单

你要做的第一事情是在你的HTML的head标签之间包括你可能想使用的JavaScript和任何CSS文件我包括了一个式样表来实现该聚合器的最后布局并用一个JavaScript文件来发出请求和进行馈送分析

<link href=css/layoutcss rel=stylesheet type=text/css />

<script src=js/requestjs></script>

下一步创建一个表单它针对你所选择的一个RSS馈送发出请求我创建的表单只包括一个输入字段和一个提交该请求的按钮该请求的查询是一个字符串它由馈送输入值和一个将在服务器端被校验的口令字组成作为一个示例我使用了下面形式

password=mypassword

该代码在每次页面加载之时发出一次请求因此如果页面被刷新现有的在该输入域中的馈送串将在页面加载时被请求下面是一个表单数据的示例连同一些div标签用来显示已分析的馈送的特定结点

<body onload=javascript:makeRequest(requestphp?request= + documentfeedFormfeedvalue + password=mypassword);

<form name=feedForm method=post action=javascript:makeRequest(requestphp?request= + documentfeedFormfeedvalue + password=mypassword);

Enter a feed: <input type=text name=feed id=feed size=

<input type=submit name=submit value=Add Feed

</form>

<div id=logo></div>

<hr/>

<div id=copy></div>

<div id=details></div>

</body>

我所创建的这三个div标签是logocopy和details其中每一个都在布局样式表中有一个与之相关联的样式当我们分析馈送时将会用到它们但是我们首先需要能够存取我们所请求的馈送这可以使用我前面所提到的PHP对象来完成

创建定制的PHP对象

我用PHP创建了一个小型RSS类它在本地服务器上创建一个请求馈送的副本这样它可以为我们稍后要创建的XML HTTP Request对象所存取典型地你不能跨域请求一个文件这意味着你要请求的文件需要位于本地服务器上这个类是一种解决跨域问题的办法因为它创建该馈送的一个副本这个副本在本地服务器上被请求并且把本地路径返回到该馈送然后它由该Request对象来存取

这个类中唯一的方法是一个请求方法它仅有一个指向所请求的RSS 馈送的URL的参数然后它通过rss的名字来检查是否一目录位于本地服务器上如果不存在就创建一个并把其权限模式设置为这意味着该目录可读写当被设置为可读的时该目录就可以在以后被存取而当被设置为可写的时就可以把该馈送的一个副本写向本地服务器上的目录

//如果不存在目录就创建一个

$dir = rss;

if(!is_dir($dir))

{

mkdir($dir );

}

注意

在一台Windows机器上对于PHP 及以上版本中模式设置是不被要求的但是如果它存在的话它将被忽略因此我保留了它以备该工程被迁移到一台UNIX或Linux服务器上

在把馈送复制到该服务器前我们需要一个唯一的文件名我对这个完整的URL使用了md加密方法以确保所有馈送的名字是唯一的通过这个新的文件名它可以连接一个描述指向该文件的目录的字符串这将在创建该馈送的副本时使用

//创建唯一的命名

$file=md($rss_url);

$path=$dir/$filexml;

通过使用被定义在上面的路径和到原始的被请求的馈送的URL的参考现在我们能创建该文件的一个副本最后把该路径返回到该新文件作为对该请求的响应

//复制馈送到本地服务器

copy($rss_url$path);

return $path;

Following is the small yet powerful RSS class in its entirety:

<?php

class RSS

{

function get($rss_url)

{

if($rss_url != )

{

//如果不存在目录就创建一个

$dir = rss;

if(!is_dir($dir))

{

mkdir($dir );

}

// 创建一个唯一的名字

$file = md($rss_url);

$path = $dir/$filexml;

//复制馈送到本地服务器

copy($rss_url $path);

return $path;

}

}

}

?>

为了存取该PHP类中的方法需要有一个请求文件来担当到该类的一个接口这也正是我们正在请求的文件这个文件首先验证从该请求查询的一口令变量或者返回一条指定该请求者不是一名经授权的用户的消息或者用指向RSS馈送(该馈送在由请求方法处理后被复制到本地服务器)的路径作出响应为了响应该RSS馈送需要包含这个RSS对象并把它实例化并且需要通过使用被请求的馈送的URL作为一参数来激活请求方法:

<?

if($password == mypassword)

{

require_once(classes/RSSclassphp);

$rss = new RSS();

echo $rss>get($request);

}

else

{

echo You are an unauthorized user;

}

?>

GET/POST与AJAX相结合

为了POST请求我们首先需要创建该请求对象如果你没有创建请求对象的经验那么可以读一下我的文章《How To Use AJAX》或简单地研究一下本文的示例源代码一旦创建该请求对象就可以调用sendFeed方法并传递由表单所创建的URL

function sendFeed(url){

postonreadystatechange = sendRequest;

postopen(POST url true);

postsend(url);

}

一旦收到来自于PHP对象的响应并被正确加载则对与该响应相应的本地文件发出另一个请求在这种情况中postresponseText提供给我们该新文件的路径

function sendRequest(){

if(checkReadyState(post)){

request = createRequestObject();

requestonreadystatechange = onResponse;

requestopen(GET postresponseText true);

requestsend(null);

}

}

分析响应

由于RSS馈送之间的区别分析响应具有一定的挑战性一些含有包含标题和描述结点的图像而其它则没有因此当我们分析回馈时我们需要做一点检查来译解它是否包括一图像如果它包括一图像我们就可以与该馈送的标题和链接一起在image div标签中显示该图像

var _logo = ;

var _title = responsegetElementsByTagName(title)[]firstChilddata;

var _link = responsegetElementsByTagName(link)[]firstChilddata;;

_logo += <a href= + _link + target=_blank + _title + </a><br/>;

if(checkForTag(responsegetElementsByTagName(image)[]))

{

var _url = responsegetElementsByTagName(url)[]firstChilddata;

_logo += <img src= + _url + border=><br/>

}

documentgetElementById(logo)innerHTML = _logo;

我们不仅必须检查每个图像以显示它当遍历馈送中所有的项时我们还需要对之进行检查因为如果存在一个图像那么所有另外的标题和链接结点索引都将无法正常工作因此当发现图像标签时我们应该通过在每一次遍历中增加索引值(+)来调整标题和链接结点的索引

if(checkForTag(responsegetElementsByTagName(image)[]) i>){

var _title=responsegetElementsByTagName(title)[i+]firstChilddata;

var _link=responsegetElementsByTagName(link)[i+]firstChilddata;

}

else{

var _title =responsegetElementsByTagName(title)[i]firstChilddata;

var _link = responsegetElementsByTagName(link)[i]firstChilddata;

}

你可以使用checkForTag方法来检查是否存在特定的标签

function checkForTag(tag){

if(tag != undefined) {

return true;

}

else{

return false;

}

}

存在许多种进行馈送分析的可能性例如你可以把项赋到类别上并使得该类别可折迭这样用户就可以对其想观看的内容进行选择作为一个示例我使用日期来对项进行分类这可以通过译解是否针对一个特定项的pubDate不同于前一个项的pubDate并且相应地显示一新的日期来实现

if(i>){

var previousPubDate = responsegetElementsByTagName(pubDate)[i]firstChilddata;

}

if(pubDate != previousPubDate || previousPubDate == undefined){

_copy += <div id=detail + pubDate + </div><hr align=left width=%/>;

}

_copy += <a href=\javascript:showDetails( + i + );\ + _title + </a><br/><br/>;

documentgetElementById(copy)innerHTML += _copy;

注意上面的最后一部分是showDetails方法它用于当一用户从一个馈送中选择一特定的项时进行细节显示这个方法有一个参数(项索引值)这个索引用于发现在该馈送中details结点的索引

function showDetails(index){

documentgetElementById(details)innerHTML = responsegetElementsByTagName(description)[index]firstChilddata;

}

结论

使用AJAX发送查询字符串到一个服务器端脚本并检索一个基于该串的定制响应这对于任何web开发者都有实现的可能这样以来你的下一个web应用程序也将会充满了新的可能性

               

上一篇:PHP网络编程:删除帖子[1]

下一篇:PHP网络编程:搜索帖子[1]