当前位置: 首页 > 图文教程 > 网站运营 > 建站经验 > Discuz 0818补丁后丢失最近访问论坛记录的解决办法

建站经验
建站经验分享 做网站的思路
网站内容 原创,转载与伪原创
建站经验 网站要成功必须具备的6点
制作网站价格为什么那么便宜
网站流量 主要来源分析
结合个人小站 谈谈如何提高网站PV
设计网站要注意吸引客户和留住客户
搜索引擎 对自助链接的一些政策
利用反向链接提高网站权重的5种形式
搜索引擎 Bing必学的高级搜索语法
用户体验 文章引导,心理引导粘住网站用户
网站上线前要做的准备工作
Google 优化蜘蛛爬取和索引的技巧
网站发展中20条禁令 推荐
站长网站建设应避免的八大雷区小结
网站15种最差的用户体验
网站策划 网站信息闭环设计
新奇网站 认识代BT下载网站
建站入门 顶级域名与二级域名
网站改版升级的理论知识 站长需要看下

建站经验 中的 Discuz 0818补丁后丢失最近访问论坛记录的解决办法


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-17   浏览: 79 ::
收藏到网摘: n/a

这些日子,我们公司的论坛时有不正常之处,典型问题就是:无征兆的,“最近访问论坛"列表,突然丢失,不少人大呼不方便。如果去后台更新一下子缓存,又正常了。

反复查对,发现:/forumdata/cache/cache_forumdisplay.php这个文件,其中缓存了论坛列表信息。出现问题时,其中本来应该正常缓存的信息,丢失了。

而缓存更新,在/include/cache.inc.php的updatecache()函数之中,cache_forumdisplay.php通过统一的流程制造,实在是想不通,什么地方产生了特殊状况。

因为这个丢失,当时看起来,是没有任何征兆,无法重现的。

无奈之下,在/include/cache.inc.php的writetocache函数中,埋了一段代码:

function writetocache($script, $cachenames, $cachedata = '', $prefix = 'cache_') {
    global $authkey, $timestamp;
    if(is_array($cachenames) && !$cachedata) {
        foreach($cachenames as $name) {
            $cachedata .= getcachearray($name, $script);
        }
    }

    $dir = DISCUZ_ROOT.'./forumdata/cache/';
    if(!is_dir($dir)) {
        @mkdir($dir, 0777);
    }
    if($fp = @fopen("$dir$prefix$script.php", 'wb')) {
        fwrite($fp, "<?phpn//Discuz! cache file, DO NOT modify me!".
            "n//Created: ".date("M j, Y, G:i").
            "n//Identify: ".md5($prefix.$script.'.php'.$cachedata.$authkey)."nn$cachedata?>");
        fclose($fp);
//
埋的代码
        if
($script==='forumdisplay')
        {
            $fps .= "GDVS:".print_r(get_defined_vars(),true)."n";
            $fps .= "DBTS:".print_r(debug_backtrace(),true)."n";
            $fps .= "nnn";
            $fps = "DLINE:".__LINE__ ."n" . "timeis:".date("Y-m-d H:i:s")."n" . $fps;
            if(strpos($cachedata,"$_DCACHE['forums']"))
            {
                writelog('debug_forumdisplay_find',$fps);
            }
            else
            
{
                writelog('debug_forumdisplay_notfound',$fps);
            }
        }
    } else {
        dexit('Can not write to cache files, please check directory ./forumdata/ and ./forumdata/cache/ .');
    }
}

一天以后,在/forumdata/logs/里面,*****_notfound.php里面,逮到了一次丢失的过程,基本流程是:

/admincp.php->/admin/prune.inc.php->updatecache()->/include/cache.func.php->writetocache()

对应的实际操作,就是在网站的后台,执行批量删除帖子的操作,其中有一个更新:updatecache(‘globalstick’);

最后,定位到了getcachevars()这个函数里面,找到了问题所在。

先卖个关子,0818的时候,dz发了一个补丁,详见http://www.discuz.net/thread-1388523-1-1.html

恰好更新了/include/cache.func.php这个文件,在getcachevars()里面加了一段代码:

if(!preg_match("/^[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*$/", $key)) {
            continue;
        }

其作用在于过滤非法变量。

殊不知,就是这段代码,变成了罪魁祸首,导致新的问题产生。

程序实际运行过程中,会有_DCACHE[‘forums’]等类似的变量名,需要通过这个关卡,结果就是挂掉,直接导致对应的信息为空,从而是的缓存文件丢失信息。有兴趣的朋友,可以自己跟踪测试一下子。

修正的代码如下:

if(!preg_match("/^[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*$/", $key) && !preg_match("/^[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*['[a-zA-Z_x7f-xff][a-zA-Z0-9_x7f-xff]*']$/", $key)) {
            continue;
        }

让_DCACHE[‘forums’]等类似的变量名通过,至此问题解决。

经查代码发现,dz4.1.0到dz7.0.0,均存在该问题,所以请使用dz的同学们,从速修改,以免出现莫名其妙的问题。

---------- 在文件中查找 ----------
"/dp20090818/4.1.0/admin/styles.inc.php"(316,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/4.1.0/include/cache.func.php"(664,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
"/dp20090818/5.0.0/admin/styles.inc.php"(320,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/5.0.0/include/cache.func.php"(776,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
"/dp20090818/5.5.0/admin/styles.inc.php"(328,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/5.5.0/include/cache.func.php"(1087,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
"/dp20090818/6.0.0/admin/styles.inc.php"(314,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/6.0.0/include/cache.func.php"(1425,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
"/dp20090818/6.1.0/admin/styles.inc.php"(332,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/6.1.0/include/cache.func.php"(1378,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
"/dp20090818/6.1.0F/admin/styles.inc.php"(332,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/6.1.0F/include/cache.func.php"(1359,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
"/dp20090818/7.0.0/admin/styles.inc.php"(736,28):                        } elseif(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $newcvar)) {
"/dp20090818/7.0.0/include/cache.func.php"(1503,21):                if(!preg_match("/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/", $key)) {
找到 14 个事件 (在 14 个文件中)。
输出完成 (耗时 0 秒)

没有打0818补丁的,请从速从http://www.discuz.net/thread-1388523-1-1.html打最新补丁,然后与打过补丁的同学,一起把getcachevars()的这个问题修正。

原帖地址:http://bbs3.chinaunix.net/thread-1574923-1-1.html