discuz 插件核心函数hookscript分析.
function hookscript($script, $hscript, $type = 'funcs', $param = array(), $func = '', $scriptextra = '') {
# 本函数是插件勾注的枋心函数. 对插件开发极为重要. 我们一一分析.
# hookscript($script, $hscript, $type = 'funcs', $param = array(), $func = '', $scriptextra = '')
# hookscript($script, $hscript, $type = 'funcs', $param = array(), $func = '', $scriptextra = '')
# hookscript(方法名, 类型(比如全局,主题, 移动等等..), 调用类型, 参数, 可以勾搭一个副方法, 特殊参数);
global $_G; // 引入核心数组, 默认是共计4KB大的数组,
static $pluginclasses; // 静态货插件类数组, 以便计算执行文件是否已经被引入过.
if($hscript == 'home') { // 当$hscript 等于home时, 做些变量的转换, 特殊参数就在这儿有效.
if($script == 'space') {
$scriptextra = !$scriptextra ? $_GET['do'] : $scriptextra;
$script = 'space'.(!empty($scriptextra) ? '_'.$scriptextra : '');
} elseif($script == 'spacecp') {
$scriptextra = !$scriptextra ? $_GET['ac'] : $scriptextra;
$script .= !empty($scriptextra) ? '_'.$scriptextra : '';
}
}
# 判断插件是否有定义或者开启. 否则退出.
if(!isset($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {
return;
}
# 判断插件是否有缓存, 假如没有则退出.
if(!isset($_G['cache']['plugin'])) {
loadcache('plugin');
}
# 循环取出module数组, module数组里面包涵着文件路径.
foreach((array)$_G['setting'][HOOKTYPE][$hscript][$script]['module'] as $identifier => $include) {
// pluginrunlist 这儿检测了方法是否被禁用, 否则跳过一次.
if($_G['pluginrunlist'] && !in_array($identifier, $_G['pluginrunlist'])) {
continue;
}
// 权限的判断.
$hooksadminid[$identifier] = !$_G['setting'][HOOKTYPE][$hscript][$script]['adminid'][$identifier] || ($_G['setting'][HOOKTYPE][$hscript][$script]['adminid'][$identifier] && $_G['adminid'] > 0 && $_G['setting']['hookscript'][$hscript][$script]['adminid'][$identifier] >= $_G['adminid']);
if($hooksadminid[$identifier]) { // 只有权限判断通过, 才会引入文件. 个人觉得应该将$pluginclasses数组运用起来.
@include_once DISCUZ_ROOT.'./source/plugin/'.$include.'.class.php';
}
}
# 判断方法集是为数组, (is_array有必要用@抑制错误吗?)
if(@is_array($_G['setting'][HOOKTYPE][$hscript][$script][$type])) {
$_G['inhookscript'] = true; // 只能标明调用成功了.
// 处理附加调用的方法增加, 以便让循环中可以使用.
$funcs = !$func ? $_G['setting'][HOOKTYPE][$hscript][$script][$type] : array($func => $_G['setting'][HOOKTYPE][$hscript][$script][$type][$func]);
// 循环所有的方法. 多维数组, 考虑到一个类型的hook可能有多个实现方法.
foreach($funcs as $hookkey => $hookfuncs) {
foreach($hookfuncs as $hookfunc) {
// $hookfunc[0] 为 类型也可理解为类的名字.
// $hookfunc[1] 为 执行方法
if($hooksadminid[$hookfunc[0]]) {
# 这儿需要重组一下类的名字.
$classkey = (HOOKTYPE != 'hookscriptmobile' ? '' : 'mobile').'plugin_'.($hookfunc[0].($hscript != 'global' ? '_'.$hscript : ''));
# 判断类没有被加载就退出. false参数是为了不检查引入.
if(!class_exists($classkey, false)) {
continue;
}
# 判断如果没实例化过, 就实例化一次.
if(!isset($pluginclasses[$classkey])) {
$pluginclasses[$classkey] = new $classkey;
}
# 判断$hookfunc[1]方法不存在实例中. 就退出.
if(!method_exists($pluginclasses[$classkey], $hookfunc[1])) {
continue;
}
# 然后调用$hookfunc[1]方法, 并且植入方法.
$return = $pluginclasses[$classkey]->$hookfunc[1]($param);
// $param = var_export($param,true);
// echo "{$classkey}->$hookfunc[1]($param)<br />"; 可通过这两行打印具体.
# 判断 类型具有某特征, 并且在pluginhooks数组中存在, 然后退出.
if(substr($hookkey, -7) == '_extend' && !empty($_G['setting']['pluginhooks'][$hookkey])) {
continue;
}
# 判断返回值为数组时就进入.
if(is_array($return)) {
# $hookkey 判断 是否存在插件hook当中. 并且要是数组. 接着循环, 将返回值做不同的赋值释放.
if(!isset($_G['setting']['pluginhooks'][$hookkey]) || is_array($_G['setting']['pluginhooks'][$hookkey])) {
foreach($return as $k => $v) {
$_G['setting']['pluginhooks'][$hookkey][$k] .= $v;
}
} else {
foreach($return as $k => $v) {
$_G['setting']['pluginhooks'][$hookkey][$k] = $v;
}
}
} else {
#假如返回值不是数组, 则换种方法释放返回值.
if(!is_array($_G['setting']['pluginhooks'][$hookkey])) {
$_G['setting']['pluginhooks'][$hookkey] .= $return;
} else {
foreach($_G['setting']['pluginhooks'][$hookkey] as $k => $v) {
$_G['setting']['pluginhooks'][$hookkey][$k] .= $return;
}
}
}
}
}
}
}
# 变个变量是什么意思, 上面定义true, 这儿定义false, 是在计算流程是否完成吗?
$_G['inhookscript'] = false;
}
discuz 插件核心函数hookscript分析.的更多相关文章
- DiscuzX /source/function/function_core.php通用核心函数库文件分析
... <?php /** * [Discuz!] (C)2001-2099 Comsenz Inc. * This is NOT a freeware, use is subject to l ...
- discuz核心函数库function_core的函数注释
/** * 系统错误处理 * @param <type> $message 错误信息 * @param <type> $show 是否显示信息 * @param <typ ...
- Discuz核心函数的解析
dz采用的是多入口的方式,在每个入口函数你能看到引用,启动核心类的语句(其余省略),如下: require './source/class/class_core.php'; C::app()-> ...
- Zepto核心模块源代码分析
一.Zepto核心模块架构 Zepto核心模块架构图 该图展示了Zepto核心模块架构代码的组织方式.主要分为私有变量.函数和暴露给用户的所有api. Zepto核心模块架构代码 该图展示了Zepto ...
- Discuz X3核心文件解析
<?php /** * [Discuz!] (C)2001-2099 Comsenz Inc. * This is NOT a freeware, use is subjec ...
- R数据分析:数据清洗的思路和核心函数介绍
好多同学把统计和数据清洗搞混,直接把原始数据发给我,做个统计吧,这个时候其实很大的工作量是在数据清洗和处理上,如果数据很杂乱,清洗起来是很费工夫的,反而清洗好的数据做统计分析常常就是一行代码的事情. ...
- 解密jQuery内核 DOM操作的核心函数domManip
domManip是什么 dom即Dom元素,Manip是Manipulate的缩写,连在一起就是Dom操作的意思. .domManip()是jQuery DOM操作的核心函数 对封装的节点操作做了参数 ...
- discuz二次开发,分析和实现 之 向dz数据库插入自己的帖子吧
发个博客太麻烦了,难怪写博客的越来越少,吐一下,cnblogs的编辑器模板太丑! 最近开发社区 需要采集一些数据,使得模板输出有图文效果.就写了个简单的采集脚本,爬取目标站的内容,(用php 下载图片 ...
- PHP基于数组的分页函数(核心函数array_slice())
关于数组的分页函数,用数组进行分页的好处是可以方便的进行联合多表查询,只需要将查询的结果放在数组中就可以了以下是数组分页的函数,函数page_array用于数组的分页,函数show_array用于分页 ...
随机推荐
- 设计模式-(8)外观(swift版)
一,概念 为子系统中的一组接口提供一个统一的接口.外观模式定义了一个更高层次的接口,这个接口使得这一子系统更加容易使用. 二,结构图 (1)SubSystem子系统类:每个子系统定义了相关功能和模块的 ...
- Ubuntu下Jupyter Notebook的安装
pip install --upgrade pip //更新pip pip install jupyter sudo apt install jupyter-notebook 运行 jupyter-n ...
- I.MX6 RGB clock 和 data 重合
/*********************************************************************** * I.MX6 RGB clock 和 data 重合 ...
- pymemcache get start
Getting started! A comprehensive, fast, pure-Python memcached client library. Basic Usage from pymem ...
- MySQL 三种关联查询的方式: ON vs USING vs 传统风格
看看下面三个关联查询的 SQL 语句有何区别? 1SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) 2 ...
- 让padding不影响容器总长度
增加CSS属性: box-sizing:border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box;
- bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】
树套树: 约等于是个暴力了.以区间线段树的方式开一棵权值线段树,在权值线段树的每一个点上以动态开点的方式开一棵区间线段树. 结果非常惨烈(时限20s) #include<iostream> ...
- bzoj 1614: [Usaco2007 Jan]Telephone Lines架设电话线【二分+spfa】
二分答案,然后把边权大于二分值的的边赋值为1,其他边赋值为0,然后跑spfa最短路看是否满足小于等于k条边在最短路上 #include<iostream> #include<cstd ...
- Spring Json数据
json 数据转换 @RequestBody 用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter 进行解析,然后把相应的数据绑定到Controll ...
- Matlab调用C程序 分类: Matlab c/c++ 2015-01-06 19:18 464人阅读 评论(0) 收藏
Matlab是矩阵语言,如果运算可以用矩阵实现,其运算速度非常快.但若运算中涉及到大量循环,Matlab的速度令人难以忍受的.当必须使用for循环且找不到对应的矩阵运算来等效时,可以将耗时长的函数用C ...