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

建站经验
制作Html与XML格式的网站地图和内容导航
老手段新思维 常见的DDOS攻击以及防护
社区运营总结:让网站以蜂巢模式运营
网站该这么建:从一门户网站策划书看门道
网站策划之“帮助中心”策划思考
告诉新手站长 网站质量重点要注意的地方
让您的网站更有的放矢:网页设计的小建议
行行出怪事 友情链接也潜规则?
图文解析:请您不要用技术的眼光来做网站
坚顶原创 同意常规转载 反对盗用
个人站长心情故事 建站100天的酸甜苦辣
浅谈地区分类信息网前期筹划、推广及运营
告诉新手站长们 如何提高网站质量七方法
web专题设计模板化可行性研究
浅谈地区分类信息网前期筹划推广及运营
站长朋友 在你最想放弃的时候请坚持到底!
个人站长们请远离黑帽SEO
网页制作之事不过三 做站八种情况要杜绝
由交朋友来看提升网站用户黏度的八项注意
网站设计最重要环节 改善网站可读性11招

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-17   浏览: 121 ::
收藏到网摘: 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