CI框架 -- 核心文件 之 Hooks.php
钩子 - 扩展框架核心
CodeIgniter 的钩子特性提供了一种方法来修改框架的内部运作流程,而无需修改 核心文件。CodeIgniter 的运行遵循着一个特定的流程,你可以参考这个页面的 应用程序流程图 。但是,有些时候你可能希望在 执行流程中的某些阶段添加一些动作,例如在控制器加载之前或之后执行一段脚本, 或者在其他的某些位置触发你的脚本。
启用钩子
钩子特性可以在 application/config/config.php 文件中全局的启用或禁用, 设置下面这个参数: $config['enable_hooks'] = TRUE;
挂钩点
CI框架可以实现在不修改系统核心文件的基础上来改变或增加系统的核心运行功能,那就是Hook,看看CI有哪些钩子:
- pre_system
系统执行的早期调用.仅仅在benchmark 和 hooks 类 加载完毕的时候. 没有执行路由或者其它的过程. - pre_controller
在调用你的任何控制器之前调用.此时所用的基础类,路由选择和安全性检查都已完成. - post_controller_constructor
在你的控制器实例化之后,任何方法调用之前调用. - post_controller
在你的控制器完全运行之后调用. - display_override
覆盖_display()函数, 用来在系统执行末尾向web浏览器发送最终页面.这允许你用自己的方法来显示.注意,你需要通过 $this->CI =& get_instance() 引用 CI 超级对象,然后这样的最终数据可以通过调用 $this->CI->output->get_output() 来获得。 - cache_override
可以让你调用自己的函数来取代output类中的_display_cache() 函数.这可以让你使用自己的缓存显示方法 - post_system
在最终着色页面发送到浏览器之后,浏览器接收完最终数据的系统执行末尾调用
定义钩子
$hook['pre_controller'] = array(
'class' => 'TestHook', //调用的类名,如果你更喜欢使用过程式的函数的话,这一项可以留空。
'function' => 'test', //调用的函数名
'filename' => 'TestHook.php', //包含你的类或函数的文件名
'filepath' => 'hooks', //包含你的脚本文件的目录名。 注意: 你的脚本必须放在 application/ 目录里面,所以 filepath 是相对 application/ 目录的路径,举例来说,如果你的脚本位于 application/hooks/ ,那么 filepath 可以简单的设置为 'hooks' ,如果你的脚本位于application/hooks/utilities/ , 那么 filepath 可以设置为 'hooks/utilities' ,路径后面不用加斜线
'params' => 'array()'//传递给脚本参数,可选
);
多次调用同一个挂钩点
如果你想在同一个挂钩点处添加多个脚本,只需要将钩子数组变成二维数组即可,像这样:
$hook['pre_controller'][] = array(
'class' => 'MyClass',
'function' => 'MyMethod',
'filename' => 'Myclass.php',
'filepath' => 'hooks',
'params' => array('beer', 'wine', 'snacks')
); $hook['pre_controller'][] = array(
'class' => 'MyOtherClass',
'function' => 'MyOtherMethod',
'filename' => 'Myotherclass.php',
'filepath' => 'hooks',
'params' => array('red', 'yellow', 'blue')
);
注意数组索引后面多了个中括号:$hook['pre_controller'][]
这可以让你在同一个挂钩点处执行多个脚本,多个脚本执行顺序就是你定义数组的顺序。
钩子类分析
/**
* 钩子嘛,就是在不修改系统核心文件的基础上来改变或增加系统的核心运行功能
*/
class CI_Hooks { /**
* 检测hook是否开启
*/
var $enabled = FALSE;
/**
* config/hooks.php中的hooks配置信息
*/
var $hooks = array();
//防止死循环,因为钩子程序里面可能还还有钩子
var $in_progress = FALSE; //构造函数
function __construct()
{
$this->_initialize();
log_message('debug', "Hooks Class Initialized");
} /**
* 初始化,获取hooks配合
*/
function _initialize()
{
$CFG =& load_class('Config', 'core'); // 检测配置是否开启钩子
if ($CFG->item('enable_hooks') == FALSE)
{
return;
} // 检测是否配置钩子
if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
{
include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
}
elseif (is_file(APPPATH.'config/hooks.php'))
{
include(APPPATH.'config/hooks.php');
} if ( ! isset($hook) OR ! is_array($hook))
{
return;
} $this->hooks =& $hook;
$this->enabled = TRUE;
} // -------------------------------------------------------------------- /**
* 运行钩子程序,外部就是这样调用:
* $EXT =& load_class('Hooks', 'core');
* $EXT->_call_hook('pre_system');
*/
function _call_hook($which = '')
{
if ( ! $this->enabled OR ! isset($this->hooks[$which]))
{
return FALSE;
}
//CI支持多次钩子,那么就是二维数组
if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
{
foreach ($this->hooks[$which] as $val)
{
$this->_run_hook($val);
}
}
else
{
//一个钩子直接运行钩子
$this->_run_hook($this->hooks[$which]);
} return TRUE;
} // -------------------------------------------------------------------- /**
* Run Hook
*
* Runs a particular hook
*
* @access private
* @param array the hook details
* @return bool
*/
function _run_hook($data)
{
if ( ! is_array($data))
{
return FALSE;
} //防止死循环,因为钩子程序里面可能还还有钩子
if ($this->in_progress == TRUE)
{
return;
} //设置路径
//下面可以filepathfilepath就以那个文件夹(application)为基准,application/hooks下, 你可以把hooks 作为你的filepath if ( ! isset($data['filepath']) OR ! isset($data['filename']))
{
return FALSE;
} $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; if ( ! file_exists($filepath))
{
return FALSE;
} // -----------------------------------
// Set class/function name
// ----------------------------------- $class = FALSE;
$function = FALSE;
$params = ''; if (isset($data['class']) AND $data['class'] != '')
{
$class = $data['class'];
} if (isset($data['function']))
{
$function = $data['function'];
} if (isset($data['params']))
{
$params = $data['params'];
} if ($class === FALSE AND $function === FALSE)
{
return FALSE;
} //不用多说了吧
$this->in_progress = TRUE; //获取钩子配置信息成功后,运行钩子程序
if ($class !== FALSE)
{
if ( ! class_exists($class))
{
require($filepath);
} $HOOK = new $class;
$HOOK->$function($params);
}
else
{
if ( ! function_exists($function))
{
require($filepath);
} $function($params);
}
// //执行相应程序完毕后,重新把当前hook的状态改为非运行中,以让它可以再次被触发。
$this->in_progress = FALSE;
return TRUE;
} }
CI框架 -- 核心文件 之 Hooks.php的更多相关文章
- CI框架 -- 核心文件 之 Exceptions.php
使用CI框架,我们通常使用一下三个函数处理错误: show_error('消息' [, int $status_code = 500 ] ) show_404('页面' [, 'log_error'] ...
- CI框架 -- 核心文件 之 Loader.php(加载器)
顾名思义,装载器就是加载元素的,使用CI时,经常加载的有: 加载类库文件:$this->load->library() 加载视图文件:$this->load->view() ...
- CI框架 -- 核心文件 之 Common.php
system/core/Common.php 文件中可以定义 公共函数,我们可以在这里定义自己的公共函数.在任何情况下你都能够使用这些函数.使用他们不需要载入任何类库或辅助函数. 接下来分析下该文件中 ...
- CI框架 -- 核心文件 之 config.php
Config:该文件包含CI_Config类,这个类包含启用配置文件来管理的方法 /** * 加载配置文件 * * @param string $file 配置文件名 * @param bool $u ...
- CI框架 -- 核心文件 之 Output.php(输出类文件)
CI输出类Output.php的功能是将最终web页面发送给浏览器,这里面的东西可能是你用的最少的.你使用装载器加载了一个视图文件, 这个视图文件的内容会自动传递给输出类对象, 然后呢,在方法执行完毕 ...
- CI框架 -- 核心文件 之 Benchmark.php
Benchmark.php文件中定义的CI_Benchmark类可以让你标记点,并计算它们之间的时间差.还可以显示内存消耗. Benchmarking类库,它是被系统自动被加载的,不需要手工加载 cl ...
- CI框架 -- 核心文件 之 Model.php
class CI_Model { /** * Class constructor * * @return void */ public function __construct() { log_mes ...
- CI框架 -- 核心文件 之 Input.php(输入数据处理文件)
class CI_Input { //用户ip地址 protected $ip_address = FALSE; //用户浏览器地址 protected $user_agent = FALSE; // ...
- CI框架 -- 核心文件 之 Lang.php(加载语言包)
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class CI_Lang { var $l ...
随机推荐
- Lua语法基础(1)---简介、基本数据类型、表达式
我觉得我已经陷入了一个坑内.因为,安装了Lua和SublimeText3编辑器之后,怎么使自己编写的lua代码在untiy内运行起来,是个我完全不了解的机制.先放一放吧.首先,来回顾一下Lua的语法基 ...
- convert2utf8withbom
很久以前给同事要的转码bash 当时windows和mac总是出现中文注释乱码的情况,让人心塞的难过.又因为是老项目,现有源码太多了,不可能改模板重新创建.只能跑一遍这个玩意儿了…… #!/bin/b ...
- 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-1导入JavaScript插件
导入JavaScript插件 Bootstrap除了包含丰富的Web组件之外,如前面介绍的下拉菜单.按钮组.导航.分页等.他还包括一些JavaScript的插件. Bootstrap的JavaScri ...
- 使用PostgreSQL遇到的一个问题[column does not exist]字段不存在:
表结构: 在我上面的表结构中,明明有一个叫做"fromdeviceId"的字段,但是查询的时候却提示找不到该字段: 仔细观察错误信息,发现,我的字段明明是有一个大写字母(fromd ...
- Shell获取格式化日期
Shell获取格式化日期 shell date 获取昨天日期 使用date -d 选项: date +"%Y%m%d" -d "+n days" 今天的后n天日 ...
- RAID常见问题集锦+底部案例
磁盘阵列(Redundant Arrays of Inexpensive Disks,RAID),有“价格便宜具有冗余能力的磁盘阵列”之意.原理是利用数组方式来作磁盘组,配合数据分散排列的设计,提升数 ...
- 【GitHub】常用命令
克隆项目 git clone http://*git 把本地项目提交到远程 git add --all git commit -m "Initail commit" git pus ...
- [转]基于BootStrap 的城市三级联动
原文地址:https://blog.csdn.net/peiyuanxin/article/details/51992384 HTML代码部分 <div class="form- ...
- mongo的身份验证和授权
问题来源 刚装好的mongo,准备登陆进去测一把的,结果就给我报这个错,鄙人是新手,还不太清楚这个,现学一下~ Mongo的身份验证 在上一篇安装mongo的博客中(https://www.cnblo ...
- shell常用命令大全
目录: 一.文件目录类命令 二.文件压缩和归档类命令 三.系统状态类命令 四.网络类命令 五.其他 一.文件目录类命令 1.查看联机帮助信息. man命令.#man ls info命令. #info ...