Discuz缓存造成为登录用户/游客不能翻页问题浅析

2015-12-14 19:57 来自:Discuz 评论(1)次 查看(1,174)

虽说现在的微信大行其道,很多人认为BBS已经没落;但就我们观察所知,至少是在长沙地区,很多企业开始做自己的社区,因为现在的社区一样可以结合微信来做,获取来自微信的流量,然后在自己的社区发酵转化。

但企业的社区一般来讲内容结构是比较简单的,如果用传统的“版块”来讲,可能也就是那么几个版块而已,一般就是让用户交流自己产品或者给用户晒单、提意见的。特别是小米论坛等知名企业社区采用直接内容列表作为首页后,各大企业社区纷纷效仿。

说了这么久没用的,这里我们当然会一如既往的说很多论坛基于Discuz这款产品来做的,比如知名的小米社区就是。大家也都知道默认情况下Discuz的起始文件index.php会定向到forum.php,而这个脚本不带任何参数调用的模版是discuz.htm这个文件。

而开发过Discuz模版的朋友都知道,这个discuz.htm是经常被我们操刀的,因为很多时候它就是我们网站的首页。也知道实际上其中包含的不仅仅是简单的几个版块,同时也包括分区页面、不同横排版块数量的判断等等。

而要实现打开网站的域名就呈现全站帖子列表的形式,要么一开始定向到一个新增的页面,这个页面来调用数据(这也是我个人所推荐的)。也可以就把这个默认的“首页”修改,我也曾经接到过这样的需求,就是不要默认乱七八糟的,就让discuz.htm来呈现一个列表(支持翻页和筛选),当然还有周围一些聚合信息。

原理很简单,用SQL获取数据库主题表的数据,然后通过分页和相应的约束条件实现翻页和筛选,这里就涉及到两个参数——翻页的和筛选的;我们不妨以page和type为例;这个需求太常规了,一般人都不会出问题。

—————————————-这中间看故事而已,可略过—————————————-

是的,确实不会出问题,但是如果你忽略了DZ的缓存,那么有可能就会出问题,而且这个问题可以让你摸不着边。因为这个问题就是缓存,而且后台是可以设置的,后台设置太多了,后台操作人员可能随意一个设置就会导致很难被追踪到的问题。这里还得说说曾经的一个故事:

使用上面说到的把discuz.htm改成单纯的聚合页面,也就有了page和type两个动态参数,在默认情况下直接这样这个小的模块在程序上很快就能完成,其他就是页面干的事情了,开发环境OK,测试环境OK,生产环境OK。等一等,有问题,怎么当用户未登录的时候翻到第二页还是还是第一页,而且点击精华筛选也没用啊。这样的问题可以说很郁闷,因为代码是一样的、服务器环境是一样,当然数据库数据可能不一样(至少生产一直在创造内容呀)。

当然这是我收到的一个问题需求,我一开始想到当然不是什么问题,就是想以最快的方式解决问题,于是肯定就问测试和生产有什么差异,生产以前是否正常。结果得到回复是以前没问题,突然有问题,然后还说除了伪静态那个地方做了一个仅游客有效外其他都没做改变。这个时候我就纳闷了。

后来,我突然想起来,最近他们因站点慢,做了一些处理,我就在想啊,Discuz本身就有缓存处理机制,如果他们涉及站点效率的问题,那么就基本上缓存相关的配置也在相应的范围内。

—————————————-故事结束,请认真听—————————————-

于是就回到了标题的问题,为什么在游客状态下无效,我自然想到了缓存。然后我就直接看关于discuz.htm对应的M层,也就是module了,对应的文件为source/module/forum/forum_index.php。在这个文件中一开始就能看到这么一段代码

if(!$_G['uid'] && !$gid  && $_G['setting']['cacheindexlife'] && !defined('IN_ARCHIVER') && !defined('IN_MOBILE')) {
	get_index_page_guest_cache();
}

其中的$_G[‘uid’] 和$_G[‘setting’]以及get_index_page_guest_cache()让我意识到我的猜想是正确的,因为就在这里我就看到了关于用户的判断(前面不是说只有未登录用户才会这样么),$_G[‘setting’]一般地后台就能设置(也就是说他们出现问题就是后台改变了,所以生产和测试环境不一样的结果),而后面的方法则很明显是缓存,根据命名顾名思义就是关于首页页面的游客缓存。于是查看这个方法,这个方法就在这个文件中,代码如下

function get_index_page_guest_cache() {
 global $_G;
 $indexcache = getcacheinfo(0);
 if(TIMESTAMP - $indexcache['filemtime'] > $_G['setting']['cacheindexlife']) {
 @unlink($indexcache['filename']);
 define('CACHE_FILE', $indexcache['filename']);
 } elseif($indexcache['filename']) {
 @readfile($indexcache['filename']);
 $updatetime = dgmdate($indexcache['filemtime'], 'H:i:s');
 $gzip = $_G['gzipcompress'] ? ', Gzip enabled' : '';
 echo "<script type=\"text/javascript\">
 if($('debuginfo')) {
 $('debuginfo').innerHTML = '. This page is cached at $updatetime $gzip .';
 }
 </script>";
 exit();
 }
}

到了这里我就更加确信了我的判断,于是我打开我本地随便一个站点,在后台找$_G[‘setting’][‘cacheindexlife’]这个设置项,虽然我不喜欢在后台折腾太多,但因为对Discuz的熟悉,很快就能找到相应的设置。

ds

那么解决方案呢?

我觉得解决有三个路径,一个是停掉首页的缓存,这对于大访问量论坛可能不原因,压力山大啊,小论坛直接关闭就好了(就是把上图设置为0)。第二个方式就是新增一个页面来做,然后访问网站首页直接定向到这个页面,这个比如做一个插件之类的,这个不用多说。

第三种方式嘛,就是稍微修改一下M层,也就是上面的forum_index.php,修改上那段代码即可,我们可以看到其中if中有!$gid,而gid这个参数就是我们访问分区。也就是官方设计思想是什么呢?在首页起始页面如果我们开启了缓存,就调用缓存页面,而当有参数gid的时候不缓存,我们也可以加上page和type参数有有效值的时候不缓存;这样即可。同时我们可以继续修改,比如说当登录的用户也请求缓存页面,当然这样做我不是特别喜欢,毕竟动了核心的源代码。

转载请注明出处:Discuz缓存造成为登录用户/游客不能翻页问题浅析 - 木泉网
分享:

发表评论

请登录

未登录

  1. 不错,支持下

    未语 2015-12-15 回复
返回顶部