Ajax 和 XML: 使用 Ajax 实现打分评级和添加评论功能

来源:互联网 发布:网络教育大专本科 编辑:程序博客网 时间:2024/06/04 19:57
在由人员驱动的 Web 时代,允许读者评级和评论站点内容的功能是必不可少的。通过本文探索如何使用 Ajax 在站点中加入评级和评论功能。

我们大家都喜欢 评定内容的等级。我认为这是人类与生俱来的秉性。我和我的女儿都喜欢去电影院看电影;虽然她过去对电影的内容毫不讲究,不过现在却挑剔了许多,因为她已经 四岁了。我曾经教过她使用 “大拇指朝上” 和 “大拇指朝下” 的评级系统 à la Ebert 和 Roeper。(她曾经为 Shrek the Third 这部电影竖起了大拇指。)我认为这就是人们乐于在因特网上评论产品和文章的原因所在。


Y4e`B,P/S@IZ0

本文将介绍如何结合使用 MySQLPHP、Prototype.js 和 Asynchronous Javascrīpt™ and XML (Ajax) 在站点中添加简单的评级和评论功能。

评级系统

虽然我女儿乐于使用大拇指进行评级,不过大多数人更倾向于另一种略有差别的评级系统:五星级评级系统,其中一颗星为最差,三颗星为中等。在本例中,我将使用五星级评级系统对电影进行评级。您也可以将本文中评级系统应用于需要的内容 — 如文章、产品和播客。

清单 1 显示了本例所使用的模式,其中创建了一个初始的 movies 表。这相当简单:在表中定义一个自动递增的电影 ID 和电影名称。然后,创建一个 rating 表保存电影的投票结果。这个表通过 movie_id 与 movie 表绑定在一起,表中还包含一个 rating 字段,取值范围为 1 到 5。

PHPChina 开源社区门户2Nri nQDE4yS
清单 1. rating.sql
y+^}Q th)Y;}s0
                
.t Rgb|)g0DROP TABLE IF EXISTS movies;PHPChina 开源社区门户N+MJ,HE E$Hk
PHPChina 开源社区门户(k h[?+O0m4O
CREATE TABLE movies (PHPChina 开源社区门户5Def,c5F2e7e1M
movie_id INTEGER NOT NULL AUTO_INCREMENT,
d+O*U bZ%ZH0 name VARCHAR( 128 ) NOT NULL,PHPChina 开源社区门户[rBg'BO0~2h
PRIMARY KEY ( movie_id )
"HE'K(ed}�`0);
j`yZ7xd0
?ZE?V3a2f)b0I0DROP TABLE IF EXISTS ratings;PHPChina 开源社区门户z`s~d5ok6`//s1l
PHPChina 开源社区门户^ @*[kg
CREATE TABLE ratings (PHPChina 开源社区门户$n?'dK2D"WgD
movie_id INTEGER NOT NULL,PHPChina 开源社区门户V-Sr(v D*^g/b8N
rating INTEGER NOT NULL
1q2v2kG1P8_0Z_2e@0);PHPChina 开源社区门户Kv%P0hpd7VT
PHPChina 开源社区门户 O%DcT U da'~

如果要执行 “一人一投” 的模式,则必须在 ratings 表中添加一个用户 ID,从而确保每个人只能对一部电影评定一次。考虑到程序的简单性,我并没有实现这一功能。

要将模式导入数据库,必须先创建一个数据库,然后再添加模式。可以使用以下命令行指令完成这些操作:

% mysqladmin create comments
t^/u"km"nGO0% mysql comments < ratings.sqlPHPChina 开源社区门户Z+S[8d7M[%j1k.u

V8W cd G;T0

您可能需要根据您的 MySQL 安装添加登录凭证。

完成这些步骤之后,我们需要使用一个页面显示可用的电影,并为每部电影添加一个评级页面链接。清单 2 显示了这个索引页面。

PHPChina 开源社区门户;vv _8Nzq:yC
清单 2. index.phpPHPChina 开源社区门户6O"o2J2O-rpji(hY
                
3se!S"@)@0}qA~]0<html>
q w)jj&E5R,Z0<body>
h2@|o s]*p0<?php
0u/e3T}9t EfS0require_once("DB.php");PHPChina 开源社区门户1cKT3f']?)B,b

+e;uM6h6}3SN0$db =& DB::Connect( 'mysql://root@localhost/comments', array() );
@)I,x*a0zd*^ K)i0if (PEAR::isError($db)) { die($db->getMessage()); }PHPChina 开源社区门户w%p(M"l(A+b:R
PHPChina 开源社区门户 Q^BS2L[ Na
$res = $db->query( 'SELECT * FROM movies' );
6_,ra.u�h2i0while( $res->fetchInto( $row ) )
+N0O-E;@N|_m,p0{
YD'Zgjf Sp HvcF0?>PHPChina 开源社区门户7{g7/on d^
<a href="rate.php?id=<?php echo($row[0]) ?>"><?php echo($row[1]) ?></a><br/>
?"^K/N+nm @0i0<?php
lN;bPR)aCY0}
:@G6J:X.v~,iZ0?>
4P!LoJT3C$w0</body>
M9LM/f7v7su0</html>
5Fwt4O6jP0
PHPChina 开源社区门户A l5V wJrv

简单起见,我使用结构化查询语句(Structured Query Language,SQL)语句在 movies 表中加入了一些著名的电影。下载 部分提供了示例代码。您可以在索引页面中看到这些电影,如 图 1 所示。


7?.`}I.X0图 1. 电影列表PHPChina 开源社区门户dK'W fw6M4F
电影列表 PHPChina 开源社区门户3K i [$t7R

如果您无法通过示例代码显示出这个清单,可能您的机器未使用 PEAR 存储库安装 DB 模块。要安装它,只需在命令行中运行以下命令:

% pear install DB
vn} D4S|-krY0

[ RN i o0

现在,电影列表可以正常显示了。接下来,我们将实现电影评级页面,这个页面还可以显示当前投票的总排名和日平均排名。实现这些功能的 rate.php 页面代码如 清单 3 所示。

PHPChina 开源社区门户�r8e}mf$qqQB
清单 3. rate.php
;iM^ afu4d;[H6b0
                
C3Ao�L7} p5e0<?phpPHPChina 开源社区门户/`M!n~{F
require_once("DB.php");PHPChina 开源社区门户-np RmNU1J
PHPChina 开源社区门户7yp8j*|K5E U
$db =& DB::Connect( 'mysql://root@localhost/comments', array() );PHPChina 开源社区门户'jG)B}j U
if (PEAR::isError($db)) { die($db->getMessage()); }
#P3YQv;}M?0PHPChina 开源社区门户r;Ui�Nf:i l
$id = $_GET['id'];PHPChina 开源社区门户L#[lk3rk#U4}Rl
$title = '';PHPChina 开源社区门户w.HQ!w"i.ASIV,j
PHPChina 开源社区门户*v:/}{ ia
$res = $db->query( 'SELECT name FROM movies WHERE movie_id=?', array( $id ) );PHPChina 开源社区门户B:c2}p7um3T
while( $res->fetchInto( $row ) ) { $title = $row[0]; }PHPChina 开源社区门户 TBW pMH(A
?>PHPChina 开源社区门户J%o8X!y?[-mCv U
<html>
Xd2g5xr9k0<head>
]u_~+m-w,{P0<title><?php echo($title); ?></title>
:Z dhHG0<scrīpt src="prototype.js"></scrīpt>
9|oF/Y /E6|N0q0<scrīpt>PHPChina 开源社区门户0~/L,C4_D3M#u
function rate( value ) {PHPChina 开源社区门户8u3W!Ka7qQ
new Ajax.Updater( 'rating', 'ratemovie.php?id=<?php echo($id)?>&v='+value );PHPChina 开源社区门户3j;pM+{,Gq
}PHPChina 开源社区门户z)A*H-@(YL-K0CY&^
</scrīpt>PHPChina 开源社区门户H*O&t u$M*X,Sz{
</head>
dh s)B;Y!{'U5w0<body>
J#}~#Rh_'K0<h1><?php echo($title); ?></h1>PHPChina 开源社区门户ET?9A/H2_l"o

i"TF0e p'X%G~3S+F0<div id="rating">PHPChina 开源社区门户-J8Mw{3F9Y2C)H1i;Z
<img src="star_off.gif" ōnclick="rate(1)"></img>PHPChina 开源社区门户G(d"k`] h4j,Q
<img src="star_off.gif" ōnclick="rate(2)"></img>PHPChina 开源社区门户X,E(fLF1BF,U7e`0B
<img src="star_off.gif" ōnclick="rate(3)"></img>
Nkw5hJ;G_e3x0<img src="star_off.gif" ōnclick="rate(4)"></img>PHPChina 开源社区门户J A6u8jyK
<img src="star_off.gif" ōnclick="rate(5)"></img>PHPChina 开源社区门户*eK#q2J$yS*IEy,_YL
<br/><br/>
bt3u9?+de L0<?php
e)p*E,Epc0
ev-PD#N0$res2 = $db->query(PHPChina 开源社区门户)mX,/KOqK"@3KV
'SELECT count( rating ), sum(rating ) FROM ratings WHERE movie_id=?',PHPChina 开源社区门户pQ'l ug6x
$idPHPChina 开源社区门户7h)Y({_,WOBCw
);
p6Y6A;M8zN&[o8^5r/0while( $res2->fetchInto( $row ) )PHPChina 开源社区门户2U ekR0Cmj4w
{
1p'I6aAYGw0?>
^%g.}nMp0Votes: <?php echo($row[0]); ?><br/>
5Ax z}6}-I;Sn0Average Rating: <?php echo($row[1]/$row[0]); ?>PHPChina 开源社区门户FB/CZ |4@*zwC
<?phpPHPChina 开源社区门户.Y,bBt;N*k3G
}PHPChina 开源社区门户 TM%? cn;[| x0C
?>PHPChina 开源社区门户!z3C?l^q
</div>PHPChina 开源社区门户0TY Db&N

CgT7Y(/*i]*C0</body>
V;d%n2f/M g0</html>
3ELQw.G~7_X#?0

5F?q*gZ.P0

文件顶部的代码通过传递 ID 参数获得电影标题。在脚本中间部分,我们导入了 prototype.js 库并创建了一个 rate() Javascrīpt 函数,这个函数将通过 Ajax 使用 Prototype 库调用 ratemovie.php 页面。然后,我们添加了一组星形图像,点击这些图像时脚本将调用 rate() 函数。

在文件底部的代码中,我们运行了一个快速查询获取投票数和指定电影的投票总数。然后,在页面中显示出这些数据,这样读者就可以知道该电影的评级情况。

清单 4 中的 ratemovie.php 脚本负责在数据库中添加评级,然后返回一些超文本标志语言(Hypertext Markup Language,HTML)代码,以替换原始页面中的投票星级和评论数。


2^Ls5f(j0清单 4. ratemovie.phpPHPChina 开源社区门户/vWj/^/H5g
                PHPChina 开源社区门户+s1klJ0B}3Cl
<?phpPHPChina 开源社区门户c9Q}'}#_2m
require_once("DB.php");
n)Ir6x!uE9},`0
-SRkaZ{f*X%L0$db =& DB::Connect( 'mysql://root@localhost/comments', array() );
3V(B7VK V*m0if (PEAR::isError($db)) { die($db->getMessage()); }PHPChina 开源社区门户/x&RYt(jux/f
PHPChina 开源社区门户Z'HZD;Fj6V
$v = $_GET['v'];
y)K`9l g$hno0$id = $_GET['id'];
&l(d+}6F!?K"cM/v&i0PHPChina 开源社区门户NRG~7w h
$sth = $db->prepare( 'INSERT INTO ratings VALUES ( ?,? )' );
:{WL#y"K]Y0$db->execute( $sth, array( $id, $v ) );PHPChina 开源社区门户;}Qe�i�hG e7Q
?>
1ze6Np*A:WZ0<img src="star_<?php echo( ($v>0)?'on':'off' ) ?>.gif"></img>PHPChina 开源社区门户,C*h)|{m)N*} N
<img src="star_<?php echo( ($v>1)?'on':'off' ) ?>.gif"></img>PHPChina 开源社区门户mo'h,C|8FT
<img src="star_<?php echo( ($v>2)?'on':'off' ) ?>.gif"></img>PHPChina 开源社区门户-@s5@sm$v2N Wk
<img src="star_<?php echo( ($v>3)?'on':'off' ) ?>.gif"></img>
XM6pkjhAE0<img src="star_<?php echo( ($v>4)?'on':'off' ) ?>.gif"></img>
;fp#d!N"|t_1c0<br/><br/>PHPChina 开源社区门户S:}W,E{P-g#j:m
<?php
oz%a,] |E5U0$res2 = $db->query(
iz C$uU6}1Dx$l-C7f0 'SELECT count( rating ), sum(rating ) FROM ratings WHERE movie_id=?',
8/-ud3hY)]0 $id
)Q.sD2mua0);
/v9QWM`;t0while( $res2->fetchInto( $row ) )
*BO+W"j1} b0{
.]Z*CD7L8TD2d0?>
?_2S)eH/ye:a0Votes: <?php echo($row[0]); ?><br/>
n)FK ^F(r6Z0Average Rating: <?php echo($row[1]/$row[0]); ?>PHPChina 开源社区门户-/atcYW
<?php
i/o4}*T'f0}
G%Od%lOJ0?>
,@(Oq�ts y Ri3O0
PHPChina 开源社区门户 w;TMIZ'v_l

图 2 显示了运行中的评级页面。

PHPChina 开源社区门户(x7~2I$Mi3v
图 2. 评级页面PHPChina 开源社区门户h3wh2tl1RT
The rating page PHPChina 开源社区门户/ g&JkGq9F�u(_

单击页面的中星形图案时,投票将添加到数据库中;星形图案、投票和平均评级的 HTML 代码会发生改变,从而反映出投票已添加。

理想情况下,我希望能够在主页上看到所有电影的评分情况。清单 5 中的新版索引页面实现了这一功能。


Jx9c,v~K.V*Z0清单 5. index2.php
"yh"IE,u#e ^JD)l3v0
                PHPChina 开源社区门户d:p5G]�vE)ES
<html>
"D2k/K /B&s0<body>PHPChina 开源社区门户6e e`j3I#ks9f
<table>PHPChina 开源社区门户Kp?.A.D F2qa
<?php
Xx/e ~hNlv0require_once("DB.php");PHPChina 开源社区门户d'vXvkT4L1O
PHPChina 开源社区门户 On'A-~^|#d(@
$db =& DB::Connect( 'mysql://root@localhost/comments', array() );
Qk#W5X(j]a0if (PEAR::isError($db)) { die($db->getMessage()); }
/A1X!R-^|!vA5aNU0PHPChina 开源社区门户?.U1].?w2UO v4ef3}]~
$res = $db->query( 'SELECT * FROM movies' );
9` x3^d6o$BM s0while( $res->fetchInto( $row ) )
-X teU&|f ox6Bu0{
K9u:U$a*Aj,x0
p'l7Z${ WSc�x0$res2 = $db->query(
Vz#x e"lv0 'SELECT count( rating ), sum(rating ) FROM ratings WHERE movie_id=?', $row[0]
*[XsRXh ZK0);
)|^&DE/Qa(y0$rating = 0.0;PHPChina 开源社区门户Pxp5N6M }wCHk2[W
while( $res2->fetchInto( $row2 ) ) { $rating = $row2[1] / $row2[0]; }PHPChina 开源社区门户9y!g0hbsO/)`
?>PHPChina 开源社区门户~~|Q_ X-@0V,nc
<tr><td align="center">PHPChina 开源社区门户-/-ue2[2wf Gy-] hR
<?php echo( $rating > 0 ? $rating : 0 ) ?>PHPChina 开源社区门户tw-Y:o6f&_
<td><td>PHPChina 开源社区门户0F_5qsB
<a href="rate2.php?id=<?php echo($row[0]) ?>"><?php echo($row[1]) ?></a>PHPChina 开源社区门户+a7i;i2_l w%SW7as
</td></tr>PHPChina 开源社区门户�W~4N/mF/H$b Z
<?phpPHPChina 开源社区门户Yd!@"M.V3k
}
"A!H!r:{s9J ['f�so0?>PHPChina 开源社区门户.Rl$t+Qdd1Qf;W
</table>PHPChina 开源社区门户Y [/n0v+B3X3u
</body>
` vF�BW,]7c+F0</html>
U sq�E|_#V0

m3{ L%L,l/Vc0

从 图 3 中可以看出,各个电影的评级情况都在新版的索引页面中显示出来了。

PHPChina 开源社区门户7q7h/A|rJ
图 3. 更新后的电影页面
y*_X1s|-Jz0 更新后的电影页面 PHPChina 开源社区门户VOps Jf8w�p6{

使用 Ajax、PHP、MySQL 和非常方便的 Prototype.js Javascrīpt 库实现投票模式就这么简单。

在下一个示例中,我们将实现电影评论功能。

PHPChina 开源社区门户6a:oB�E S^

PHPChina 开源社区门户"thi}at

评论

Web 上的评论系统形式各异,从极其简单的博客评论系统(可以对博客条目发表一连串的评论)到异常复杂的主题评论系统(比如 Slashdot 上的评论系统),不一而足。

本例所使用的评论系统比较简单。您可以根据需要对它进行适当的调整。

首先,在已有数据库模式中添加一个表,如 清单 6 所示。


wQ_![P6V*e~0清单 6. comments.sql
%M Gg h_Y5H'N0
                
qJxd}IW8yr0DROP TABLE IF EXISTS comments;PHPChina 开源社区门户*H/}v2` x8j/C~
CREATE TABLE comments (PHPChina 开源社区门户-r9K)PKC�R)xI
movie_id INTEGER NOT NULL,
9CPaR_K5f C0d0 email VARCHAR(255) NOT NULL,
/.zzvX5yH'B0 name VARCHAR(255) NOT NULL,PHPChina 开源社区门户?d#E#j2rd5ZL
comment TEXT NOT NULL
q Q L_/_(UF#q#`0);
"`lp*u~%q2t;R Na0

VcQ!M rn`X'F"n5Y0

所添加的是 comments 表,这个表通过 movie_id 字段与电影关联在一起。表中定义了一个电子邮件地址、评论者名称和评论文本。这是一个相当基本的评论系统,类似于 WordPress 和 MoveableType 博客软件上的评论系统。

如果想要创建一个主题评论系统,则需要在表中添加一个自动递增的 ID 字段,然后使用一个可为空的 parent_id 字段指向各个评论的父级评论。如果 字段为空,则这个评论是顶层评论。

要在评级页面中加入评论功能,我们需要在页面底部包含一些额外的脚本。清单 7 显示了这个新的 php 代码。

PHPChina 开源社区门户5nzs4a#my4wj$?
清单 7. rate2.php
(["h,v'{1g(XB0
                PHPChina 开源社区门户0^e%u;Yh9F3P
...PHPChina 开源社区门户&Q:/-RI B+W`EZ
<h2>Comments</h2>
}X2}RH;p+rPs)a0<div id="comments">PHPChina 开源社区门户/Gh4_@i wMT
<?phpPHPChina 开源社区门户|I#G6MT
$res3 = $db->query(PHPChina 开源社区门户-Y%? qf*KZ
'SELECT * FROM comments WHERE movie_id=?',
@/NTqp0 $id
"r?#S.Vd$d!K3{7K0);
n;k%{`WR*}1K q0while( $res3->fetchInto( $row3 ) )PHPChina 开源社区门户�mq)T/&j5w0Jrm
{
/@0f|2gB*X@0c0?>
(v0P @ D/&@G3E*c0P0<div>PHPChina 开源社区门户RP&tw�`U#lX
<a href="mailto:<?php echo($row3[1]) ?>"><?php echo($row3[2]) ?></a> says:PHPChina 开源社区门户/q1V h8J:U#C
'<?php echo($row3[3]) ?>'
P"C/k9@~5/8oV0</div>
3bR r;W2C0<?phpPHPChina 开源社区门户O+e(@:X/P7{%n
}
:m8|(h!y:y4kv0?>PHPChina 开源社区门户-Bg*XB3S}d /
</div>
x!G }Kk6{0
?4v)r#l8O&@0<div style="margin-top:20px;">Add your own comment:</div>
eP a�H1f_*Pm-N0PHPChina 开源社区门户4vP4C.v /}&h.}"Yt
<form id="cform">PHPChina 开源社区门户n/zbO6J0Q
<input type="hidden" name="id" value="<?php echo($id)?>">PHPChina 开源社区门户(Wd7^1Re9`0Ds [
<table>
+x4?3D4@_Dr!ht$M:z0<tr><td>Name:</td><td><input type="text" name="name"></td></tr>
9{R}&} s h)/)dEJ0<tr><td>Email:</td><td><input type="text" name="email"></td></tr>
3P8~LS lM9f0<tr><td>Comment:</td><td><textarea name="comment" id="comment_text"></textarea></td></tr>
n}7XI'`j+s}xWW s0</table>PHPChina 开源社区门户$z@'Y!YG*| /)`"i
</form>
e{1C;Owrx5F0<button ōnclick="addcomment()">Add Comment</button>PHPChina 开源社区门户W H:fy1l

`*p�_*g v0<scrīpt>
Wk r{X0function addcomment()PHPChina 开源社区门户/eHy6eJ
{PHPChina 开源社区门户x(o!_l6u:PQP
new Ajax.Updater( 'comments', 'addcomment.php',
:?Js7L0d,Yh0 {PHPChina 开源社区门户 o~e t3t { {G-p$d
method: 'post',PHPChina 开源社区门户w*z_{y�Q
parameters: $('cform').serialize(),PHPChina 开源社区门户;e0Z5o)E6u
onSuccess: function() {
7A6w)j5`1g0 $('comment_text').value = '';
:UH V9d'fm(DA%|0 }PHPChina 开源社区门户 W8JnH:@9`
} );PHPChina 开源社区门户#](uG2b"v-|o
}PHPChina 开源社区门户2m3_ z0O [
</scrīpt>
iw`/F?.b0</body>
&d/H:[2vz8O,t)aI/0</html>PHPChina 开源社区门户6o/~)I+e9Z:A

vbtZ]0

脚本首先使用数据库中关于该电影的评论填充 “comments” <div> 标记。 然后,在标准 HTML <form> 标记中包含评论名称、评论者电子邮件和评论内容的字段。form 标记中还包含一个隐藏值(当前所查看电影的 ID),从而评论添加脚本知道应该将这个评论指派给哪部电影。

表单下面的 Add Comment 按钮将调用 addcomment() Javascrīpt 函数。这个函数使用了 Prototype.js 库中的 Ajax.Updater 对象来调用 addcomment.php 脚本。它使用了非常方便的 serialize() 函数对名称、电子邮件地址和评论内容进行打包,这个函数也是由 Prototype.js 提供的。

如果评论成功,代码会重置评论字段的文本,这样可以允许用户随意添加任意数量的评论,而不用重新输入名称和电子邮件地址。

清单 8 显示了 addcomment.php 脚本。


S'Rw,|&S~A0清单 8. addcomment.phpPHPChina 开源社区门户b0/)nb:Hc(/
                PHPChina 开源社区门户p_T%O|,r6@Ts
<?phpPHPChina 开源社区门户GUT'lJ5Fj/Mj
require_once("DB.php");
/gQ/|0M2Lc`0PHPChina 开源社区门户e{Q'Ealy
$id = $_POST['id'];
O+T&c6bk&U2P0PHPChina 开源社区门户(k*cH$W5Ca
$db =& DB::Connect( 'mysql://root@localhost/comments', array() );
7tC1U+i,D7ea a qo u0if (PEAR::isError($db)) { die($db->getMessage()); }
@?Vc&gE.A�Y-J0
#zB&w"/mgH0$sth = $db->prepare( 'INSERT INTO comments VALUES ( ?, ?, ?, ? )' );PHPChina 开源社区门户R&JY.Y�ZKIr^;p&Q
$db->execute( $sth, array( $id,
FF OxoAh0 $_POST['email'], $_POST['name'], $_POST['comment' ] ) );
;I0O,S1SHR0
o'X)}�R2B6f/n)I0$res = $db->query('SELECT * FROM comments WHERE movie_id=?', $id );PHPChina 开源社区门户�``/}q&VQ{
while( $res->fetchInto( $row ) )PHPChina 开源社区门户k6` ade&E"or
{PHPChina 开源社区门户/}K+v#Cx+b
?>PHPChina 开源社区门户e�bp-]nS@/c`
<div>PHPChina 开源社区门户o/Q&B6f
<a href="mailto:<?php echo($row[1]) ?>"><?php echo($row[2]) ?></a> says:PHPChina 开源社区门户4x]#w5hD&S
'<?php echo($row[3]) ?>'
6hqHcL$nV?b F0</div>
!XR�X:?x@R0<?php
lk u&H$BO.cH0}PHPChina 开源社区门户?'ROi0H&sT;~;O
?>
2[b|7QT c T0

'{:[R4wg/]:jc0

首先,脚本将 POST 数据中指定的评论内容添加到数据库中。然后,将所有的评论内容作为 HTML 代码输出,其方式与原始评级页面一样,只不过这次页面中额外显示了用户所提供的评论。

新的评级页面如 图 4 所示。


H5R;^#nh%OA&c/R J0图 4. 更新后的评级页面,具有评论功能。
/BK0X"c&TId tZ0 新的评级页面 PHPChina 开源社区门户F'p*kyjEK

这个评论系统可以即时地向用户反馈信息。用户单击 Add Comment 时,页面会立即更新评论内容。系统还可以显示出其他用户在这期间提交的评论。

您可能需要扩展这个示例,使服务器可以自动更新评论部分。当然,您大可不必调用 addcomment.php 来完成这点。可以使用另一个脚本来返回评论,而不必添加新脚本。为此,Prototype.js 提供了一个 Ajax.PeriodicalUpdater 类,使用这个类中定义的 ID、刷新率和 URL 可以根据需要刷新 Web 页面中的任何部分。


-LyCj)`7|S(u0


8vv0be7Vp CF0

添加 RSS 提要

扩展该示例的另一种简单的方法是将电影列表的内容和排名作为 RSS 导出。实现这一功能的代码如 清单 9 所示。

PHPChina 开源社区门户^[B@XC'Q
清单 9. rss.php
Z1I!Q!A;L+uos0
                PHPChina 开源社区门户6tx t-o&i5B^0N
<?phpPHPChina 开源社区门户.Zi7oc2s!T*@d9r6J:~
header( "content-type:text/xml" );PHPChina 开源社区门户 M5|$l%r6W&`b5/_
?>PHPChina 开源社区门户+b0c,dc9a
<rss version="0.91">
9Q�XPxg0<channel>
-W-z&znu9E#g(q {0<title>Movie rankings</title>
l%WnOJ0DY(Q8V0<link>http://localhost/comments/rss.php</link>
?)Q:J2a8Uw0<?phpPHPChina 开源社区门户%Z G JvoRv E U+W
require_once("DB.php");PHPChina 开源社区门户mLK%cQS
PHPChina 开源社区门户LT/,/K/CW�|
$db =& DB::Connect( 'mysql://root@localhost/comments', array() );
mx4a Z]}0if (PEAR::isError($db)) { die($db->getMessage()); }PHPChina 开源社区门户eHg j*f
PHPChina 开源社区门户A&z%f;z,A
$res = $db->query( 'SELECT * FROM movies' );PHPChina 开源社区门户B7fiuOHDp G
while( $res->fetchInto( $row ) )
w2H9g&Tz }0{PHPChina 开源社区门户(N4/"S?J H^

&s/(HQ_6`0$res2 = $db->query(PHPChina 开源社区门户(z9W5k)F v` }"@}r
'SELECT count( rating ), sum(rating ) FROM ratings WHERE movie_id=?', $row[0]
.Su)`5Hyu ax }~0);
^�L6F I!cw9N-u)b0$rating = 0.0;
v-c.ls]b'~0while( $res2->fetchInto( $row2 ) ) { if ( $row2[0] > 0 ) $rating = $row2[1] / $row2[0]; }PHPChina 开源社区门户}I;NG_$deS
?>
:u1Gf%o}g6v;A0<item>PHPChina 开源社区门户av{ f,EV ly
<title><?php echo($row[1]) ?> - PHPChina 开源社区门户R7J:P,?o$fy%_'qy#s].I
<?php echo( $rating > 0 ? $rating : 0 ) ?> stars</title>PHPChina 开源社区门户d$s$b To-ZUN9K
<link>http://localhost/commentsts/rate2.php?id=<?php echo($row[0]) ?></link>PHPChina 开源社区门户r]E,r `
<descrīption><?php echo($row[1]) ?></descrīption>PHPChina 开源社区门户1zz0lI,Ws_8w
</item>PHPChina 开源社区门户NC$M%i8KJT
<?phpPHPChina 开源社区门户$/8yCLKr N
}PHPChina 开源社区门户M"_ Tbmc)}(@S4QbMz
?>PHPChina 开源社区门户 }I;ue!}}G
</channel>PHPChina 开源社区门户k&z,K{2^#[0r
</rss>PHPChina 开源社区门户6}]-uNRPag
PHPChina 开源社区门户 /.}?/k

清单 9 中的代码的作用类似于使用 HTML 格式导出数据。它使用 <title><descrīption><link> 标记指向各个电影页面,而不是 HTML 中的 <table><tr><td> 标记。当我在 Firefox 浏览器中打开这个页面时,所显示的页面如 图 5 所示。

PHPChina 开源社区门户o3n!~x^a6t
图 5. 浏览器中的 RSS 提要
C9v$a4yf n0 浏览器中的 RSS 提要
j k2ba%H5R|0

很容易吧!从 php 中获取 XML 提要就是这么简单。

当我使用以下命令行在本地运行代码时:

% php rss.phpPHPChina 开源社区门户Q/u `gG {:G
PHPChina 开源社区门户D1TO2n u_ |*|

我可以直接看到 RSS XML。清单 10 显示了这个 RSS 的一部分。

PHPChina 开源社区门户PCi7S+p6a'y�s2C{

'_ E;H l,pC0清单 10. RSS excerpt
~-~"?3d6i;i:r0
                
8M}SCx0<rss version="0.91">PHPChina 开源社区门户 C$w z,p3u!d A$_
<channel>
1J$X2QL$E0<title>Movie rankings</title>
jE9p [)v4v+bJ8I+U3[0<link>http://localhost/comments/rss.php</link>
(K+m]Bg}6` k0<item>PHPChina 开源社区门户H:j["yx�L/{
<title>Star Wars - 4.5 stars</title>
V ?-@%DF#Sv(Cm�?0<link>http://localhost/commentsts/rate2.php?id=1</link>
epTM!s/E0<descrīption>Star Wars</descrīption>PHPChina 开源社区门户 uLu�@Q:q)N
</item>
%pq/%Ces0<item>PHPChina 开源社区门户,n//g1zQ+s:Y{
...
S+QP+l;T9p8b M7g~Y&C0PHPChina 开源社区门户P?"F!WFm2[z{v1M]
PHPChina 开源社区门户"ih_ d1UT

结束语

最近,关于用户生成内容的话题格外引人关注,尤其是它如何增强 Web 2.0 的力量这方面。与本文中示例一样,您可以使用 Prototype.js 库之类的优秀工具轻易地构建 Ajax 应用程序。对网站内容的评级和评论功能确实是一种极好的用户生成内容的形式。

PHPChina 开源社区门户4O)jV-i,DL