优化Discuz!6.1的RSS
2008 12 20 05:54 AM 4196次查看
分类:Discuz! 标签:Discuz!, PHP, RSS
相信很多discuz的站长都遇到过进入RSS页面什么帖都不显示,但刷新下就显示出来了的情况。
原因就在于discuz生成RSS页面时会判断是否需要更新,当访问RSS页面时距上次更新超过后台所设置的TTL时间时,discuz就会自动更新RSS的数据;但更新完后就直接退出了,而不会输出数据!
所以当阅读器第一次访问时,只获取了论坛的基本信息。之后,阅读器根据获得的TTL,决定在TTL分钟后再次访问;但下次访问时,discuz会发现需要更新数据了,所以又只给阅读器基本信息。如果你的论坛有很多人订阅,那倒没关系;如果只有1个人订阅,那可能一辈子都收不到更新!
懂php的应该都看得懂rss.php中的这段代码吧:
if($fidarray) {
$query = $db->query("SELECT * FROM {$tablepre}rsscaches WHERE fid IN (".implode(',', $fidarray).") ORDER BY dateline DESC LIMIT $num");
if($db->num_rows($query)) {
while($thread = $db->fetch_array($query)) {
if($timestamp - $thread['lastupdate'] > $ttl * 60) {
updatersscache();
break;
} else {
echo " <item>\n".
" <title>".dhtmlspecialchars($thread['subject'])."</title>\n".
" <link>{$boardurl}viewthread.php?tid=$thread[tid]</link>\n".
" <description><![CDATA[$thread[description]]]></description>\n".
" <category>".dhtmlspecialchars($thread['forum'])."</category>\n".
" <author>".dhtmlspecialchars($thread['author'])."</author>\n".
" <pubDate>".gmdate('r', $thread['dateline'])."</pubDate>\n".
" </item>\n";
}
}
} else {
updatersscache();
}
}
我们所要做的,就是在执行updatersscache()后,再次从数据库中取数据,然后输出。用下面的代码替换上述代码即可:
if($fidarray && !fetchthread()) {
updatersscache();
fetchthread();
}
function echothread($thread) {
global $boardurl;
echo
" <item>\n".
" <title>".dhtmlspecialchars($thread['subject'])."</title>\n".
" <link>{$boardurl}viewthread.php?tid=$thread[tid]</link>\n".
" <description><![CDATA[$thread[description]]]></description>\n".
" <category>".dhtmlspecialchars($thread['forum'])."</category>\n".
" <author>".dhtmlspecialchars($thread['author'])."</author>\n".
" <pubDate>".gmdate('r', $thread['dateline'])."</pubDate>\n".
" </item>\n";
}
function fetchthread() {
global $timestamp, $num, $tablepre, $db, $ttl, $fidarray;
static $first = TRUE;
$query = $db->query("SELECT * FROM {$tablepre}rsscaches WHERE fid IN (".implode(',', $fidarray).") ORDER BY dateline DESC LIMIT $num");
if($db->num_rows($query)) {
while($thread = $db->fetch_array($query)) {
if($first && $timestamp - $thread['lastupdate'] > $ttl * 60) {
$first = FALSE;
updatersscache();
fetchthread();
break;
} else {
$first = FALSE;
echothread($thread);
}
}
return TRUE;
}
return FALSE;
}
接下来,如果你的论坛开启了伪静态,请按如下方式替换:搜索
<link>{$boardurl}viewthread.php?tid=$thread[tid]</link>\n".
改为
<link>{$boardurl}thread-$thread[tid]-1-1.html</link>\n".
搜索
<link>{$boardurl}forumdisplay.php?fid=$rssfid</link>\n".
改为
<link>{$boardurl}forum-$rssfid-1.html</link>\n".
顺便说下那个$num = 20;,如果你的论坛新主题发得很频繁,可以适当增大该值。假设你的论坛每小时有50个新主题,TTL为30分钟,那么你的$num应不低于50×60÷30=100。此外,我还觉得自动生成的那一串地址很长,例如http://www.keakon.cn/bbs/rss.php?auth=9a26GCBlk8hZq83%2BxYTVIuEUcsYlNku6nqn1htmUzngW2UAFUcYxRa(注意,我有做更改。)
在rss.php中发现auth后的那串东西其实是一串加密后的验证码,有了这串东西,就获得了生成你所能访问版块和帖子的权限,有可能比游客或一般会员生成的更多。
但这一长串实在很麻烦,如果你的论坛可让游客浏览大部分内容,那大可删掉这串东西。实在有需要,你也可以生成2种地址,供会员自行选择。
删除的办法:打开discuz.htm和forumdisplay.htm,搜索&auth=$rssauth,删掉即可。
不过head中还有个rss的link,可以在index.php中将'rss.php?auth='.$rssauth."改为"rss.php,forumdisplay.php中将'&auth='.$rssauth.删掉。请注意其中的引号和小数点不要遗漏或添加。
最后,由于每次访问RSS页面,都会读取1~2次数据库。虽说rsscaches是个很小的表,但如果你的订阅数很多(例如超过1000),TTL又很短的话,也是很影响性能的。
如果不考虑访问权限的话,可以定期生成一个rss.xml文件,稍微修改下就可以用discuz自带的计划任务实现了。
不过已经很晚了,我懒得做了。等哪天有很多人订阅时再去改吧…
0条评论 你不来一发么↓