Discuz!官方免费开源建站系统

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索

discuzx中DIY的时候模块为空(消失)的检查。

[复制链接]
rikioy 发表于 2011-8-29 18:02:14 | 显示全部楼层 |阅读模式
本帖最后由 rikioy 于 2011-8-29 19:32 编辑

最近帮论坛里的会员解决了一个问题。就是DIY里面,模块没有,显示空白。下面我就简述下,如何排查的这个问题。大家的问题可能与这个问题一样,也可能不一样。但是,检查问题的思路是一样的。希望有能力的站长出现这个问题后检查一下。

首先进入DIY后。点击模块的链接是
  1. <a id="hd_mod" onclick="spaceDiy.getdiy('blockclass');this.blur();return false;" href="javascript:;">模块</a>
复制代码
在这里调用了js函数 getdiy() 并且传进一个参数 'blockclass' ,在portal_diy.js 中我找到了这个函数。997行。
其中流程执行的程序段是
  1.     getdiy : function (type) {
  2.         if (type) {
  3.             var nav = $('controlnav').children;
  4.             for (var i in nav) {
  5.                 if (nav[i].className == 'current') {
  6.                     nav[i].className = '';
  7.                     var contentid = 'content'+nav[i].id.replace('nav', '');
  8.                     if ($(contentid)) $(contentid).style.display = 'none';
  9.                 }
  10.             }
  11.             $('nav'+type).className = 'current';
  12.             if (type == 'start' || type == 'frame') {
  13.                 $('content'+type).style.display = 'block';
  14.                 return true;
  15.             }
  16.             if(type == 'blockclass' && $('content'+type).innerHTML !='') {
  17.                 $('content'+type).style.display = 'block';
  18.                 return true;
  19.             }
  20.             var para = '&op='+type;
  21.             if (arguments.length > 1) {
  22.                 for (var i = 1; i < arguments.length; i++) {
  23.                     para += '&' + arguments[i] + '=' + arguments[++i];
  24.                 }
  25.             }
  26.             var ajaxtarget = type == 'diy' ? 'diyimages' : '';
  27.             var x = new Ajax();
  28.             x.showId = ajaxtarget;
  29.             x.get('portal.php?mod=portalcp&ac=diy'+para+'&inajax=1&ajaxtarget='+ajaxtarget,function(s, x) {
  30.                 if (s) {
  31.                     if (typeof cpb_frame == 'object' && !BROWSER.ie) {delete cpb_frame;}
  32.                     if (!$('content'+type)) {
  33.                         var dom = document.createElement('div');
  34.                         dom.id = 'content'+type;
  35.                         $('controlcontent').appendChild(dom);
  36.                     }
  37.                     $('content'+type).innerHTML = s;
  38.                     $('content'+type).style.display = 'block';
  39.                     if (type == 'diy') {
  40.                         spaceDiy.setCurrentDiy(spaceDiy.currentDiy);
  41.                         if (spaceDiy.styleSheet.rules.length > 0) {
  42.                             Util.show('recover_button');
  43.                         }
  44.                     }

  45.                     var evaled = false;
  46.                     if(s.indexOf('ajaxerror') != -1) {
  47.                         evalscript(s);
  48.                         evaled = true;
  49.                     }
  50.                     if(!evaled && (typeof ajaxerror == 'undefined' || !ajaxerror)) {
  51.                         if(x.showId) {
  52.                             ajaxupdateevents($(x.showId));
  53.                         }
  54.                     }
  55.                     if(!evaled) evalscript(s);
  56.                 }
  57.             });
  58.         }
  59.     }
复制代码
看到这里我们会看到程序会请求一个地址
  1. http://x2/portal.php?mod=portalcp&ac=diy&op=blockclass&inajax=1&ajaxtarget=
复制代码

看到这个之后,我们先放一边,在portalcp_diy.htm 中我们找到了生成diy模块选项的这块代码
  1.         <!--{loop $_G['cache']['blockclass'] $key $value}-->
  2.         <!--{if $isfirst}-->
  3.         <!--{eval $isfirst=0;}-->
  4.         <ul class="blocks content" id="contentblockclass_$key">
  5.         <!--{else}-->
  6.         <ul class="blocks content" id="contentblockclass_$key" class="hide">
  7.         <!--{/if}-->
  8.                 <li class="module-$key">
  9.                         <ol>
  10.                         <!--{loop $value[subs] $skey $svalue}-->
  11.                                 <li class="module-$skey"><label onmousedown="drag.createObj (event,'block','$skey');" onmouseover="className='hover';" onmouseout="this.className='';">$svalue[name]</label></li>
  12.                         <!--{/loop}-->
  13.                         </ol>
  14.                 </li>
  15.         </ul>
  16.         <!--{/loop}-->
复制代码
在这里使用了dz中的模板语法 loop 与 /loop 间循环把 $_G['cache']['blockclass'] 中的值以html形式输出。好了,我们知道了问题的上一个根源。$_G是dx中的全局变量,那我们在dx中把它输出出来看看,里面有没有内容。在

  1. http://x2/portal.php?mod=portalcp&ac=diy&op=blockclass&inajax=1&ajaxtarget=
复制代码
根据这个地址,找到portal_portalcp.php,其中还包含了比较重要的一个文件是 portalcp_diy.php
其中的
  1. if($op == 'blockclass') {
复制代码
这段对我们上面js中的请求进行了处理。
  1. loadcache('blockclass');
复制代码
这段是读取 blockclass 为名字的缓存,读到$_G['cache']['blockclass']中。说到这里,大家应该明白这之间的关系了吧。

鼠标点击触发js函数,js函数中get一个php文件,php文件中对这次请求进行了处理,读取了 blockclass 缓存,存到了 $_G['cache']['blockclass'] 中,然后在模板文件中把它们循环显示出来。就是这样。

问题分析到这里知道了流程,那么这个问题就出在 $_G['cache']['blockclass'] 上。我尝试打印了$_G['cache']['blockclass']的值。
  1. <?php
  2. require './source/class/class_core.php';
  3. $discuz = & discuz_core::instance();
  4. $discuz->cachelist = $cachelist;
  5. $discuz->init();
  6. loadcache('blockclass');
  7. print_r($_G['cache']['blockclass']);
  8. ?>
复制代码
这段程序就是读下blockclass 缓存,然后把 $_G['cache']['blockclass'] 的值打出来,奇怪的是,我在这个站长的站上这个值打印出来是空的,只有结构没有数据,所以当然显示模块为空了。
没办法,只有继续往上查。查什么?查读取缓存的程序,读取模块缓存的函数是 blockclass_cache() 在 function_block.php 中
在这里,我摘出了部分代码,然后让它输出我需要的东西。程序代码不在这里贴了。上传附件中了。

在这个函数中程序分别读取 class/block 下面文件夹中的程序文件,输出结果如图:


分别把它读取block模块的文件、类、方法的步骤读出并且显示出来。使用这个文件,在站长的服务器上发现了问题,输出并没有进行完,只输出到了一半就停止了。卡在了一个站长安装的dx模块上。问题就在这里了。我把在block文件夹中出问题的那个模块移出block目录。在看一遍。输出都正常了。这样更新一遍缓存。首页DIY模块就出来了。

总结来说。这个是因为第三方的代码植入了dx的缓存体系中,在 loadcache('blockclass'); 的时候。这个第三方代码出现了问题。程序并没有按照以往人们想象的那样,会报错?导致了所需要的缓存没有进行更新导致的错误。


北北″ 发表于 2011-8-29 18:21:00 | 显示全部楼层
说实话我没看懂...
回复

使用道具 举报

 楼主| rikioy 发表于 2011-8-29 19:19:07 | 显示全部楼层
北北″ 发表于 2011-8-29 18:21
说实话我没看懂...

还没写完
回复

使用道具 举报

北北″ 发表于 2011-8-29 22:14:19 | 显示全部楼层
rikioy 发表于 2011-8-29 19:19
还没写完

现在看明白了...
回复

使用道具 举报

extollive 发表于 2011-8-29 22:17:05 | 显示全部楼层
太深奥了。。。
回复

使用道具 举报

qq7941420 发表于 2011-8-29 23:23:10 | 显示全部楼层
感谢谢~!!~哈哈,很强大,
回复

使用道具 举报

壹米阳光 发表于 2011-8-31 12:30:58 | 显示全部楼层
太深奥了 看不懂
回复

使用道具 举报

 楼主| rikioy 发表于 2011-8-31 12:56:55 | 显示全部楼层
恩。写出了步骤。没写出想法。要带着思考去看。看完了。脑袋里过了个流程。就明白了。
回复

使用道具 举报

苍海浮尘 发表于 2011-8-31 14:41:18 | 显示全部楼层
收藏一下、可能以后用的着
回复

使用道具 举报

sdqdhzd1 发表于 2011-8-31 19:52:19 | 显示全部楼层
那到底怎么解决?上传那个文件就可以了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|Discuz! 官方站 ( 皖ICP备16010102号 )star

GMT+8, 2024-12-4 16:32 , Processed in 0.035385 second(s), 6 queries , Gzip On, Redis On.

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表