php中钩子(hook)的原理与简单应用demo示例

本文实例讲述了php中钩子(hook)的原理与简单应用。分享给大家供大家参考,具体如下:

我们先来回顾下原本的开发流程;

  产品汪搞出了一堆需求;

  当用户注册成功后需要发送短信、发送邮件等等;

  然后聪明机智勇敢的程序猿们就一扑而上;

  把这些需求转换成代码扔在 用户注册成功 和 跳转到首页 之间;

  没有什么能够阻挡;充满创造力的猿们;

<?php
class Test{
  public function index(){
    // 用户注册成功
      /*
       此处是一堆发送短信的代码
      */
      /*
       此处是一堆发送邮件的代码
      */
      /*
       此处是一堆其他功能的代码
      */
    // 前往网站首页
  }
}
$test=new Test();
$test->index();

  如果每个功能都由不同的猿完成的话;

  首先面临的就是代码会很杂乱;配合起来会比较麻烦;

  那封装成函数吧;一方面会规范整洁写;另外方便重复调用;

  没有什么能够阻挡;充满创造力的猿们;

<?php
class Test{
  public function index(){
    // 用户注册成功
    // 发送短信
    sendSms($phone);
    // 发送邮件
    sendSms($email);
    // 其他操作...
    // 前往网站首页
  }
}
/**
 * 发送短信通知
 * @param integer $phone 手机号
 */
function sendSMS($phone){
  // 此处是发送短信的代码
}
/**
 * 发送邮件通知
 * @param string $email 邮箱地址
 */
function sendEmail($email){
  // 此处是发送邮件的代码
}

这时候运营喵表示;

如果能在后台点点按钮就能设置是发邮件还是发短信;那想必是极好的;

没有什么能够阻挡;充满创造力的猿们;

<?php
class Test{
  public function index(){
    // 用户注册成功
    if ('如果设置了发送短信') {
      // 发送短信
      sendSms($phone);
    }
    if ('如果设置了发送邮件') {
      // 发送邮件
      sendSms($email);
    }
    // 其他操作...
    // 前往网站首页
  }
}
/**
 * 发送短信通知
 * @param integer $phone 手机号
 */
function sendSMS($phone){
  // 此处是发送短信的代码
}
/**
 * 发送邮件通知
 * @param string $email 邮箱地址
 */
function sendEmail($email){
  // 此处是发送邮件的代码
}

  在一个封闭企业环境下这样搞是没有问题的;

  然鹅;我们还有一位开放无私的猿领导要把程序开源出去造福其他猿类;

  希望有更多的猿类来参与这个项目;共同开发功能;

  如果大家都去改动这套程序;把自己的代码扔在 用户注册成功 和 跳转到首页 之间;

  这显然是不靠谱的;想想都混乱的一塌糊涂;

  那可不可以大家把自己写的代码放到某个目录下;

  然后系统自动的根据配置项把这些代码加载到 用户注册成功 和 跳转到首页 之间呢?

  好先定义如下目录

├─plugin // 插件目录
│  ├─plugin1 // 插件1
│  │  ├─config.php // 插件1的配置项
│  │  ├─index.php // 插件1的程序处理内容
│  ├─plugin2
│  │  ├─config.php
│  │  ├─index.php
│  ├─plugin3
│  │  ├─config.php
│  │  ├─index.php
│  ├─...
├─index.php // 业务逻辑

业务逻辑的代码:

<?php
class Test{
  public function index(){
    // 用户注册成功
    // 获取全部插件
    $pluginList=scandir('./plugin/');
    // 循环插件 // 排除. ..
    foreach ($pluginList as $k => $v) {
      if ($v=='.' || $v=='..') {
        unset($pluginList[$k]);
      }
    }
    echo "简易后台管理<hr>";
    // 插件管理
    foreach ($pluginList as $k => $v) {
      // 获取配置项
      $config=include './plugin/'.$v.'/config.php';
      $word=$config['status']==1 ? '点击关闭' : '点击开启';
      echo $config['title'].'<a href="./index.php?change='.$v.'" rel="external nofollow" >'.$word.'</a><br />';
    }
    echo '<hr>';
    // 输出插件内容
    foreach ($pluginList as $k => $v) {
      // 获取配置项
      $config=include './plugin/'.$v.'/config.php';
      if ($config['status']==1) {
        include './plugin/'.$v.'/index.php';
        // 运行插件
        Hook::run($v);
      }
    }
    // 前往网站首页
  }
}
// 插件类
class Hook{
  // 注册添加插件
  public static function add($name,$func){
    $GLOBALS['hookList'][$name][]=$func;
  }
  // 执行插件
  public static function run($name,$params=null){
    foreach ($GLOBALS['hookList'][$name] as $k => $v) {
      call_user_func($v,$params);
    }
  }
}
// 更改插件状态
if (isset($_GET['change'])) {
  // 获取到配置项
  $config=include './plugin/plugin'.substr($_GET['change'],-1).'/config.php';
  // 如果是开启 那就关闭 如果是关闭 则开启
  $config['status']=$config['status']==1 ? 0: 1;
  // 将更改后的配置项写入到文件中
  $str="<?php \\r\\n return ".var_export($config,true).';';
  file_put_contents('./plugin/'.$_GET['change'].'/config.php', $str);
  header('Location:./');
}
$test=new Test();
$test->index();

插件配置项代码:

<?php
 return array (
 'status' => 1, // 定义状态 1表示开启 0表示关闭
 'title' => '发送短信', // 插件的名称
);

插件的内容:

  没错;这就是插件的思想;

  当然这只是一个超级简单的示例;

  完整的插件机制要包括插件的类型、数据库、审核等等;

  如果使用过wordpress或者国内的discuz;

  你就会发现一个好的程序并不仅仅是自身多么优秀;

  而且重要的就是设计的扩展性有多好;能多方便的让大家去扩展它的功能;

  想对插件深入研究的话;建议去阅读wordpress、discuz的源代码;

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php面向对象程序设计入门教程》、《PHP数组(Array)操作技巧大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

(0)

相关推荐

  • PHP对象Object的概念 介绍

    例如,员工管理应用程序可能包括一个EmPloyee 类.然后可以用这个类来创建和维护特定实例,比如Gonn和Sally. 根据预定义的类创建对象常称为类的实例化(class instantiation). 对象使用new关键字创建,如下: 复制代码 代码如下: $employee = new Employee(); 创建对象之后,这个刚实例化的对象就具有了类中定义的所有性质和行为. 如何实例化对象 面向对象程序的单位就是对象,但对象又是通过类的实例化出来的,既然我们类会声明了,下一步就是实例化对

  • PHP 面向对象 final类与final方法

    final---用于类.方法前. final类---不可被继承. final方法---不可被覆盖. final类不能被继承. 如果我们不希望一个类被继承,我们使用final来修饰这个类.这个类将无法被继承.比如我们设定的Math类,涉及了我们要做的数学计算方法,这些算法也没有必要修改,也没有必要被继承,我们把它设置成final类型. 复制代码 代码如下: <? //声明一个final类Math final class Math{ public static $pi = 3.14; public

  • PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)

    面象对向的三大特点:封装性.继承性.多态性 首先简单理解一下抽象:我们在前面定义一个类的时候,实际上就是把一类事物共有的属性和行为提取出来,形成一个物理模型(模版),这种研究问题的方法称为抽象一.封装性 封装就是把抽取出来的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有被授权的操作(方法)才能对数据进行操作. php提供了三种访问控制修饰符 public 表示全局,本类内部,类外部,子类都可以访问 protected 表示受保护的,只有本类或子类可以访问 private 表示

  • 浅谈PHP中如何实现Hook机制

    对"钩子"这个概念其实不熟悉,最近看到一个php框架中用到这种机制来扩展项目,所以大概来了解下. 所谓Hook机制,是从Windows编程中流行开的一种技术.其主要思想是提前在可能增加功能的地方埋好(预设)一个钩子,这个钩子并没有实际的意义,当我们需要重新修改或者增加这个地方的逻辑的时候,把扩展的类或者方法挂载到这个点即可. hook插件机制的基本思想: 在项目代码中,你认为要扩展(暂时不扩展)的地方放置一个钩子函数,等需要扩展的时候,把需要实现的类和函数挂载到这个钩子上,就可以实现扩

  • php面向对象中static静态属性和静态方法的调用

    本文实例讲述了php中static静态属性和静态方法的调用.分享给大家供大家参考.具体如下: 这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内存中,只有一个位置(而非静态属性,有多少实例化对象,就有多少个属性). 实例: <?php header("content-type:text/html;charset=utf-8"); c

  • CI框架源码解读之利用Hook.php文件完成功能扩展的方法

    本文实例讲述了CI框架源码解读之利用Hook.php文件完成功能扩展的方法.分享给大家供大家参考,具体如下: 看了hook.php的源码,就知道CI使用hook来进行扩展的原理了. hook的基本知识 http://codeigniter.org.cn/user_guide/general/hooks.html CI中hook的使用经历了一个:开启hook,定义hook,调用hook,执行hook的过程. 手册中已经告知了开启.定义.调用的方法.那么hook的实现原理是啥呢. <?php if

  • PHP钩子与简单分发方式实例分析

    本文实例讲述了PHP钩子与简单分发方式.分享给大家供大家参考,具体如下: //简单的钩子实现例子 class tool{ public static function main($class, $fun, $data = ''){ //前置公共操作 $con = new $class; $con->$fun($data); //后置公共操作 } } class a{ function b($data){ echo '我是方法b'; } } class c{ function d($data){

  • thinkPHP中钩子的使用方法实例分析

    本文实例讲述了thinkPHP中钩子的使用方法.分享给大家供大家参考,具体如下: 前面介绍过thinkPHP中钩子的两种配置调用方法,这里来进一步分析一下钩子的使用方法. 1 创建钩子行为: 我们自己定义的标签位可以直接放在Think\Behaviors中,也可以放在应用目录中,比如说Home模块下,新建一个Behaviors的文件夹,在文件夹内新建 标签名+Behavior.class.PHP 注:需要带Behavior的原因,见代码: static public function exec(

  • thinkPHP中钩子的两种配置调用方法详解

    本文实例讲述了thinkPHP中钩子的两种配置调用方法.分享给大家供大家参考,具体如下: thinkphp的钩子行为类是一个比较难以理解的问题,网上有很多写thinkphp钩子类的文章,我也是根据网上的文章来设置thinkphp的钩子行为的,但根据这些网上的文章,我在设置的过程中,尝试了十几次都没有成功,不过,我还是没有放弃,最后还是在一边调节细节,一边试验的过程中实现了钩子行为的设置.下面是我个人的设置经验,在这里跟大家分享一下. 个人做了两种设置,都试验成功了,一个简单点,在thinkphp

  • thinkPHP基于反射实现钩子的方法分析

    本文实例讲述了thinkPHP基于反射实现钩子的方法.分享给大家供大家参考,具体如下: ThinkPHP框架的控制器模块是如何实现 前控制器.后控制器,及如何执行带参数的方法? PHP系统自带的 ReflectionClass.ReflectionMethod 类,可以反射用户自定义类的中属性,方法的权限和参数等信息,通过这些信息可以准确的控制方法的执行. ReflectionClass: 主要用的方法: hasMethod(string)  是否存在某个方法 getMethod(string)

  • PHP钩子实现方法解析

    本文实例讲述了PHP钩子实现方法.分享给大家供大家参考,具体如下: PHP编程的钩子实现,示例讲解和解释它们的作用,写了一个样板的钩子实现 钩子是编程里一个常见的概念,非常的重要.它使得系统变得非常容易拓展(而不用理解其内部的实现机理,这样可以减少很多工作量).只要有一个钩子样本,能很容易仿照第一个钩子快速的编写第二个钩子,这里对钩子进行一个简单的理解. 下面是一个最简单的代码例子: <?php class Test { public static function example() { $a

  • php中的钩子理解及应用实例分析

    本文实例讲述了php中的钩子理解及应用.分享给大家供大家参考,具体如下: 钩子的解释 钩子定义 钩子是编程里一个常见概念,非常的重要.它使得系统变得非常容易拓展,(而不用理解其内部的实现机理,这样可以减少很多工作量). 可以理解为当一个玻璃球从空中落下,即将砸到人的时候,有个事件会提前发生.例如告诉那个被砸的人,球已经在下落过程中, 告诉就是一个事件,一个钩子,我们可以针对不同的人做出不同的相应,如果是男人我们告诉他这个球砸到人不疼,如果是女人则告诉她很疼; 钩子作用 钩子函数可以截获并处理其他

随机推荐