最近打脸了,因为很久没更博客了,脸好疼。。。

钩子的使用起源是在刚面试的时候,被面试官指着我基于CI做的demo说用过这个(指着hooks目录)吗?,当时我就懵逼了,只能摇头尴尬苦笑的说了没有。不过事情过去了我并没有把它放过,然后回去看了一下钩子hook。


HOOK是什么?

HOOK(钩子)见名思其意,这东西应该是用来“挂”在哪儿的。没错,hook像事件驱动,hook具体操作就像js里的事件绑定的那个方法函数,而各种click、blur等等就像钩子的挂载点,当你做相应的操作就会触发这个钩子。

CI中的hook使用和js事件或许有一点不一样,但道理是一样的。只不过哟在CI中hook的挂载点是在框架运行的流程中的,比如说开始加载控制器时、加载完控制器准备输出模板时等,只要你挂载点写了对应的实际操作,就会在框架运行的时候自动执行(其实也不算自动,如果你把访问也当做一个事件触发的话。)


CI中HOOK的使用示例

我们伟大的领袖毛主席曾说过:“实践是检验真理的唯一标准”,光理论不操作是没用的。 先贴一下应用结构图:

使用流程:

  1. 先在配置文件config/config.php中将$config['enable_hooks']值改为true(将钩子使用开关打开)
$config['enable_hooks'] = TRUE;

  1. 在hooks目录下写下钩子操作类文件hookname.php,我这里名字叫hooktest.php,我下面要写的是一个过滤含有welcome访问url的功能
class hooktest
{
    public function test()
    {
        $uri = $_SERVER['REQUEST_URI'];
        if(preg_match('/welcome/', $uri))
        {
            exit("不允许url含有welcome,你的url是:$uri");
        }
            echo '年轻人~~~你通过了考验!和我一起使用CI吧!';
    }
}

  1. 在config/hooks.php里配置挂载点(把写好的钩子操作挂上),我这里是挂在基础类等已加载完毕,控制器调用之前即pre_controller,后面我会把其他挂载点信息放上
$hook['pre_controller'] = array(
    'class'    => 'hooktest',
    'function' => 'test',
    'filename' => 'hooktest.php',
    'filepath' => 'hooks',
);

  1. 这样钩子就可以运行了,我们来测试一下,先直接只进入默认欢迎页,在浏览器上输入:http://demo.test.dev/CodeIgniter/(这是我ci项目访问位置),然后再按照完整路径来输入:http://demo.test.dev/CodeIgniter/index.php/welcome。对比的结果图如下:

    http://demo.test.dev/CodeIgniter/


    http://demo.test.dev/CodeIgniter/index.php/welcome


    就是这么简单~~~


补充:

以下是所有可用挂钩点的一份列表:

  • pre_system 在系统执行的早期调用,这个时候只有 基准测试类 和 钩子类 被加载了, 还没有执行到路由或其他的流程。
  • pre_controller 在你的控制器调用之前执行,所有的基础类都已加载,路由和安全检查也已经完成。
  • post_controller_constructor 在你的控制器实例化之后立即执行,控制器的任何方法都还尚未调用。
  • post_controller 在你的控制器完全运行结束时执行。
  • display_override 覆盖 _display() 方法,该方法用于在系统执行结束时向浏览器发送最终的页面结果。 这可以让你有自己的显示页面的方法。注意你可能需要使用 $this->CI =& get_instance() 方法来获取 CI 超级对象,以及使用 $this->CI->output->get_output() 方法来 获取最终的显示数据。
  • cache_override 使用你自己的方法来替代 输出类 中的 _display_cache() 方法,这让你有自己的缓存显示机制。
  • post_system 在最终的页面发送到浏览器之后、在系统的最后期被调用。