发布一个DISCUZX模组挂载系统…
通过这个挂载系统 可以让我们在外部”手术刀”得方式 以最小改动源程序进行修改功能得目的
class Module { /* 模组挂载系统 */ public $Module = Array(); //记录实例 public $ModuleCallnum = Array(); //记录需要call次数 public $ModuleCallnumed = Array(); //记录需要已经call次数 public $ModuleMethodClist = Array(); public $ModuleReturnClist = Array(); //记录模组有return得 检查 public $ModulePointlist = Array(); //所有被CALL数组 public $Pointlist = Array(); //全局嵌入点列表 public $FuncPointlist = Array(); //函数嵌入点列表 public $ClassPointlist = Array(); //类嵌入点列表 public $Returns = Array(); public function Module(){ GLOBAL $Module; $Module = Array(); $this->Module = & $Module; } public function ModuleAdd($modname_point, $function = '' ,$class = '') { if(strpos($modname_point,'/')){ @list($modname,$args0,$args1,$args2) = explode('/',$modname_point); if($args2){ $class = $args0; $function=$args1; $point = $args2; }elseif($args1){ $function=$args0; $point = $args1; }else{ $point = $args0; } }else{ echo 'Notice: Module: '.$modname_point.'.Point Missing'; return false; } if(!isset($this->Module[$modname])){ $this->ModuleMethodClist[$modname] = $this->ModuleReturnClist[$modname] = Array(); } //判断模组插入点是否重复插入相同得模组 if(in_array($modname_point,$this->ModulePointlist)){ echo 'Notice: Module: '.$modname.' Been Added'; return false; } if(!class_exists($modname)) { echo 'Notice: Module: '.$modname.' NoExists'; return false; } if(!in_array($modname,$this->ModuleMethodClist[$modname])){ $class_methods = get_class_methods($modname); $this->ModuleMethodClist[$modname]=in_array('action',$class_methods )&&in_array('execute',$class_methods); if(!$this->ModuleMethodClist[$modname]){ echo 'Notice: Module: '.$modname.' Method Missing'; return false; } } if(!in_array($modname,$this->ModuleReturnClist[$modname])){ $class_vars = get_class_vars($modname); $this->ModuleReturnClist[$modname] = array_key_exists('returns',$class_vars); } if($class && $function && $point && !in_array($modname_point,$this->ModulePointlist)){ $this->ModulePointlist[] = $modname_point; if(!isset($this->ModuleCallnum[$modname])){ $this->ModuleCallnum[$modname] = 1; }else{ $this->ModuleCallnum[$modname] ++; } if(!in_array($modname,$this->ClassPointlist[$class][$function][$point])){ $this->ClassPointlist[$class][$function][$point][] = $modname; } }elseif($function && $point && !in_array($modname_point,$this->ModulePointlist)){ $this->ModulePointlist[] = $modname_point; if(!isset($this->ModuleCallnum[$modname])){ $this->ModuleCallnum[$modname] = 1; }else{ $this->ModuleCallnum[$modname] ++; } if(!in_array($modname,$this->FuncPointlist[$function][$point])){ $this->FuncPointlist[$function][$point][] = $modname; } }elseif(!in_array($modname_point,$this->ModulePointlist)){ $this->ModulePointlist[] = $modname_point; if(!isset($this->ModuleCallnum[$modname])){ $this->ModuleCallnum[$modname] = 1; }else{ $this->ModuleCallnum[$modname] ++; } if(!is_array($this->Pointlist[$point])||!in_array($modname,$this->Pointlist[$point])){ $this->Pointlist[$point][] = $modname; } } } public function ModulePoint($point, $function = '' ,$class = '') { if($class && $function && !empty($this->ClassPointlist[$class][$function][$point])){ $this->Classexecute($point,$this->ClassPointlist[$class][$function][$point]); }elseif($function && !empty($this->FuncPointlist[$function][$point])){ $this->Functionexecute($point,$this->FuncPointlist[$function][$point]); }elseif($point && !empty($this->Pointlist[$point])){ $this->Pointexecute($point,$this->Pointlist[$point]); } } public function Classexecute($point,& $classAry) { foreach($classAry as $name){ $this->execute($name,$point); } } public function Functionexecute($point,& $functionAry) { foreach($functionAry as $name){ $this->execute($name,$point); } } public function Pointexecute($point,& $pointAry) { foreach($pointAry as $name){ $this->execute($name,$point); } } public function execute($name,$point) { if(!isset($this->Module[$name])){ $this->Module[$name] = new $name(); } if($this->ModuleReturnClist[$name]){ $this->Module[$name]->returns = & $this->Returns; } if($this->Module[$name]->action($point)){ $this->Module[$name]->execute($point); } if(!isset($this->ModuleCallnumed[$modname])){ $this->ModuleCallnumed[$modname] = 1; }else{ $this->ModuleCallnumed[$modname] ++; } if($this->ModuleCallnumed[$name] >= $this->ModuleCallnum[$name]){ unset($this->Module[$name]); } }}function & Module() { static $Module; if(!isset($Module)){ $Module = New Module(); } return $Module;}function ModuleAdd($name) { $Module = Module(); $Module->ModuleAdd($name);}function ModulePointWhether($name,$function='',$class ='') { $Module = Module(); if($class && $function && !empty($Module->ClassPointlist[$class][$function][$name])){ return TRUE; }elseif($function && !empty($Module->FuncPointlist[$function][$name])){ return TRUE; }elseif($name && !empty($Module->Pointlist[$name])){ return TRUE; }else{ return FALSE; }}function ModulePoint($name,$function='',$class ='', $returns = array()) { $Module = Module(); if($returns) $Module->Returns = $returns; $Module->ModulePoint($name,$function,$class); if($Module->Returns) return $Module->Returns;}以上便是模组挂载系统的全部代码
其实这个挂载系统可以挂载到任意程序上..
下载我们改造下DISCUZX 让他可以挂载东西..
将以上模组系统得代码 我建议我们放置到一个单独得 程序文件下
比如 在程序主目录下新建 require.php
将模组系统的代码复制其中
将执行文件 加入到 内核执行之前 于是我们找到文件
source/class/class_core.php
在 代码
class discuz_core {之前加入
define(‘BIGQI_ROOT’, substr(dirname(__FILE__), 0, -12));
require_once BIGQI_ROOT.’./require.php’;
这样模组系统 就成功加入PHP 代码中了..
下面 我们给discuzx加入挂载点 (你可以自由定义挂载点..)
这里介绍下我自己认为需要添加得挂载点..
start 内核被执行前
core 内核执行后,功能script执行前
template 模版加载前
output 模版输出前
好了 知道这几个挂载点得 含义 我们接下来去加入这些挂载点
增加 start 挂载点:
打开文件
source/class/class_core.php
在
class discuz_core {得上一行加入
/* ModuleSystem Point */
if(ModulePointWhether(‘start’,__FUNCTION__,__CLASS__)){
$Modextract = ModulePoint(‘start’,__FUNCTION__,__CLASS__);
if(isset($Modextract) && is_array($Modextract)){
extract($Modextract);
unset($Modextract);
}
}
/* ModuleSystem Point */
增加 core 挂载点:
打开文件
source/class/class_core.php
找到代码
$this->_init_misc();在其下部加入
/* ModuleSystem Point */ if(ModulePointWhether('core')){ $Modextract = ModulePoint('core'); if(isset($Modextract) && is_array($Modextract)){ extract($Modextract); unset($Modextract); } } /* ModuleSystem Point */增加 core 挂载点:
打开文件
source\function\function_core.php
找到代码
function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') { global $_G;在其下部加入
/* ModuleSystem Point */ if(ModulePointWhether('template')){ $Modextract = ModulePoint('template'); if(isset($Modextract) && is_array($Modextract)){ extract($Modextract); unset($Modextract); } } /* ModuleSystem Point */增加 output 挂载点:
打开文件
source\function\function_core.php
找到代码
function output() { global $_G;在其下部加入
/* ModuleSystem Point */ if(ModulePointWhether('output')){ $Modextract = ModulePoint('output'); if(isset($Modextract) && is_array($Modextract)){ extract($Modextract); unset($Modextract); } } /* ModuleSystem Point */好了 现在 4个挂载点 就全部增加完毕.. 现在就该我们看看 要怎么用到这个挂载系统 挂载具体得功能
我先发一个案例(此案例是预防机器人发帖得部分代码)
类得 定义 必须有2个方法分别是 action 用来判断执行 execute具体得执行代码
class postvalidate { public function action($point) { // if(CURSCRIPT == 'forum' && CURMODULE == 'post' && $_POST){ return true; }else{ return false; } } public function execute() { if( FORMHASH != $_G['gp_posthash']){ showmessage('undefined_action'); } }}ModuleAdd('postvalidate/output'); //含义:在output 上挂载postvalidate类将以上代码 复制到 require.php 文件内
看到了.. 很简单得几行代码 我们就可以对 forum动作得 POST进行截断执行postvalidate ::execute下得代码
其实 这个代码挂载系统 还远远不只这些功能…
下载我们再来更牛叉点得功能…
给一个函数内加入挂载点
首先需要修改代码
打开文件
source\function\function_core.php
找到代码
$string = str_replace(array("\r", "\n"), array('', ''), $string);在其下部加入
/* ModuleSystem Point */
if(ModulePointWhether(‘output’,__FUNCTION__,__CLASS__)){
$returns['string'] = $string;
$returns['replace'] = $replace;
$returns['http_resp**e_code'] = $http_resp**e_code;
$Modextract = ModulePoint(‘output’,__FUNCTION__,__CLASS__,$returns);
if(isset($Modextract) && is_array($Modextract)){
extract($Modextract);
unset($Modextract);
}
}
/* ModuleSystem Point */
好了 发一个案例
这个功能 就是 更改提示信息跳转得URL (wp.cc使用得URL规则)
class redirect_staticlink { public $returns; public function action($point) { if(CURSCRIPT == 'forum'&& CURMODULE == 'redirect'){ return true; }elseif(CURSCRIPT == 'forum'&& CURMODULE == 'post'){ return true; }else{ return false; } } public function execute() { global $_G; if (preg_match ('/forum.php\?mod\=viewthread&(amp;)?tid=(\d+)/is', $this->returns['string'], $matches)) { $query = "SELECT fid FROM ".DB::table('forum_thread')." WHERE tid='$matches[2]'"; $fid = DB::result_first($query); $this->returns['string'] = str_replace('tid='.$matches[2],'fid='.$fid.'&tid='.$matches[2],$this->returns['string']); $siteurl = str_replace('develop/','',$_G['siteurl']); $search = '/forum.php\?mod\=viewthread&(amp;)?fid\=(\d+)&(amp;)?tid=(\d+)(&(amp;)?page\=(\d+))?(&(amp;)?[^"\'# ]+)?/e'; $replace= '$siteurl.manage_staticlink::staticrewrite(\'$0\',\'$2\',\'$4\',\'$7\',\'$8\')'; $this->returns['string'] = preg_replace($search,$replace,$this->returns['string']); } }}ModuleAdd('redirect_staticlink/dheader/output'); // 在dheader函数内得 output挂载点加入redirect_staticlink
|