Ahgigu 发表于 2013-11-20 09:33:35

使用hook实现过滤器before_filter

MY_Controller:


class MY_Controller extends CI_Controller {

    private $_hooks = array();


    public function __construct() {
      parent::__construct();

      $this->_hooks = $this->before_filter();
      $this->_post_controller_constructor_hooks();
    }

    protected function before_filter() {
      return array();
    }

    private function _post_controller_constructor_hooks() {
      if (!empty($this->_hooks)) {
            $func = $this->router->fetch_method();
            if(!empty($this->_hooks[$func])){
                $this->hooks->set_post_controller_constructor_hooks($this->_hooks[$func]);
            }
      }
    }

}


MY_Hooks:

class MY_Hooks extends CI_Hooks {

    function __construct()
    {
      parent::__construct();

      log_message('debug', "BI Hooks Class Initialized");
    }

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

      foreach ($hook as $key => $value) {
            $this->hooks[$value['type']][] = $value;
      }
                $this->enabled = TRUE;
        }

        /**
       * Set the post controller constructor hooks
       *
       * @access        public
       * @return        void
       */
    public function set_post_controller_constructor_hooks($hooks){
      $_hooks = array();
      $count = count($hooks);
      $post_hooks = $this->hooks['post_controller_constructor'];

      for($i=0; $i<$count; $i++) {
            $_hooks[] = $post_hooks[$this->search_2d_array_by_value($hooks[$i], 'name', $post_hooks)];
      }

      $this->hooks['post_controller_constructor'] = array_filter($_hooks);
    }

    function search_2d_array_by_value($value, $key_name, $array)
    {
      foreach ($array as $key => $val)
      {
            if ($val[$key_name] == $value)
            {
                return $key;
            }
      }
      return NULL;
    }

}


config/hooks:

$hook['auth'] = array(
    'name' => 'auth',
    'type' => 'post_controller_constructor',
    'class' => 'AccessHook',
    'function' => 'check_access',
    'filename' => 'AccessHook.php',
    'filepath' => 'hooks'
);
$hook['new_message'] = array(
    'name' => 'new_message',
    'type' => 'post_controller_constructor',
    'class' => 'MessageHook',
    'function' => 'new_message',
    'filename' => 'MessageHook.php',
    'filepath' => 'hooks'
);




Post_Controller:

class Post_Controller extends MY_Controller {

public function view(){

echo "view post";
}

public function list(){

echo "list all posts";
}
    protected function before_filter(){
      $_filter = array();
      $_filter['list'] = array('auth','new_message');
      $_filter['view'] = array('new_message', 'auth');
      return $_filter;
    }

}


说明:
挂钩在CI的post_controller_constructor这个点上的代码,会在controller构造函数之后action调用之前被执行,
利用这个机制,实现过滤器要解决三个问题:
1.过滤器必须有唯一名字;
1.指定哪些action需要哪些过滤器(通过过滤器名字来设定);
2.当有多个过滤器时,指定执行先后顺序;



魔侠 发表于 2015-1-21 15:45:18

这个东西能用来做什么?
页: [1]
查看完整版本: 使用hook实现过滤器before_filter