在不修改CI框架底层的基础上,实现对特定uri的方法主体钩子触发
转发至:https://my.oschina.net/querying/blog/1822324
注意配置config/config.php
的$config['enable_hooks'] = 1
配置config/hooks.php
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
| Hooks
| -------------------------------------------------------------------------
| This file lets you define "hooks" to extend CI without hacking the core
| files. Please see the user guide for info:
|
| http://codeigniter.com/user_guide/general/hooks.html
|
*/
/* End of file hooks.php */
/* Location: ./application/config/hooks.php */
//控制器方法执行之前
$hook['post_controller_constructor'] = [
'class' => 'hooks_init',
'function' => 'before_method',
'filename' => 'hooks_init.php',
'filepath' => 'hooks',
];
//控制器方法执行之后
$hook['post_controller'] = [
'class' => 'hooks_init',
'function' => 'after_method',
'filename' => 'hooks_init.php',
'filepath' => 'hooks',
];
增加钩子公共触发类,并在此类中来实现特定触发逻辑
<?php
class hooks_init extends CI_Hooks
{
public $CI;
public $config = [];
/**
* hooks_init constructor.
*/
public function __construct()
{
parent::__construct();
$this->CI = & get_instance();
$module_name = $this->CI->router->directory;
$module_name = (string) explode('/',$module_name)[0];
//类名
$class_name = $this->CI->router->class;
//调用方法名
$method_name = $this->CI->router->method;
//不同模块的配置文件引入
$hook_config_filepath = APPPATH."config/aop/{$module_name}.php";
if( !file_exists($hook_config_filepath) ){
return false;
}
$module_config = require $hook_config_filepath;
$config_key = "{$class_name}/{$method_name}";
$this->config = isset($module_config[$config_key]) ? $module_config[$config_key]:"";
return $this;
}
//主体方法调用之前执行
public function before_method(){
$config_data = isset($this->config['_before'])?$this->config['_before']:[];
if(empty($config_data)){
return false;
}else{
return $this->call_function($config_data);
}
}
//主体方法调用之前执行
public function after_method(){
$config_data = isset($this->config['_after'])?$this->config['_after']:[];
if(empty($config_data)){
return false;
}else{
return $this->call_function($config_data);
}
}
private function call_function($config_data){
if(empty($config_data['filename'])){
return false;
}
$hook_class_filepath = APPPATH.'hooks/'.$config_data['filename'];
if( !file_exists($hook_class_filepath) ){
return false;
}else{
require_once $hook_class_filepath;
}
if(!isset($config_data['class']) || !class_exists($config_data['class'])){
show_error("{$config_data['class']}该类不存在!");
die;
}
$parmas = isset($config_data['params']) ? $config_data['params'] : [];
$function = isset($config_data['function'])? $config_data['function'] : "";
$hook_obj = new $config_data['class']();
return call_user_func_array([$hook_obj,$function],$parmas);
}
}
添加admin模块的钩子配置
config/aop/admin.php
<?php
/**
* Created by PhpStorm.
* User: querying
* Date: 18-5-17
* Time: 下午2:43
* Describe: 该配置主要扩展CI框架的钩子功能
*
* CI的钩子在全局流程中调用,
* 但由于并没有针对控制器类的具体方法执行钩子配置,
* 因此对其进行扩展
*
*
*
*/
//模块名
$hook_nodes = [
//配置详解
//类名/方法名
'admin_login/index' => [
//方法执行前的钩子配置
'_before' => [
//要引入的类
'class' => 'require_class_name',
//要执行的方法
'function' => 'hook_exec_func_name_before',
//application/hooks下的文件路径
'filename' => 'admin/hook_file_path.php',
//传递的参数
'params' => []
],
//方法执行后的钩子配置
'_after' => [
//要引入的类
'class' => 'require_class_name',
//要执行的方法
'function' => 'hook_exec_func_name_after',
//application/hooks下的文件路径
'filename' => 'admin/hook_file_path.php',
],
],
'admin_keep/add_pdf_file' => [
//方法执行后的钩子配置
'_after' => [
//要引入的类
'class' => 'require_class_name',
//要执行的方法
'function' => 'hook_exec_func_name_after',
//application/hooks下的文件路径
'filename' => 'admin/hook_file_path.php',
],
],
];
return $hook_nodes;
根据配置文件在hooks/
目录下添加各个模块的钩子调用类
demo:
application/hooks/admin/hook_file_path.php
<?php
class require_class_name extends CI_controller
{
public function hook_exec_func_name_after
{
//
}
public function hook_exec_func_name_before
{
}
}