zoukankan      html  css  js  c++  java
  • thinkphp 面向切面编程行为拓展

    thinkphp的CBD模式

    核心保留了最关键的部分,并在重要位置设置了标签用以标记,其他功能都采用行为扩展和驱动的方式组合,开发人员可以根据自己的需要,对某个标签位置进行行为扩展或者替换,就可以方便的定制框架底层,也可以在应用层添加自己的标签位置和添加应用行为。而标签位置类似于AOP概念中的“切面”,行为都是围绕这个“切面”来进行编程。

    CBD主要由Core(核心)、Behavior(行为)以及Drivers(驱动)三部分组成。在ThinkPHP中,Core是指诸如路由配置,基础模型类、Behavior中使用到的行为标签配置这些最重要的核心函数库、类库以及配置文件。Behavior是框架中比较关键的一种机制,在thinkphp中是实现了“钩子”的功能,恰当的使用可以有效降低业务逻辑之间的耦合度,下面会详细。而Drivers是基于功能的,为框架的功能拓展提供驱动,比如数据库驱动,缓存驱动。

    Behavior(行为)

    AOP

    这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程 http://hejiajunsh.iteye.com/blog/1776569

    AOP(Aspect Oriented Program)与传统的面向对象编程并不冲突,反而可以对OOP编程作出补充,增加某些代码的重用性,降低不同业务逻辑之间的耦合度,使团队开发更为容易且可以有效降低开发周期。

    钩子函数

    钩子是编程里一个常见概念,非常的重要。它使得系统变得非常容易拓展,(而不用理解其内部的实现机理,这样可以减少很多工作量)。
    可以理解为当一个玻璃球从空中落下,即将砸到人的时候,有个事件会提前发生.例如告诉那个被砸的人,球已经在下落过程中,
    告诉就是一个事件,一个钩子,我们可以针对不同的人做出不同的相应,如果是男人我们告诉他这个球砸到人不疼,如果是女人则告诉她很疼;

    钩子函数可以截获并处理其他应用程序的消息。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。

    设置钩子的过程其实就是设置事件驱动的过程,简单来讲就是定义钩子函数,注册事件,监听(挂载),满足触发条件并触发钩子函数。

    行为拓展

    行为(Behavior)是ThinkPHP扩展机制中比较关键的一项扩展,行为既可以独立调用,也可以绑定到某个标签(位)中进行侦听。这里的行为指的是一个比较抽象的概念,你可以想象成在应用执行过程中的一个动作或者处理,在框架的执行流程中,各个位置都可以有行为产生,例如路由检测是一个行为,静态缓存是一个行为,用户权限检测也是行为,大到业务逻辑,小到浏览器检测、多语言检测等等都可以当做是一个行为,甚至说你希望给你的网站用户的第一次访问弹出Hello,world!这些都可以看成是一种行为,行为的存在让你无需改动框架和应用,而在外围通过扩展或者配置来改变或者增加一些功能。

    换言之,TP框架中Behavior实现了AOP(面向切面)编程,即绑定标签,利用Hook函数设置触发点。

    tp提供了诸如'app_init'(应用初始化标签位),'path_info'(path_info检测标签位),'app_began'(应用开始标签位),'app_end'(应用结束标签位)等内置标签位。

    行为拓展添加过程

    • 创建Behavior类

    可以直接放在Think\Behaviors中,也可以放在应用目录中(Application\Common\Behavior),新建文件,命名格式为 标签名+Behavior.class.PHP 。要注意类中必须含有run方法,默认run方法为入口方法。

    代码内容

    namespace Common\Behavior;
    
    use Think\Behavior;
    
    class TolldetectBehavior extends Behavior
    {
        //方法名必须为run,作为入口文件
        public function run(&$param){
            echo "Hello ";
        }
    }
    
    • 注册标签(挂载)
      ThinkPHP中的标签注册方法有两种,一种是手动注册,一种是自动注册。

    下面为手动注册方法add()的源码

    /**
         * 动态添加插件到某个标签
         * @param string $tag 标签名称
         * @param mixed $name 插件名称
         * @return void
         */
        static public function add($tag,$name) {
            if(!isset(self::$tags[$tag])){
                self::$tags[$tag]   =   array();
            }
            if(is_array($name)){
                self::$tags[$tag]   =   array_merge(self::$tags[$tag],$name);
            }else{
                self::$tags[$tag][] =   $name;
            }
        }
    

    我们在调用时用Hook::add($tags,$name)就可以绑定。注意tags为要绑定的标签名,$name为具体的behavior行为文件。

    如果使用自动注册,则需要在Common目录下新建tags.php文件。其中可以直接通过返回数组的方法进行批量绑定,TP在运行中会自动加载这个配置并进行绑定。例如:

    <?php 
    return array(
        "hellow" => array('Home\\Behaviors\\TolldetectBehavior')
    );
     ?>
    

    以上代码就完成了'hellow'标签与我上面定义的事件的自动注册。
    当我们手动或自动完成了行为拓展的绑定,就可以设置事件的触发点了。
    触发钩子则会执行run方法。

  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/augurG/p/7225494.html
Copyright © 2011-2022 走看看