CodeIgniter框架钩子机制实现方法【hooks类】


Posted in PHP onAugust 21, 2018

本文实例讲述了CodeIgniter框架钩子机制实现方法。分享给大家供大家参考,具体如下:

记得上一次去到喜啦面试,面试官问我一个问题:codeigniter是如何实现钩子机制的?

当时答不上来,后来回来之后查了一些资料才明白,所以在这里记录一下:

codeigniter的钩子是这样实现的:首先在框架的核心文件system/core/CodeIniter.php文件的 122行,载入Hooks类,接着在该文件中定义了几个挂载点,比如pre_system(129行)、post_controller_constructor(295行)等,并在这些挂载点上面执行hooks类的_call_hook() 方法。

另附codeigniter的hooks类的源代码:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * CodeIgniter
 *
 * An open source application development framework for PHP 5.1.6 or newer
 *
 * @package   CodeIgniter
 * @author   EllisLab Dev Team
 * @copyright    Copyright (c) 2008 - 2014, EllisLab, Inc.
 * @copyright    Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
 * @license   http://codeigniter.com/user_guide/license.html
 * @link    http://codeigniter.com
 * @since    Version 1.0
 * @filesource
 */

// ------------------------------------------------------------------------

/**
 * CodeIgniter Hooks Class
 *
 * Provides a mechanism to extend the base system without hacking.
 *
 * @package   CodeIgniter
 * @subpackage Libraries
 * @category  Libraries
 * @author   EllisLab Dev Team
 * @link    http://codeigniter.com/user_guide/libraries/encryption.html
 */
class CI_Hooks {

  /**
   * Determines wether hooks are enabled
   *
   * @var bool
   */
  var $enabled    = FALSE;
  /**
   * List of all hooks set in config/hooks.php
   *
   * @var array
   */
  var $hooks     = array();
  /**
   * Determines wether hook is in progress, used to prevent infinte loops
   *
   * @var bool
   */
  var $in_progress  = FALSE;

  /**
   * Constructor
   *
   */
  function __construct()
  {
    $this->_initialize();
    log_message('debug', "Hooks Class Initialized");
  }

  // --------------------------------------------------------------------

  /**
   * Initialize the Hooks Preferences
   *
   * @access private
   * @return void
   */
  function _initialize()
  {
    $CFG =& load_class('Config', 'core');

    // If hooks are not enabled in the config file
    // there is nothing else to do

    if ($CFG->item('enable_hooks') == FALSE)
    {
      return;
    }

    // Grab the "hooks" definition file.
    // If there are no hooks, we're done.

    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;
  }

  // --------------------------------------------------------------------

  /**
   * Call Hook
   *
   * Calls a particular hook
   *
   * @access private
   * @param  string the hook name
   * @return mixed
   */
  function _call_hook($which = '')
  {
    if ( ! $this->enabled OR ! isset($this->hooks[$which]))
    {
      return FALSE;
    }

    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;
    }

    // -----------------------------------
    // Safety - Prevents run-away loops
    // -----------------------------------

    // If the script being called happens to have the same
    // hook call within it a loop can happen

    if ($this->in_progress == TRUE)
    {
      return;
    }

    // -----------------------------------
    // Set file path
    // -----------------------------------

    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;
    }

    // -----------------------------------
    // Set the in_progress flag
    // -----------------------------------

    $this->in_progress = TRUE;

    // -----------------------------------
    // Call the requested class and/or function
    // -----------------------------------

    if ($class !== FALSE)
    {
      if ( ! class_exists($class))
      {
        require($filepath);
      }

      $HOOK = new $class;
      $HOOK->$function($params);
    }
    else
    {
      if ( ! function_exists($function))
      {
        require($filepath);
      }

      $function($params);
    }

    $this->in_progress = FALSE;
    return TRUE;
  }

}

// END CI_Hooks class

/* End of file Hooks.php */
/* Location: ./system/core/Hooks.php */

可以看出codeigniter实现钩子机制的方式不够优雅,其实完全可以使用观察者模式来实现钩子机制,将挂载点当做监听的事件。

希望本文所述对大家基于CodeIgniter框架的PHP程序设计有所帮助。

PHP 相关文章推荐
初品cakephp 入门基础
Feb 16 PHP
php 文件上传实例代码
Apr 19 PHP
基于php伪静态的实现详细介绍
Apr 28 PHP
10条php编程小技巧
Jul 07 PHP
PHP模板引擎Smarty内建函数foreach,foreachelse用法分析
Apr 11 PHP
提交表单后 PHP获取提交内容的实现方法
May 25 PHP
PHP实现小偷程序实例
Oct 31 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
利用PHP判断是手机移动端还是PC端访问的函数示例
Dec 14 PHP
php 替换文章中的图片路径,下载图片到本地服务器的方法
Feb 06 PHP
PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析
Jun 12 PHP
PHP的介绍以及优势详细分析
Sep 05 PHP
PHP依赖注入原理与用法分析
Aug 21 #PHP
PHP 二维array转换json的实例讲解
Aug 21 #PHP
PHP删除数组中指定值的元素常用方法实例分析【4种方法】
Aug 21 #PHP
php 将json格式数据转换成数组的方法
Aug 21 #PHP
php正确输出json数据的实例讲解
Aug 21 #PHP
php将从数据库中获得的数据转换成json格式并输出的方法
Aug 21 #PHP
php实现将数据做成json的格式给前端使用
Aug 21 #PHP
You might like
在PHP中使用与Perl兼容的正则表达式
2006/11/26 PHP
YII2.0之Activeform表单组件用法实例
2016/01/09 PHP
用PHP去掉文件头的Unicode签名(BOM)方法
2017/06/22 PHP
JQuery 学习笔记 选择器之六
2009/07/23 Javascript
javascript 用函数语句和表达式定义函数的区别详解
2014/01/06 Javascript
jquery获取当前点击对象的value方法
2014/02/28 Javascript
JavaScript判断表单提交时哪个radio按钮被选中的方法
2015/03/21 Javascript
简单理解vue中track-by属性
2016/10/26 Javascript
五步轻松实现zTree的使用
2017/11/01 Javascript
vue-cli webpack2项目打包优化分享
2018/02/07 Javascript
基于VuePress 轻量级静态网站生成器的实现方法
2018/04/17 Javascript
Node.js文件编码格式的转换的方法
2018/04/27 Javascript
vue实现的树形结构加多选框示例
2019/02/02 Javascript
Node.js 实现简单的无侵入式缓存框架的方法
2019/07/21 Javascript
[01:45]DOTA2众星出演!DSPL刀塔次级职业联赛宣传片
2014/11/21 DOTA
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
pandas 根据列的值选取所有行的示例
2018/11/07 Python
在Pycharm中对代码进行注释和缩进的方法详解
2019/01/20 Python
解决windows上安装tensorflow时报错,“DLL load failed: 找不到指定的模块”的问题
2020/05/20 Python
python-图片流传输的思路及示例(url转换二维码)
2020/12/21 Python
纯CSS3实现图片无间断轮播效果
2016/08/25 HTML / CSS
HTML5是什么 HTML5是什么意思 HTML5简介
2012/10/26 HTML / CSS
基于HTML5实现类似微信手机摇一摇功能(计算摇动次数)
2017/07/24 HTML / CSS
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
英国123鲜花网站:123 Flowers
2019/07/07 全球购物
法国在线药房:1001Pharmacies
2021/03/07 全球购物
快递业务员岗位职责
2014/01/06 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
党的群众路线对照检查材料
2014/08/27 职场文书
四风对照检查剖析材料
2014/10/07 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
上班迟到检讨书范文300字
2014/11/02 职场文书
我们的节日重阳节活动总结
2015/03/24 职场文书
2016年“七一建党节”广播稿
2015/12/18 职场文书
JavaScript实现显示和隐藏图片
2021/04/29 Javascript
python中的被动信息搜集
2021/04/29 Python