A-A+

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

2019年02月15日 我爱编程 暂无评论

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

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

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

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

另附codeigniter的hooks类的源代码:

  1. <!--?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3.  * CodeIgniter
  4.  *
  5.  * An open source application development framework for PHP 5.1.6 or newer
  6.  *
  7.  * @package   CodeIgniter
  8.  * @author   EllisLab Dev Team
  9.  * @copyright    Copyright (c) 2008 - 2014, EllisLab, Inc.
  10.  * @copyright    Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
  11.  * @license   http://codeigniter.com/user_guide/license.html
  12.  * @link    http://codeigniter.com
  13.  * @since    Version 1.0
  14.  * @filesource
  15.  */
  16. // ------------------------------------------------------------------------
  17. /**
  18.  * CodeIgniter Hooks Class
  19.  *
  20.  * Provides a mechanism to extend the base system without hacking.
  21.  *
  22.  * @package   CodeIgniter
  23.  * @subpackage Libraries
  24.  * @category  Libraries
  25.  * @author   EllisLab Dev Team
  26.  * @link    http://codeigniter.com/user_guide/libraries/encryption.html
  27.  */
  28. class CI_Hooks {
  29.   /**
  30.    * Determines wether hooks are enabled
  31.    *
  32.    * @var bool
  33.    */
  34.   var $enabled    = FALSE;
  35.   /**
  36.    * List of all hooks set in config/hooks.php
  37.    *
  38.    * @var array
  39.    */
  40.   var $hooks     = array();
  41.   /**
  42.    * Determines wether hook is in progress, used to prevent infinte loops
  43.    *
  44.    * @var bool
  45.    */
  46.   var $in_progress  = FALSE;
  47.   /**
  48.    * Constructor
  49.    *
  50.    */
  51.   function __construct()
  52.   {
  53.     $this--->_initialize();
  54.     log_message('debug'"Hooks Class Initialized");
  55.   }
  56.   // --------------------------------------------------------------------
  57.   /**
  58.    * Initialize the Hooks Preferences
  59.    *
  60.    * @access private
  61.    * @return void
  62.    */
  63.   function _initialize()
  64.   {
  65.     $CFG =& load_class('Config''core');
  66.     // If hooks are not enabled in the config file
  67.     // there is nothing else to do
  68.     if ($CFG->item('enable_hooks') == FALSE)
  69.     {
  70.       return;
  71.     }
  72.     // Grab the "hooks" definition file.
  73.     // If there are no hooks, we're done.
  74.     if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
  75.     {
  76.       include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
  77.     }
  78.     elseif (is_file(APPPATH.'config/hooks.php'))
  79.     {
  80.       include(APPPATH.'config/hooks.php');
  81.     }
  82.     if ( ! isset($hook) OR ! is_array($hook))
  83.     {
  84.       return;
  85.     }
  86.     $this->hooks =& $hook;
  87.     $this->enabled = TRUE;
  88.   }
  89.   // --------------------------------------------------------------------
  90.   /**
  91.    * Call Hook
  92.    *
  93.    * Calls a particular hook
  94.    *
  95.    * @access private
  96.    * @param  string the hook name
  97.    * @return mixed
  98.    */
  99.   function _call_hook($which = '')
  100.   {
  101.     if ( ! $this->enabled OR ! isset($this->hooks[$which]))
  102.     {
  103.       return FALSE;
  104.     }
  105.     if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0]))
  106.     {
  107.       foreach ($this->hooks[$whichas $val)
  108.       {
  109.         $this->_run_hook($val);
  110.       }
  111.     }
  112.     else
  113.     {
  114.       $this->_run_hook($this->hooks[$which]);
  115.     }
  116.     return TRUE;
  117.   }
  118.   // --------------------------------------------------------------------
  119.   /**
  120.    * Run Hook
  121.    *
  122.    * Runs a particular hook
  123.    *
  124.    * @access private
  125.    * @param  array  the hook details
  126.    * @return bool
  127.    */
  128.   function _run_hook($data)
  129.   {
  130.     if ( ! is_array($data))
  131.     {
  132.       return FALSE;
  133.     }
  134.     // -----------------------------------
  135.     // Safety - Prevents run-away loops
  136.     // -----------------------------------
  137.     // If the script being called happens to have the same
  138.     // hook call within it a loop can happen
  139.     if ($this->in_progress == TRUE)
  140.     {
  141.       return;
  142.     }
  143.     // -----------------------------------
  144.     // Set file path
  145.     // -----------------------------------
  146.     if ( ! isset($data['filepath']) OR ! isset($data['filename']))
  147.     {
  148.       return FALSE;
  149.     }
  150.     $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
  151.     if ( ! file_exists($filepath))
  152.     {
  153.       return FALSE;
  154.     }
  155.     // -----------------------------------
  156.     // Set class/function name
  157.     // -----------------------------------
  158.     $class   = FALSE;
  159.     $function = FALSE;
  160.     $params    = '';
  161.     if (isset($data['class']) AND $data['class'] != '')
  162.     {
  163.       $class = $data['class'];
  164.     }
  165.     if (isset($data['function']))
  166.     {
  167.       $function = $data['function'];
  168.     }
  169.     if (isset($data['params']))
  170.     {
  171.       $params = $data['params'];
  172.     }
  173.     if ($class === FALSE AND $function === FALSE)
  174.     {
  175.       return FALSE;
  176.     }
  177.     // -----------------------------------
  178.     // Set the in_progress flag
  179.     // -----------------------------------
  180.     $this->in_progress = TRUE;
  181.     // -----------------------------------
  182.     // Call the requested class and/or function
  183.     // -----------------------------------
  184.     if ($class !== FALSE)
  185.     {
  186.       if ( ! class_exists($class))
  187.       {
  188.         require($filepath);
  189.       }
  190.       $HOOK = new $class;
  191.       $HOOK->$function($params);
  192.     }
  193.     else
  194.     {
  195.       if ( ! function_exists($function))
  196.       {
  197.         require($filepath);
  198.       }
  199.       $function($params);
  200.     }
  201.     $this->in_progress = FALSE;
  202.     return TRUE;
  203.   } //
  204. }
  205. // END CI_Hooks class
  206. /* End of file Hooks.php */
  207. /* Location: ./system/core/Hooks.php */

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

标签:

给我留言

Copyright © 四季博客 保留所有权利.   Theme  Ality

用户登录