当前位置: 移动技术网 > IT编程>开发语言>PHP > CodeIgniter框架钩子机制实现方法【hooks类】

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

2018年09月23日  | 移动技术网IT编程  | 我要评论

贵阳市租房网,断奶后丰胸的技巧看亦姿佳,艾莱依羽绒裤

本文实例讲述了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相关内容感兴趣的读者可查看本站专题:《codeigniter入门教程》、《ci(codeigniter)框架进阶教程》、《php优秀开发框架总结》、《thinkphp入门教程》、《thinkphp常用方法总结》、《zend framework框架入门教程》、《php面向对象程序设计入门教程》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网