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

建站经验
经验探讨 用户体验与搜索引擎优化的结合
让你的网站产生Google Sitelinks的六个要素
凸显使用体验 网站导航最受美国厂商关注
外国人眼中网站设计和网站建设二十个原则
网站更换域名应该注意的八个方面
五年经验告诉你 细节决定网站成败
新网站如何提高流量
稳中求升 购买付费链接应注意的九个问题
经验越多下手越难 你能抛弃你所学习的吗
站长进行设计网站时必须注意二十三个方面
路径突破 谈谈英文站比中文站更能做成功
谈谈网站运营中的关键的一环 团队的管理
最原始的东西最有价值 致天下所有创业者
名博怎样练成 析月光博客成功的六个原因
学生站长持续自己的冬天 仍坚守春天的期待
关于对web的分析 获得可行动的认识和度量
五个月前后五次改动 让我的流量稳在五万
亲手关闭自己论坛 泣血奉献一些心得经验
用户体验指导思想 易用友好 把用户当傻瓜
网站如何将用户体验与搜索引擎优化相结合

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


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