php的c 钩子函数数,有大神知道吗

php技术(88)
钩子函数定义:
钩子函数可以截获并处理其他应用程序的消息。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
钩子的种类很多,每种钩子可以截获并处理相应的消息,如键盘钩子可以截获键盘消息,外壳钩子可以截取、启动和关闭应用程序的消息等
PHP 插件机制及功能实现解决方案
时间:来源:经典论坛 作者:fimmuhu 点击: 541 次
&&&&摘要:&&PHP 插件机制及功能实现解决方案,php 插件机制,php plugin ,php hook 接口,php 钩子函数,php 钩子机制,php hook 机制,包括 PHP 插件的动态监听和加载、插件的动态触发及其 hooks 实现。 插件机制 亦即Plug-in,是
PHP 插件机制及功能实现解决方案,php 插件机制,php plugin ,php hook 接口,php 钩子函数,php 钩子机制,php hook 机制,包括 PHP 插件的动态监听和加载、插件的动态触发及其 hooks 实现。
亦即Plug-in,是指一类特定的功能模块(通常由第三方开发者实现),它的特点是:当你需要它的时候激活它,不需要它的时候禁用/删除它;且无论是激活还是禁用都不影响系统核心模块的运行,也就是说插件是一种非侵入式的模块化设计,实现了核心程序与插件程序的松散耦合。
一个典型的例子就是Wordpress中众多的第三方插件,比如Akimet插件用于对用户的评论进行Spam过滤。
一个健壮的插件机制,我认为必须具备以下特点:
插件的动态监听和加载(Lookup)插件的动态触发
以上两点的实现均不影响核心程序的运行
要在程序中实现插件,我们首先应该想到的就是定义不同的钩子(Hooks);“钩子”是一个很形象的逻辑概念,你可以认为它是系统预留的插件触发条件。
它的逻辑原理如下:当系统执行到某个钩子时,会判断这个钩子的条件是否满足;如果满足,会转而先去调用钩子所制定的功能,然后返回继续执行余下的程序;如果不满足,跳过即可。这有点像汇编中的“中断保护”逻辑。
某些钩子可能是系统事先就设计好的,比如之前我举的关于评论Spam过滤的钩子,通常它已经由核心系统开发人员设计进了评论的处理逻辑中;另外一类钩子则可能是由用户自行定制的(由第三方开发人员制定),通常存在于表现层,比如一个普通的PHP表单显示页面中。
看懂下面的代码,理解以上的原理是必不可少的。
下面进行PHP中插件机制的核心实现,整个机制核心分为三大块:
一个插件经理类:这是核心之核心。它是一个应用程序全局Global对象。它主要有三个职责:
负责监听已经注册了的所有插件,并实例化这些插件对象。
负责注册所有插件。
当钩子条件满足时,触发对应的对象方法。
插件的功能实现:这大多由第三方开发人员完成,但需要遵循一定的规则,这个规则是插件机制所规定的,因插件机制的不同而不同,下面的显示代码你会看到这个规则。
插件的触发:也就是钩子的触发条件。具体来说这是一小段代码,放置在你需要插件实现的地方,用于触发这个钩子。
PHP 插件机制及功能实现解决方案(2)
时间:来源:经典论坛 作者:fimmuhu 点击: 541 次
&&&&摘要:&&插件管理类 PluginManager 以下为引用内容: ? /** * STBLOG PluginManager Class * 插件机制的实现核心类 * @package STBLOG * @subpackage Libraries * @category Libr
&&&&& 插件管理类 PluginManager
以下为引用内容:& &?
* STBLOG PluginManager Class&
* 插件机制的实现核心类&
* @package&&&&&&& STBLOG&
* @subpackage&&& Libraries&
* @category&&& Libraries&
* @author&&&&&&& Saturn&
*&@link /&
class PluginManager&
&&&& * 监听已注册的插件&
&&&& * @access private&
&&&& * @var array&
&&& private $_listeners = array();&
&&&& * 构造函数&
&&&& * @access public&
&&&& * @return void&
&&& public function __construct()&
&&&&&&& #这里$plugin数组包含我们获取已经由用户激活的插件信息&
&&&& #为演示方便,我们假定$plugin中至少包含&
&&&& #$plugin = array(&
&&&&&&& #&&& 'name' =& '插件名称',&
&&&&&&& #&&& 'directory'=&'插件安装目录'&
&&&&&&& #);&
&&&&&&& $plugins = get_active_plugins();#这个函数请自行实现&
&&&&&&& if($plugins)&
&&&&&&& {&
&&&&&&&&&&& foreach($plugins as $plugin)&
&&&&&&&&&&& {//假定每个插件文件夹中包含一个actions.php文件,它是插件的具体实现&
&&&&&&&&&&&&&&& if (@file_exists(STPATH .'plugins/'.$plugin['directory'].'/actions.php'))&
&&&&&&&&&&&&&&& {&
&&&&&&&&&&&&&&&&&&& include_once(STPATH .'plugins/'.$plugin['directory'].'/actions.php');&
&&&&&&&&&&&&&&&&&&& $class = $plugin['name'].'_actions';&
&&&&&&&&&&&&&&&&&&& if (class_exists($class))&&
&&&&&&&&&&&&&&&&&&& {&
&&&&&&&&&&&&&&&&&&&&&&& //初始化所有插件&
&&&&&&&&&&&&&&&&&&&&&&& new $class($this);&
&&&&&&&&&&&&&&&&&&& }&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&& }&
&&&&&&& }&
&&&&&&& #此处做些日志记录方面的东西&
&&&& * 注册需要监听的插件方法(钩子)&
&&&& * @param string $hook&
&&&& * @param object $reference&
&&&& * @param string $method&
&&& function register($hook, &$reference, $method)&
&&&&&&& //获取插件要实现的方法&
&&&&&&& $key = get_class($reference).'-&'.$&
&&&&&&& //将插件的引用连同方法push进监听数组中&
&&&&&&& $this-&_listeners[$hook][$key] = array(&$reference, $method);&
&&&&&&& #此处做些日志记录方面的东西&
&&&& * 触发一个钩子&
&&&& * @param string $hook 钩子的名称&
&&&& * @param mixed $data 钩子的入参&
&&&& *&@return mixed&
&&& function trigger($hook, $data='')&
&&&&&&& $result = '';&
&&&&&&& //查看要实现的钩子,是否在监听数组之中&
&&&&&&& if (isset($this-&_listeners[$hook]) && is_array($this-&_listeners[$hook]) && count($this-&_listeners[$hook]) & 0)&
&&&&&&& {&
&&&&&&&&&&& // 循环调用开始&
&&&&&&&&&&& foreach ($this-&_listeners[$hook] as $listener)&
&&&&&&&&&&& {&
&&&&&&&&&&&&&&& // 取出插件对象的引用和方法&
&&&&&&&&&&&&&&& $class =& $listener[0];&
&&&&&&&&&&&&&&& $method = $listener[1];&
&&&&&&&&&&&&&&& if(method_exists($class,$method))&
&&&&&&&&&&&&&&& {&
&&&&&&&&&&&&&&&&&&& // 动态调用插件的方法&
&&&&&&&&&&&&&&&&&&& $result .= $class-&$method($data);&
&&&&&&&&&&&&&&& }&
&&&&&&&&&&& }&
&&&&&&& }&
&&&&&&& #此处做些日志记录方面的东西&
&&&&&&& return $&
PHP 插件机制及功能实现解决方案(3)
时间:来源:经典论坛 作者:fimmuhu 点击: 541 次
&&&&摘要:&&以上代码加上注释不超过100行,就完成了整个插件机制的核心。需要再次说明的是,你必须将它设置成全局类,在所有需要用到插件的地方,优先加载。用#注释的地方是你需要自行完成的部分,包括插件的获取和日志记录等等。 下面是一个简单插件的实现。 以下为引用内容: ? /** *
&&&&& 以上代码加上注释不超过100行,就完成了整个插件机制的核心。需要再次说明的是,你必须将它设置成全局类,在所有需要用到插件的地方,优先加载。用#注释的地方是你需要自行完成的部分,包括插件的获取和日志记录等等。
下面是一个简单插件的实现。
以下为引用内容:& &?
* 这是一个Hello World简单插件的实现&
* @package&&&&&&& DEMO&
* @subpackage&&& DEMO&
* @category&&& Plugins&
* @author&&&&&&& Saturn&
*需要注意的几个默认规则:&
*&&& 1. 本插件类的文件名必须是action&
*&&& 2. 插件类的名称必须是{插件名_actions}&
class DEMO_actions&
//解析函数的参数是pluginManager的引用&
function __construct(&$pluginManager)&
//注册这个插件&
//第一个参数是钩子的名称&
//第二个参数是pluginManager的引用&
//第三个是插件所执行的方法&
$pluginManager-&register('demo', $this, 'say_hello');&
function say_hello()&
echo 'Hello World';&
这是一个简单的Hello World插件,用于输出一句话。在实际情况中,say_hello可能包括对数据库的操作,或者是其他一些特定的逻辑,比如调用Akimet API。
插件实现的默认规则由核心系统开发者自行确定。比如本例的一些默认规则我在注释中已经写的很清楚,在此不在赘述。需要特别注意的是钩子名称不要重复。
最后一步,就是定义钩子的触发,你将钩子放在哪里,上面这个插件的方法就会在哪里出发。比如将say_hello放到博客首页Index.php,那么你在index.php中的某个位置写下:
以下为引用内容:& $pluginManager-&trigger('demo','');
第一个参数表示钩子的名字,在本例中它是第二个参数是插件对应方法的入口参数,由于这个例子中没有输入参数,所以为空。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:83438次
积分:1421
积分:1421
排名:千里之外
原创:45篇
转载:105篇
(3)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(1)(4)(2)(8)(11)(3)(4)(3)(10)(8)(8)(19)(6)(7)(6)(7)(11)(3)(14)(1)PHP编程的钩子实现示例讲解和解释他们的作用,写了一个样板钩子实现
钩子是编程里一个常见概念,非常的重要。它使得系统变得非常容易拓展,(而不用理解其内部的实现机理,这样可以减少很多工作量)。只要有一个钩子样本,能很容易仿照第一个钩子快速的编写第二个钩子,这里对钩子进行一个简单的理解小结。&&&& 下面一个最简单的代码例子:&&& &?php& class&& Test&& {public& static& function&& example() {&&& $arr = array(1,2,3,4,5,6);&& echo& "I am a Hook test&br /&";&& echo&&& "hello&br /&";& echo&& "&pre&";&& print_r($arr);&& &&& echo&&& "&/pre&";}}Test::example();?&一个测试类里面,写了一个example方法。本来这个example的方法非常简单的,就是输出hello。但是在输入的时候,我们还有其他的事情要做(这里我假定了在输入hello之前有一个字符串要输出,在结尾有个数组要输出)。我们现在有俩种写法:第一:我们可以直接在方法里面实现我们需要的功能但是会有个问题,就是我们每次更动系统,都需要去更改系统的内核部分(我们假定test是系统的内核,当内核代码非常多的时候,开发的时候不适宜直接改动内核部分)这样会需要我们每次改动都要跳到类test内部去改动,这样的开发成本会非常大,而且代码全部在一起非常的不好维护。第二:我们封装一个exec的方法& function& exec($parms) {&&& if(is_array($parms)) {&& &&& &echo&& "&pre&";&&&&&& print_r($parms);&& &&& echo&&& "&/pre&";&& &}& else& {&&&&&&& echo&&&&&&& $&& &}&}&这样我们实现的时候,方便了很多,下面的方法简化成了&& class&& Test&& {public& static& function&& example() {&& exc("I am a Hook test&br /&");&& echo&&& "hello&br /&";&& $arr = array(1,2,3,4,5,6);& exec($arr);}}&但是现在仍然有个问题,我们改动的时候,仍然要去系统内部改动(我们最终需要的目标是不改动内核的情况下,可以直接改动,如果是简单的数组和字符串,是可以进行配置的,但是如果是逻辑的时候,配置行不通)。我们想的是写一个类(通过这个类,向系统发送信息的时候,系统可以直接调用我们的类,而且我们的类只要遵循一定的规则设计,直接和原系统是相容的)。做了改进设计出如下钩子格式:
&&class&&&Test&&&{
public&&static&&function&&&example()&{
&&&Hook::exec("string");
&&&echo&&&&"hello&br&/&";
&&&Hook::exec("arr");
class&&Hook&&{
&static&&public&function&&exec($type,$model='&')&{
&&&&&&if($model='&')&{
&&&&&&&&&$m&=&new&hello();
&&&&&&}&&else&{
&&&&&&&$m&=&new&$model();
&&&&if($type=='string')&{&&&&&
&&&&&&&&$m-&string();
&&&&}&&elseif($type=='arr')&{
&&&&&&&&$m-&arr();&&&&
//我们只要改动一个外部的hello类&就可以实现对系统内部的控制了。
class&&&hello&&{
&public&&function&&string()&{
&&&&&$str="I&am&a&Hook&test&br&/&";
&&&&echo&&&"$str&&br&/&";
public&&function&arr()&{
&&&&$arr&=array(1,2,3,4,5,6);
&&&echo&&&"&pre&";
&&&print_r($arr);
&&&echo&&&&"&/pre&";
Test::example();
从上面可以看出,组成一个单独的类,系统内部的实现固定了后。外部可以写各种类,进行钩子的实现,现在写了一个hello类。假如增加一个拓展world类同样可以仅仅改动Hook,而不用去改动Test系统内部,只要我们定义一个抽象类abstract& class& lan {& abstract& function& string() ;& abstract function arr();}然后让所有的扩展类,比如hello或者另外写个类world继承这个抽象类,就可以直接写个扩展。
& 开源中国(OSChina.NET) |
开源中国社区(OSChina.net)是工信部
指定的官方社区7个必须知道的实用PHP函数和功能_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
7个必须知道的实用PHP函数和功能
上传于||文档简介
&&1​、​任​意​参​数​数​目​的​函​数​
​
、​使​用​ ​G​l​o​b​(​)​ ​查​找​文​件​
​
、​内​存​使​用​信​息​
​
、​C​P​U​ ​使​用​信​息​
​
、​魔​术​常​量​
​
、​生​成​唯​一​标​识​符​
​
、​序​列​化
大小:10.55KB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢菜鸟,小白 !!求大神!!求解决!!PHP 调用函数.._百度知道CI框架可以实现在不修改系统核心文件的基础上来改变或增加系统的核心运行功能,那就是Hook,看看CI有哪些钩子:
pre_system系统执行的早期调用.仅仅在benchmark 和 hooks&类&加载完毕的时候. 没有执行路由或者其它的过程.
pre_controller在调用你的任何控制器之前调用.此时所用的基础类,路由选择和安全性检查都已完成.
post_controller_constructor在你的控制器实例化之后,任何方法调用之前调用.
post_controller在你的控制器完全运行之后调用.
display_override覆盖_display()函数, 用来在系统执行末尾向web浏览器发送最终页面.这允许你用自己的方法来显示.注意,你需要通过 $this-&CI =& get_instance() 引用 CI 超级对象,然后这样的最终数据可以通过调用 $this-&CI-&output-&get_output() 来获得。
cache_override可以让你调用自己的函数来取代output类中的_display_cache() 函数.这可以让你使用自己的缓存显示方法
post_system在最终着色页面发送到浏览器之后,浏览器接收完最终数据的系统执行末尾调用 &
&钩子的配置很简单:$hook['pre_controller'] = array(
=& 'TestHook', //调用的类名
'function' =& 'test', //调用的函数名
'filename' =& 'TestHook.php', //文件名
'filepath' =& 'hooks', //文件或脚本路径,以application为基准
=& 'array()'//传递给脚本参数,可选
用二维数组还可以对同一个挂载点多次引用!/**
* 钩子嘛,就是在不修改系统核心文件的基础上来改变或增加系统的核心运行功能
class CI_Hooks {
* 检测hook是否开启
var $enabled
* config/hooks.php中的hooks配置信息
var $hooks
= array();
//防止死循环,因为钩子程序里面可能还还有钩子
var $in_progress = FALSE;
//构造函数
function __construct()
$this-&_initialize();
log_message('debug', "Hooks Class Initialized");
* 初始化,获取hooks配合
function _initialize()
$CFG =& load_class('Config', 'core');
// 检测配置是否开启钩子
if ($CFG-&item('enable_hooks') == FALSE)
// 检测是否配置钩子
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))
$this-&hooks =& $
$this-&enabled = TRUE;
// --------------------------------------------------------------------
* 运行钩子程序,外部就是这样调用:
$EXT =& load_class('Hooks', 'core');
$EXT-&_call_hook('pre_system');
function _call_hook($which = '')
if ( ! $this-&enabled OR ! isset($this-&hooks[$which]))
return FALSE;
//CI支持多次钩子,那么就是二维数组
if (isset($this-&hooks[$which][0]) AND is_array($this-&hooks[$which][0]))
foreach ($this-&hooks[$which] as $val)
$this-&_run_hook($val);
//一个钩子直接运行钩子
$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;
//防止死循环,因为钩子程序里面可能还还有钩子
if ($this-&in_progress == TRUE)
//设置路径
//下面可以filepathfilepath就以那个文件夹(application)为基准,application/hooks下, 你可以把hooks 作为你的filepath
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
// -----------------------------------
$function = FALSE;
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;
//不用多说了吧
$this-&in_progress = TRUE;
//获取钩子配置信息成功后,运行钩子程序
if ($class !== FALSE)
if ( ! class_exists($class))
require($filepath);
$HOOK = new $
$HOOK-&$function($params);
if ( ! function_exists($function))
require($filepath);
$function($params);
// //执行相应程序完毕后,重新把当前hook的状态改为非运行中,以让它可以再次被触发。
$this-&in_progress = FALSE;
return TRUE;
关注微信公众平台

我要回帖

更多关于 c 钩子函数 的文章

 

随机推荐