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

PHP钩子机制原理及详解

发布:smiling 来源: PHP粉丝网  添加日期:2022-05-26 10:56:53 浏览: 评论:0 

什么是钩子?

大家想必听过插件,wordpress插件特别多,这个就是用钩子机制实现的。

当代码在运行的过程中,我们预先在运行的几个特殊点里执行一些特殊方法:例如在运行方法(例如Blog::add的add方法)之前记录输入参数、运行方法之后记录处理结果,这个运行方法之前、运行方法之后就是简单的钩子(挂载点),我们在这个钩子上放置钩子函数(记录输入参数、记录处理结果),执行一些和程序运行不相关的任务。

  1. <?php 
  2.  
  3. class Blog extends Controller{ 
  4.  
  5.       
  6.  
  7.     public function add(){ 
  8.  
  9.           
  10.  
  11.         //some code 
  12.  
  13.         $res = $data; 
  14.  
  15.           
  16.  
  17.         return $res; 
  18.  
  19.     } 
  20.  
  21. } 
  22.  
  23. $obj = new Blog(); 
  24.  
  25. Log::write($_REQUEST); 
  26.  
  27. $res =  $obj->add(); 
  28.  
  29. Log::write(json_encode($res)); 

如果在运行方法之前放置的是一个OnBeforeRunActionCallback()的方法,这个方法可能最开始的时候是空的,但我们以后就可以不去修改原有代码,直接在OnBeforeRunActionCallback()里面加代码逻辑就可以了,例如记录日志、参数过滤等等。

  1. <?php 
  2.  
  3. class Blog extends Controller{ 
  4.  
  5.       
  6.  
  7.     public function add(){ 
  8.  
  9.           
  10.  
  11.         //some code 
  12.  
  13.         $res = $data; 
  14.  
  15.           
  16.  
  17.         return $res; 
  18.  
  19.     } 
  20.  
  21. } 
  22.  
  23. $obj = new Blog(); 
  24.  
  25. OnBeforeRunActionCallback($_REQUEST); 
  26.  
  27. $obj->add(); 
  28.  
  29. OnAfterRunActionCallback($res); 
  30.  
  31. function OnBeforeRunActionCallback($param){ 
  32.  
  33.     Log::write($param); 
  34.  
  35.         FilterParams($param); 
  36.  
  37. } 
  38.  
  39. function OnAfterRunActionCallback($res){ 
  40.  
  41.     Log::write(json_encode($res)); 
  42.  
  43. } 

在项目代码中,你认为要扩展(暂时不扩展)的地方放置一个钩子函数,等需要扩展的时候,把需要实现的类和函数挂载到这个钩子上,就可以实现扩展了。

原理

实际的钩子一般设计为一个类Hook,该类提供注册插件到钩子(add_hook)、触发钩子方法(trigger_hook)。注册插件的时候将插件所要运行的可执行方法存储到钩子对应的数组里面。

  1. $_listeners = array( 
  2.  
  3.     'OnBeforeRunAction' => array( 
  4.  
  5.         'callback1', 
  6.  
  7.         'callback2', 
  8.  
  9.         'callback3', 
  10.  
  11.     ), 
  12.  
  13. ); 
  14.  
  15. //提前注册插件到钩子 
  16.  
  17. add_hook('OnBeforeRunAction', 'callback4'); 
  18.  
  19. //特定地方执行钩子 
  20.  
  21. trigger_hook('OnBeforeRunAction'); 

当触发钩子的时候,将遍历OnBeforeRunAction里注册的回调方法,执行对应的回调方法,实现动态扩展功能。注册的钩子方法一般是匿名函数:

  1. function trigger_hook($hook, $data=''){ 
  2.  
  3.     //查看要实现的钩子,是否在监听数组之中 
  4.  
  5.     if (isset($this->_listeners[$hook]) && is_array($this->_listeners[$hook]) && count($this->_listeners[$hook]) > 0) 
  6.  
  7.     { 
  8.  
  9.         // 循环调用开始 
  10.  
  11.         foreach ($this->_listeners[$hook] as $listener) 
  12.  
  13.         { 
  14.  
  15.             if(is_callable()){ 
  16.  
  17.                 call_user_func($listener, $data); 
  18.  
  19.             }elseif(is_array($listener)){ 
  20.  
  21.                 // 取出插件对象的引用和方法 
  22.  
  23.                 $class =& $listener[0]; 
  24.  
  25.                 $method = $listener[1]; 
  26.  
  27.                 if(method_exists($class,$method)) 
  28.  
  29.                 { 
  30.  
  31.                     // 动态调用插件的方法 
  32.  
  33.                     $class->$method($data); 
  34.  
  35.                 } 
  36.  
  37.             } 
  38.  
  39.         } 
  40.  
  41.     } 
  42.  
  43. } 

如何实现?

简单的

1、插件类Hook:提供注册插件和执行插件的方法,实际是往一个数组里存挂载点对应的可执行方法。

2、在某个配置文件或者函数里统一注册插件。

  1. class Hook 
  2.  
  3. { 
  4.  
  5.     //action hooks array   
  6.  
  7.     private static $actions = array(); 
  8.  
  9.     /** 
  10.  
  11.      * ads a function to an action hook 
  12.  
  13.      * @param $hook 
  14.  
  15.      * @param $function 
  16.  
  17.      */ 
  18.  
  19.     public static function add_action($hook,$function) 
  20.  
  21.     {    
  22.  
  23.         $hook=mb_strtolower($hook,CHARSET); 
  24.  
  25.         // create an array of function handlers if it doesn't already exist 
  26.  
  27.         if(!self::exists_action($hook)) 
  28.  
  29.         { 
  30.  
  31.             self::$actions[$hook] = array(); 
  32.  
  33.         } 
  34.  
  35.         // append the current function to the list of function handlers 
  36.  
  37.         if (is_callable($function)) 
  38.  
  39.         { 
  40.  
  41.             self::$actions[$hook][] = $function; 
  42.  
  43.             return TRUE; 
  44.  
  45.         } 
  46.  
  47.         return FALSE ; 
  48.  
  49.     } 
  50.  
  51.     /** 
  52.  
  53.      * executes the functions for the given hook 
  54.  
  55.      * @param string $hook 
  56.  
  57.      * @param array $params 
  58.  
  59.      * @return boolean true if a hook was setted 
  60.  
  61.      */ 
  62.  
  63.     public static function do_action($hook,$params=NULL) 
  64.  
  65.     { 
  66.  
  67.         $hook=mb_strtolower($hook,CHARSET); 
  68.  
  69.         if(isset(self::$actions[$hook])) 
  70.  
  71.         { 
  72.  
  73.             // call each function handler associated with this hook 
  74.  
  75.             foreach(self::$actions[$hook] as $function) 
  76.  
  77.             { 
  78.  
  79.                 if (is_array($params)) 
  80.  
  81.                 { 
  82.  
  83.                     call_user_func_array($function,$params); 
  84.  
  85.                 } 
  86.  
  87.                 else 
  88.  
  89.                 { 
  90.  
  91.                     call_user_func($function); 
  92.  
  93.                 } 
  94.  
  95.                 //cant return anything since we are in a loop! dude! 
  96.  
  97.             } 
  98.  
  99.             return TRUE; 
  100.  
  101.         } 
  102.  
  103.         return FALSE; 
  104.  
  105.     } 
  106.  
  107.     /** 
  108.  
  109.      * gets the functions for the given hook 
  110.  
  111.      * @param string $hook 
  112.  
  113.      * @return mixed 
  114.  
  115.      */ 
  116.  
  117.     public static function get_action($hook) 
  118.  
  119.     { 
  120.  
  121.         $hook=mb_strtolower($hook,CHARSET); 
  122.  
  123.         return (isset(self::$actions[$hook]))? self::$actions[$hook]:FALSE; 
  124.  
  125.     } 
  126.  
  127.     /** 
  128.  
  129.      * check exists the functions for the given hook 
  130.  
  131.      * @param string $hook 
  132.  
  133.      * @return boolean 
  134.  
  135.      */ 
  136.  
  137.     public static function exists_action($hook) 
  138.  
  139.     { 
  140.  
  141.         $hook=mb_strtolower($hook,CHARSET); 
  142.  
  143.         return (isset(self::$actions[$hook]))? TRUE:FALSE; 
  144.  
  145.     } 
  146.  
  147. } 
  148.  
  149.    
  150.  
  151.     /** 
  152.  
  153.      * Hooks Shortcuts not in class 
  154.  
  155.      */ 
  156.  
  157.     function add_action($hook,$function) 
  158.  
  159.     { 
  160.  
  161.         return Hook::add_action($hook,$function); 
  162.  
  163.     } 
  164.  
  165.    
  166.  
  167.     function do_action($hook) 
  168.  
  169.     { 
  170.  
  171.         return Hook::do_action($hook); 
  172.  
  173.     } 

用法举例:

  1. //添加钩子 
  2.  
  3. Hook::add_action('unique_name_hook','some_class::hook_test'); 
  4.  
  5. //或使用快捷函数添加钩子: 
  6.  
  7. add_action('unique_name_hook','other_class::hello'); 
  8.  
  9. add_action('unique_name_hook','some_public_function'); 
  10.  
  11. //执行钩子 
  12.  
  13. do_action('unique_name_hook');//也可以使用 Hook::do_action(); 

带安装/卸载的

钩子类初始化的时候去注册已经开启的插件(如数据库记录);全局合适的时候设置挂载点;运行到合适的时候触发挂载点注册的事件。

1、插件类Hook:提供注册插件和执行插件的方法,实际是往一个数组里存挂载点对应的可执行方法。

2、插件类增加一个初始化的方法,去数据查找已经安装的插件,运行插件必须执行的注册方法(reg),注册插件方法注册钩子到挂载点。

3、固定把插件放在某个目录,并安照一定规范写配置文件。后台有插件列表页面,遍历指定目录下的插件。当安装的时候,将插件信息记录到数据库,卸载的时候删除数据库记录信息。

  1. <?php 
  2.  
  3. /** 
  4.  
  5.  * @file plugin.php 
  6.  
  7.  * @brief 插件核心类 
  8.  
  9.  * @note 观察者模式,注册事件,触发事件 
  10.  
  11.  */ 
  12.  
  13. class plugin extends IInterceptorBase 
  14.  
  15. { 
  16.  
  17.     //默认开启的插件列表 
  18.  
  19.     private static $defaultList = array("_verification","_goodsCategoryWidget","_authorization","_userInfo","_initData"); 
  20.  
  21.     //已经注册监听 
  22.  
  23.     private static $_listen = array(); 
  24.  
  25.     //加载插件 
  26.  
  27.     public static function init() 
  28.  
  29.     { 
  30.  
  31.         $pluginDB    = new IModel('plugin'); 
  32.  
  33.         $pluginList  = $pluginDB->query("is_open = 1","class_name","sort asc"); 
  34.  
  35.         //加载默认插件 
  36.  
  37.         foreach(self::$defaultList as $val) 
  38.  
  39.         { 
  40.  
  41.             $pluginList[]= array('class_name' => $val); 
  42.  
  43.         } 
  44.  
  45.         foreach($pluginList as $key => $val) 
  46.  
  47.         { 
  48.  
  49.             $className = $val['class_name']; 
  50.  
  51.             $classFile = self::path().$className."/".$className.".php"; 
  52.  
  53.             if(is_file($classFile)) 
  54.  
  55.             { 
  56.  
  57.                 include_once($classFile); 
  58.  
  59.                 $pluginObj = new $className(); 
  60.  
  61.                 $pluginObj->reg(); 
  62.  
  63.             } 
  64.  
  65.         } 
  66.  
  67.     } 
  68.  
  69.     /** 
  70.  
  71.      * @brief 注册事件 
  72.  
  73.      * @param string $event 事件 
  74.  
  75.      * @param object ro function $classObj 类实例 或者 匿名函数 
  76.  
  77.      * @param string $method 方法名字 
  78.  
  79.      */ 
  80.  
  81.     public static function reg($event,$classObj,$method = "") 
  82.  
  83.     { 
  84.  
  85.         if(!isset(self::$_listen[$event])) 
  86.  
  87.         { 
  88.  
  89.             self::$_listen[$event] = array(); 
  90.  
  91.         } 
  92.  
  93.         self::$_listen[$event][] = array($classObj,$method); 
  94.  
  95.     } 
  96.  
  97.     /** 
  98.  
  99.      * @brief 显示已注册事件 
  100.  
  101.      * @param string $event 事件名称 
  102.  
  103.      * @return array 
  104.  
  105.      */ 
  106.  
  107.     public static function get($event = '') 
  108.  
  109.     { 
  110.  
  111.         if($event) 
  112.  
  113.         { 
  114.  
  115.             if( isset(self::$_listen[$event]) ) 
  116.  
  117.             { 
  118.  
  119.                 return self::$_listen[$event]; 
  120.  
  121.             } 
  122.  
  123.             return null; 
  124.  
  125.         } 
  126.  
  127.         return self::$_listen; 
  128.  
  129.     } 
  130.  
  131.     /** 
  132.  
  133.      * @brief 触发事件 
  134.  
  135.      * @param string $event 事件 
  136.  
  137.      * @param mixed  $data  数据 
  138.  
  139.      * @notice 可以调用匿名函数和方法 
  140.  
  141.      */ 
  142.  
  143.     public static function trigger($event,$data = null) 
  144.  
  145.     { 
  146.  
  147.         $result = array(); 
  148.  
  149.         if(isset(self::$_listen[$event])) 
  150.  
  151.         { 
  152.  
  153.             foreach(self::$_listen[$event] as $key => $val) 
  154.  
  155.             { 
  156.  
  157.                 list($pluginObj,$pluginMethod) = $val; 
  158.  
  159.                 $result[$key] = is_callable($pluginObj) ? call_user_func($pluginObj,$data):call_user_func(array($pluginObj,$pluginMethod),$data); 
  160.  
  161.             } 
  162.  
  163.         } 
  164.  
  165.         return isset($result[1]) ? $result : current($result); 
  166.  
  167.     } 
  168.  
  169.     /** 
  170.  
  171.      * @brief 插件物理路径 
  172.  
  173.      * @return string 路径字符串 
  174.  
  175.      */ 
  176.  
  177.     public static function path() 
  178.  
  179.     { 
  180.  
  181.         return IWeb::$app->getBasePath()."plugins/"; 
  182.  
  183.     } 
  184.  
  185.     /** 
  186.  
  187.      * @brief 插件WEB路径 
  188.  
  189.      * @return string 路径字符串 
  190.  
  191.      */ 
  192.  
  193.     public static function webPath() 
  194.  
  195.     { 
  196.  
  197.         return IUrl::creatUrl('')."plugins/"; 
  198.  
  199.     } 
  200.  
  201.     /** 
  202.  
  203.      * @brief 获取全部插件 
  204.  
  205.      * @param string $name 插件名字,如果为空则获取全部插件信息 
  206.  
  207.      * @return array 插件信息 array( 
  208.  
  209.         "name"        => 插件名字, 
  210.  
  211.         "description" => 插件描述, 
  212.  
  213.         "explain"     => 使用说明, 
  214.  
  215.         "class_name"  => 插件ID, 
  216.  
  217.         "is_open"     => 是否开启, 
  218.  
  219.         "is_install"  => 是否安装, 
  220.  
  221.         "config_name" => 默认插件参数结构, 
  222.  
  223.         "config_param"=> 已经保存的插件参数, 
  224.  
  225.         "sort"        => 排序, 
  226.  
  227.      ) 
  228.  
  229.      */ 
  230.  
  231.     public static function getItems($name = '') 
  232.  
  233.     { 
  234.  
  235.         $result = array(); 
  236.  
  237.         $dirRes = opendir(self::path()); 
  238.  
  239.         //遍历目录读取配置文件 
  240.  
  241.         $pluginDB = new IModel('plugin'); 
  242.  
  243.         while($dir = readdir($dirRes)) 
  244.  
  245.         { 
  246.  
  247.             if($dir[0] == "." || $dir[0] == "_") 
  248.  
  249.             { 
  250.  
  251.                 continue; 
  252.  
  253.             } 
  254.  
  255.             if($name && $result) 
  256.  
  257.             { 
  258.  
  259.                 break; 
  260.  
  261.             } 
  262.  
  263.             if($name && $dir != $name) 
  264.  
  265.             { 
  266.  
  267.                 continue; 
  268.  
  269.             } 
  270.  
  271.             $pluginIndex = self::path().$dir."/".$dir.".php"; 
  272.  
  273.             if(is_file($pluginIndex)) 
  274.  
  275.             { 
  276.  
  277.                 include_once($pluginIndex); 
  278.  
  279.                 if(get_parent_class($dir) == "pluginBase") 
  280.  
  281.                 { 
  282.  
  283.                     $class_name   = $dir; 
  284.  
  285.                     $pluginRow    = $pluginDB->getObj('class_name = "'.$class_name.'"'); 
  286.  
  287.                     $is_open      = $pluginRow ? $pluginRow['is_open'] : 0; 
  288.  
  289.                     $is_install   = $pluginRow ? 1                     : 0; 
  290.  
  291.                     $sort         = $pluginRow ? $pluginRow['sort']    : 99; 
  292.  
  293.                     $config_param = array(); 
  294.  
  295.                     if($pluginRow && $pluginRow['config_param']) 
  296.  
  297.                     { 
  298.  
  299.                         $config_param = JSON::decode($pluginRow['config_param']); 
  300.  
  301.                     } 
  302.  
  303.                     $result[$dir] = array( 
  304.  
  305.                         "name"        => $class_name::name(), 
  306.  
  307.                         "description" => $class_name::description(), 
  308.  
  309.                         "explain"     => $class_name::explain(), 
  310.  
  311.                         "class_name"  => $class_name, 
  312.  
  313.                         "is_open"     => $is_open, 
  314.  
  315.                         "is_install"  => $is_install, 
  316.  
  317.                         "config_name" => $class_name::configName(), 
  318.  
  319.                         "config_param"=> $config_param, 
  320.  
  321.                         "sort"        => $sort, 
  322.  
  323.                     ); 
  324.  
  325.                 } 
  326.  
  327.             } 
  328.  
  329.         } 
  330.  
  331.         if(!$name) 
  332.  
  333.         { 
  334.  
  335.             return $result; 
  336.  
  337.         } 
  338.  
  339.         return isset($result[$name]) ? $result[$name] : array(); 
  340.  
  341.     } 
  342.  
  343.     /** 
  344.  
  345.      * @brief 系统内置的所有事件触发 
  346.  
  347.      */ 
  348.  
  349.     public static function onCreateApp(){plugin::init();plugin::trigger("onCreateApp");} 
  350.  
  351.     public static function onFinishApp(){plugin::trigger("onFinishApp");} 
  352.  
  353.     public static function onBeforeCreateController($ctrlId){plugin::trigger("onBeforeCreateController",$ctrlId);plugin::trigger("onBeforeCreateController@".$ctrlId);} 
  354.  
  355.     public static function onCreateController($ctrlObj){plugin::trigger("onCreateController");plugin::trigger("onCreateController@".$ctrlObj->getId());} 
  356.  
  357.     public static function onFinishController($ctrlObj){plugin::trigger("onFinishController");plugin::trigger("onFinishController@".$ctrlObj->getId());} 
  358.  
  359.     public static function onBeforeCreateAction($ctrlObj,$actionId){plugin::trigger("onBeforeCreateAction",$actionId);plugin::trigger("onBeforeCreateAction@".$ctrlObj->getId());plugin::trigger("onBeforeCreateAction@".$ctrlObj->getId()."@".$actionId);} 
  360.  
  361.     public static function onCreateAction($ctrlObj,$actionObj){plugin::trigger("onCreateAction");plugin::trigger("onCreateAction@".$ctrlObj->getId());plugin::trigger("onCreateAction@".$ctrlObj->getId()."@".$actionObj->getId());} 
  362.  
  363.     public static function onFinishAction($ctrlObj,$actionObj){plugin::trigger("onFinishAction");plugin::trigger("onFinishAction@".$ctrlObj->getId());plugin::trigger("onFinishAction@".$ctrlObj->getId()."@".$actionObj->getId());} 
  364.  
  365.     public static function onCreateView($ctrlObj,$actionObj){plugin::trigger("onCreateView");plugin::trigger("onCreateView@".$ctrlObj->getId());plugin::trigger("onCreateView@".$ctrlObj->getId()."@".$actionObj->getId());} 
  366.  
  367.     public static function onFinishView($ctrlObj,$actionObj){plugin::trigger("onFinishView");plugin::trigger("onFinishView@".$ctrlObj->getId());plugin::trigger("onFinishView@".$ctrlObj->getId()."@".$actionObj->getId());} 
  368.  
  369.     public static function onPhpShutDown(){plugin::trigger("onPhpShutDown");} 
  370.  
  371. } 
  372.  
  373. /** 
  374.  
  375.  * @brief 插件基类,所有插件必须继承此类 
  376.  
  377.  * @notice 必须实现3个抽象方法: reg(),name(),description() 
  378.  
  379.  */ 
  380.  
  381. abstract class pluginBase extends IInterceptorBase 
  382.  
  383. { 
  384.  
  385.     //错误信息 
  386.  
  387.     protected $error = array(); 
  388.  
  389.     //注册事件接口,内部通过调用payment::reg(事件,对象实例,方法); 
  390.  
  391.     public function reg(){} 
  392.  
  393.     /** 
  394.  
  395.      * @brief 默认插件参数信息,写入到plugin表config_param字段 
  396.  
  397.      * @return array("字段名" => array( 
  398.  
  399.          "name"    => "文字显示", 
  400.  
  401.          "type"    => "数据类型【text,radio,checkbox,select】", 
  402.  
  403.          "pattern" => "数据校验【int,float,date,datetime,require,正则表达式】", 
  404.  
  405.          "value"   => "1,数组:枚举数据【radio,checkbox,select】的预设值,array(名字=>数据); 2,字符串:【text】默认数据", 
  406.  
  407.         )) 
  408.  
  409.      */ 
  410.  
  411.     public static function configName() 
  412.  
  413.     { 
  414.  
  415.         return array(); 
  416.  
  417.     } 
  418.  
  419.     /** 
  420.  
  421.      * @brief 插件安装 
  422.  
  423.      * @return boolean 
  424.  
  425.      */ 
  426.  
  427.     public static function install() 
  428.  
  429.     { 
  430.  
  431.         return true; 
  432.  
  433.     } 
  434.  
  435.     /** 
  436.  
  437.      * @brief 插件卸载 
  438.  
  439.      * @return boolean 
  440.  
  441.      */ 
  442.  
  443.     public static function uninstall() 
  444.  
  445.     { 
  446.  
  447.         return true; 
  448.  
  449.     } 
  450.  
  451.     /** 
  452.  
  453.      * @brief 插件名字 
  454.  
  455.      * @return string 
  456.  
  457.      */ 
  458.  
  459.     public static function name() 
  460.  
  461.     { 
  462.  
  463.         return "插件名称"; 
  464.  
  465.     } 
  466.  
  467.     /** 
  468.  
  469.      * @brief 插件功能描述 
  470.  
  471.      * @return string 
  472.  
  473.      */ 
  474.  
  475.     public static function description() 
  476.  
  477.     { 
  478.  
  479.         return "插件描述"; 
  480.  
  481.     } 
  482.  
  483.     /** 
  484.  
  485.      * @brief 插件使用说明 
  486.  
  487.      * @return string 
  488.  
  489.      */ 
  490.  
  491.     public static function explain() 
  492.  
  493.     { 
  494.  
  495.         return ""; 
  496.  
  497.     } 
  498.  
  499.     /** 
  500.  
  501.      * @brief 获取DB中录入的配置参数 
  502.  
  503.      * @return array 
  504.  
  505.      */ 
  506.  
  507.     public function config() 
  508.  
  509.     { 
  510.  
  511.         $className= get_class($this); 
  512.  
  513.         $pluginDB = new IModel('plugin'); 
  514.  
  515.         $dataRow  = $pluginDB->getObj('class_name = "'.$className.'"'); 
  516.  
  517.         if($dataRow && $dataRow['config_param']) 
  518.  
  519.         { 
  520.  
  521.             return JSON::decode($dataRow['config_param']); 
  522.  
  523.         } 
  524.  
  525.         return array(); 
  526.  
  527.     } 
  528.  
  529.     /** 
  530.  
  531.      * @brief 返回错误信息 
  532.  
  533.      * @return array 
  534.  
  535.      */ 
  536.  
  537.     public function getError() 
  538.  
  539.     { 
  540.  
  541.         return $this->error ? join("\r\n",$this->error) : ""; 
  542.  
  543.     } 
  544.  
  545.     /** 
  546.  
  547.      * @brief 写入错误信息 
  548.  
  549.      * @return array 
  550.  
  551.      */ 
  552.  
  553.     public function setError($error) 
  554.  
  555.     { 
  556.  
  557.         $this->error[] = $error; 
  558.  
  559.     } 
  560.  
  561.     /** 
  562.  
  563.      * @brief 插件视图渲染有布局 
  564.  
  565.      * @param string $view 视图名字 
  566.  
  567.      * @param array  $data 视图里面的数据 
  568.  
  569.      */ 
  570.  
  571.     public function redirect($view,$data = array()) 
  572.  
  573.     { 
  574.  
  575.         if($data === true) 
  576.  
  577.         { 
  578.  
  579.             $this->controller()->redirect($view); 
  580.  
  581.         } 
  582.  
  583.         else 
  584.  
  585.         { 
  586.  
  587.             $__className      = get_class($this); 
  588.  
  589.             $__pluginViewPath = plugin::path().$__className."/".$view; 
  590.  
  591.             $result = self::controller()->render($__pluginViewPath,$data); 
  592.  
  593.             if($result === false) 
  594.  
  595.             { 
  596.  
  597.                 IError::show($__className."/".$view."插件视图不存在"); 
  598.  
  599.             } 
  600.  
  601.         } 
  602.  
  603.     } 
  604.  
  605.     /** 
  606.  
  607.      * @brief 插件视图渲染去掉布局 
  608.  
  609.      * @param string $view 视图名字 
  610.  
  611.      * @param array  $data 视图里面的数据 
  612.  
  613.      */ 
  614.  
  615.     public function view($view,$data = array()) 
  616.  
  617.     { 
  618.  
  619.         self::controller()->layout = ""; 
  620.  
  621.         $this->redirect($view,$data); 
  622.  
  623.     } 
  624.  
  625.     /** 
  626.  
  627.      * @brief 插件物理目录 
  628.  
  629.      * @param string 插件路径地址 
  630.  
  631.      */ 
  632.  
  633.     public function path() 
  634.  
  635.     { 
  636.  
  637.         return plugin::path().get_class($this)."/"; 
  638.  
  639.     } 
  640.  
  641.     /** 
  642.  
  643.      * @brief 插件WEB目录 
  644.  
  645.      * @param string 插件路径地址 
  646.  
  647.      */ 
  648.  
  649.     public function webPath() 
  650.  
  651.     { 
  652.  
  653.         return plugin::webPath().get_class($this)."/"; 
  654.  
  655.     } 
  656.  
  657. }

Tags: PHP钩子机制

分享到: