首先进入DIY后。点击模块的链接是
- <a id=”hd_mod” οnclick=”spaceDiy.getdiy(‘blockclass’);this.blur();return false;” href=”:;”>模块</a>
复制代码
在这里调用了js函数 getdiy() 并且传进一个参数 ‘blockclass’ ,在portal_diy.js 中我找到了这个函数。997行。 其中流程执行的程序段是
- getdiy : function (type) {
- if (type) {
- var nav = $(‘controlnav’).children;
- for (var i in nav) {
- if (nav[i].className == ‘current’) {
- nav[i].className = ”;
- var contentid = ‘content’+nav[i].id.replace(‘nav’, ”);
- if ($(contentid)) $(contentid).style.display = ‘none’;
- }
- }
- $(‘nav’+type).className = ‘current’;
- if (type == ‘start’ || type == ‘frame’) {
- $(‘content’+type).style.display = ‘block’;
- return true;
- }
- if(type == ‘blockclass’ && $(‘content’+type).innerHTML !=”) {
- $(‘content’+type).style.display = ‘block’;
- return true;
- }
- var para = ‘&op=’+type;
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- para += ‘&’ + arguments[i] + ‘=’ + arguments[++i];
- }
- }
- var ajaxtarget = type == ‘diy’ ? ‘diyp_w_picpaths’ : ”;
- var x = new Ajax();
- x.showId = ajaxtarget;
- x.get(‘portal.php?mod=portalcp&ac=diy’+para+’&inajax=1&ajaxtarget=’+ajaxtarget,function(s, x) {
- if (s) {
- if (typeof cpb_frame == ‘object’ && !BROWSER.ie) {delete cpb_frame;}
- if (!$(‘content’+type)) {
- var dom = document.createElement(‘div’);
- dom.id = ‘content’+type;
- $(‘controlcontent’).appendChild(dom);
- }
- $(‘content’+type).innerHTML = s;
- $(‘content’+type).style.display = ‘block’;
- if (type == ‘diy’) {
- spaceDiy.setCurrentDiy(spaceDiy.currentDiy);
- if (spaceDiy.styleSheet.rules.length > 0) {
- Util.show(‘recover_button’);
- }
- }
- var evaled = false;
- if(s.indexOf(‘ajaxerror’) != -1) {
- evalscript(s);
- evaled = true;
- }
- if(!evaled && (typeof ajaxerror == ‘undefined’ || !ajaxerror)) {
- if(x.showId) {
- ajaxupdateevents($(x.showId));
- }
- }
- if(!evaled) evalscript(s);
- }
- });
- }
- }
复制代码
看到这里我们会看到程序会请求一个地址
- http://x2/portal.php?mod=portalcp&ac=diy&op=blockclass&inajax=1&ajaxtarget=
复制代码
看到这个之后,我们先放一边,在portalcp_diy.htm 中我们找到了生成diy模块选项的这块代码
- <!–{loop $_G['cache']['blockclass'] $key $value}–>
- <!–{if $isfirst}–>
- <!–{eval $isfirst=0;}–>
- <ul id=”contentblockclass_$key”>
- <!–{else}–>
- <ul id=”contentblockclass_$key”>
- <!–{/if}–>
- <li>
- <ol>
- <!–{loop $value[subs] $skey $svalue}–>
- <li class=”module-$skey”><label οnmοusedοwn=”drag.createObj (event,’block’,'$skey’);” οnmοuseοut=”this.className=”;”>$svalue[name]</label></li>
- <!–{/loop}–>
- </ol>
- </li>
- </ul>
- <!–{/loop}–>
复制代码
在这里使用了dz中的模板语法 loop 与 /loop 间循环把 $_G['cache']['blockclass'] 中的值以html形式输出。好了,我们知道了问题的上一个根源。$_G是dx中的全局变量,那我们在dx中把它输出出来看看,里面有没有内容。在
- http://x2/portal.php?mod=portalcp&ac=diy&op=blockclass&inajax=1&ajaxtarget=
复制代码
根据这个地址,找到portal_portalcp.php,其中还包含了比较重要的一个文件是 portalcp_diy.php 其中的
- if($op == ‘blockclass’) {
复制代码
这段对我们上面js中的请求进行了处理。
- loadcache(‘blockclass’);
复制代码
这段是读取 blockclass 为名字的缓存,读到$_G['cache']['blockclass']中。说到这里,大家应该明白这之间的关系了吧。
鼠标点击触发js函数,js函数中get一个php文件,php文件中对这次请求进行了处理,读取了 blockclass 缓存,存到了 $_G['cache']['blockclass'] 中,然后在模板文件中把它们循环显示出来。就是这样。
问题分析到这里知道了流程,那么这个问题就出在 $_G['cache']['blockclass'] 上。我尝试打印了$_G['cache']['blockclass']的值。
- <?php
- require ‘./source/class/class_core.php’;
- $discuz = & discuz_core::instance();
- $discuz->cachelist = $cachelist;
- $discuz->init();
- loadcache(‘blockclass’);
- print_r($_G['cache']['blockclass']);
- ?>
复制代码
这段程序就是读下blockclass 缓存,然后把 $_G['cache']['blockclass'] 的值打出来,奇怪的是,我在这个站长的站上这个值打印出来是空的,只有结构没有数据,所以当然显示模块为空了。 没办法,只有继续往上查。查什么?查读取缓存的程序,读取模块缓存的函数是 blockclass_cache() 在 function_block.php 中 在这里,我摘出了部分代码,然后让它输出我需要的东西。程序代码不在这里贴了。上传附件中了。
在这个函数中程序分别读取 class/block 下面文件夹中的程序文件,输出结果如图:
分别把它读取block模块的文件、类、方法的步骤读出并且显示出来。使用这个文件,在站长的服务器上发现了问题,输出并没有进行完,只输出到了一半就停 止了。卡在了一个站长安装的dx模块上。问题就在这里了。我把在block文件夹中出问题的那个模块移出block目录。在看一遍。输出都正常了。这样更 新一遍缓存。首页DIY模块就出来了。
总结来说。这个是因为第三方的代码植入了dx的缓存体系中,在 loadcache(‘blockclass’); 的时候。这个第三方代码出现了问题。程序并没有按照以往人们想象的那样,会报错?导致了所需要的缓存没有进行更新导致的错误。