当前位置:首页 > PHP教程 > php高级应用 > 列表

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

发布:smiling 来源: PHP粉丝网  添加日期:2018-11-15 09:53:33 浏览: 评论:0 

本文实例讲述了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.   
  19. /** 
  20.  * CodeIgniter Hooks Class 
  21.  * 
  22.  * Provides a mechanism to extend the base system without hacking. 
  23.  * 
  24.  * @package   CodeIgniter 
  25.  * @subpackage Libraries 
  26.  * @category  Libraries 
  27.  * @author   EllisLab Dev Team 
  28.  * @link    http://codeigniter.com/user_guide/libraries/encryption.html 
  29.  */ 
  30. class CI_Hooks { 
  31.   
  32.   /** 
  33.    * Determines wether hooks are enabled 
  34.    * 
  35.    * @var bool 
  36.    */ 
  37.   var $enabled    = FALSE; 
  38.   /** 
  39.    * List of all hooks set in config/hooks.php 
  40.    * 
  41.    * @var array 
  42.    */ 
  43.   var $hooks     = array(); 
  44.   /** 
  45.    * Determines wether hook is in progress, used to prevent infinte loops 
  46.    * 
  47.    * @var bool 
  48.    */ 
  49.   var $in_progress  = FALSE; 
  50.   
  51.   /** 
  52.    * Constructor 
  53.    * 
  54.    */ 
  55.   function __construct() 
  56.   { 
  57.     $this--->_initialize(); 
  58.     log_message('debug'"Hooks Class Initialized"); 
  59.   } 
  60.   
  61.   // -------------------------------------------------------------------- 
  62.   
  63.   /** 
  64.    * Initialize the Hooks Preferences 
  65.    * 
  66.    * @access private 
  67.    * @return void 
  68.    */ 
  69.   function _initialize() 
  70.   { 
  71.     $CFG =& load_class('Config''core'); 
  72.   
  73.     // If hooks are not enabled in the config file 
  74.     // there is nothing else to do 
  75.   
  76.     if ($CFG->item('enable_hooks') == FALSE) 
  77.     { 
  78.       return
  79.     } 
  80.   
  81.     // Grab the "hooks" definition file. 
  82.     // If there are no hooks, we're done. 
  83.   
  84.     if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php')) 
  85.     { 
  86.       include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'); 
  87.     } 
  88.     elseif (is_file(APPPATH.'config/hooks.php')) 
  89.     { 
  90.       include(APPPATH.'config/hooks.php'); 
  91.     } 
  92.   
  93.   
  94.     if ( ! isset($hook) OR ! is_array($hook)) 
  95.     { 
  96.       return
  97.     } 
  98.   
  99.     $this->hooks =& $hook
  100.     $this->enabled = TRUE; 
  101.   } 
  102.   
  103.   // -------------------------------------------------------------------- 
  104.   
  105.   /** 
  106.    * Call Hook 
  107.    * 
  108.    * Calls a particular hook 
  109.    * 
  110.    * @access private 
  111.    * @param  string the hook name 
  112.    * @return mixed 
  113.    */ 
  114.   function _call_hook($which = ''
  115.   { 
  116.     if ( ! $this->enabled OR ! isset($this->hooks[$which])) 
  117.     { 
  118.       return FALSE; 
  119.     } 
  120.   
  121.     if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])) 
  122.     { 
  123.       foreach ($this->hooks[$whichas $val
  124.       { 
  125.         $this->_run_hook($val); 
  126.       } 
  127.     } 
  128.     else 
  129.     { 
  130.       $this->_run_hook($this->hooks[$which]); 
  131.     } 
  132.   
  133.     return TRUE; 
  134.   } 
  135.   
  136.   // -------------------------------------------------------------------- 
  137.   
  138.   /** 
  139.    * Run Hook 
  140.    * 
  141.    * Runs a particular hook 
  142.    * 
  143.    * @access private 
  144.    * @param  array  the hook details 
  145.    * @return bool 
  146.    */ 
  147.   function _run_hook($data
  148.   { 
  149.     if ( ! is_array($data)) 
  150.     { 
  151.       return FALSE; 
  152.     } 
  153.   
  154.     // ----------------------------------- 
  155.     // Safety - Prevents run-away loops 
  156.     // ----------------------------------- 
  157.   
  158.     // If the script being called happens to have the same 
  159.     // hook call within it a loop can happen 
  160.   
  161.     if ($this->in_progress == TRUE) 
  162.     { 
  163.       return
  164.     } 
  165.   
  166.     // ----------------------------------- 
  167.     // Set file path 
  168.     // ----------------------------------- 
  169.   
  170.     if ( ! isset($data['filepath']) OR ! isset($data['filename'])) 
  171.     { 
  172.       return FALSE; 
  173.     } 
  174.   
  175.     $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; 
  176.   
  177.     if ( ! file_exists($filepath)) 
  178.     { 
  179.       return FALSE; 
  180.     } 
  181.   
  182.     // ----------------------------------- 
  183.     // Set class/function name 
  184.     // ----------------------------------- 
  185.   
  186.     $class   = FALSE; 
  187.     $function = FALSE; 
  188.     $params    = ''
  189.   
  190.     if (isset($data['class']) AND $data['class'] != ''
  191.     { 
  192.       $class = $data['class']; 
  193.     } 
  194.   
  195.     if (isset($data['function'])) 
  196.     { 
  197.       $function = $data['function']; 
  198.     } 
  199.   
  200.     if (isset($data['params'])) 
  201.     { 
  202.       $params = $data['params']; 
  203.     } 
  204.   
  205.     if ($class === FALSE AND $function === FALSE) 
  206.     { 
  207.       return FALSE; 
  208.     } 
  209.   
  210.     // ----------------------------------- 
  211.     // Set the in_progress flag 
  212.     // ----------------------------------- 
  213.   
  214.     $this->in_progress = TRUE; 
  215.   
  216.     // ----------------------------------- 
  217.     // Call the requested class and/or function 
  218.     // ----------------------------------- 
  219.   
  220.     if ($class !== FALSE) 
  221.     { 
  222.       if ( ! class_exists($class)) 
  223.       { 
  224.         require($filepath); 
  225.       } 
  226.   
  227.       $HOOK = new $class
  228.       $HOOK->$function($params); 
  229.     } 
  230.     else 
  231.     { 
  232.       if ( ! function_exists($function)) 
  233.       { 
  234.         require($filepath); 
  235.       } 
  236.   
  237.       $function($params); 
  238.     } 
  239.   
  240.     $this->in_progress = FALSE; 
  241.     return TRUE; 
  242.   } //phpfensi.com 
  243.   
  244.   
  245. // END CI_Hooks class 
  246.   
  247. /* End of file Hooks.php */ 
  248. /* Location: ./system/core/Hooks.php */ 

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

Tags: CodeIgniter hooks类

分享到: