`

PHP一个类AOP的实现

    博客分类:
  • php
php 
阅读更多
由于项目有一个需求,需要在原来的代码上做一个封装. 由于不想修改原有代码, 查了一下, PHP没有方便的支持AOP的方法,于是参考了网上一些文章,写了个包装器, 可以在不修改原有代码的基础上为函数添加before和after实现.

 
标签: <无>
 

代码片段(3)[全屏查看所有代码]

1. [代码]核心类     

01 <?php
02  
03 /**
04  * 包装器(Wrapper).
05  * Wrapper是一个AOP_LIKE的实现. 也可以看作监听者模式的实现.
06  * 一个Wrapper报装了一个对象(source). source可以是任意对象(不包括数组及原子类型),甚至是一个Wrapper.
07  *
08  * 包装器可以任意添加饰品(Decoration).通过Wrapper调用source的函数的流程将是:
09  *  unpacking --> teardown --> open --> setup --> packing.
10  *
11  *  例如调用source->doXX(),各个流程将是:
12  *  unpacking:  解包. 这是调用任意source的函数都会调用的方法;
13  *  teardown:   撕掉饰品. 对于Wrapper中的每个Decoration,调用其before()函数;
14  *  open:       真正调用source->doXX()函数;
15  *  setup:      重新贴上饰品. 对于Wrapper中的每个Decoration,调用其after()函数;
16  *  packing:    重新打包.  这是调用任意source的函数都会调用的方法;
17  *
18  */
19 class Wrapper{
20     private $source;
21  
22     /**
23      * @var bool
24      */
25     private $undecorated;
26  
27     /**
28      * @var array[Decoration]
29      */
30     private $decorations=array();
31  
32     public function __construct($source){
33         $this->source = $source;
34     }
35  
36     public function __call($name,$parameters){
37         $this->unpacking($name,$parameters);
38         $this->tearDown($name,$parameters);
39  
40         // opening
41         if(method_exists($this->source, $name)){
42             $retval = call_user_func_array(array($this->source,$name),$parameters);
43         }
44  
45         $this->setup($retval,$name,$parameters);
46         $this->packing($retval,$name,$parameters);
47  
48         return $retval;
49     }
50  
51     public function unpacking($name,$parameters){
52     }
53  
54     public function packing($name,$parameters){
55     }
56  
57     public function tearDown($name,$parameters){
58         if($this->undecorated){
59             return;
60         }
61         foreach ($this->decorations as $d){
62             $d->before($name,$parameters);
63         }
64     }
65  
66     public function setup($retval,$name,$parameters){
67         if($this->undecorated){
68             return ;
69         }
70         foreach ($this->decorations as $d){
71             $d->after($retval,$name,$parameters);
72         }
73     }
74  
75     public function decarate($decoration){
76         $this->decorations[] = $decoration;
77     }
78  
79  
80  
81     public static function wrap($source){
82         //  wrap the source
83         $wrapperConfig = app()->wrappers[get_class($source)];
84         if($wrapperConfig){
85             $wrapperClass $wrapperConfig['class'];
86             $wrapper new $wrapperClass($source);
87  
88             foreach ($wrapperConfig['decorations'as $item){
89                 $decoration new $item;
90                 $wrapper->decarate($decoration);
91             }
92         }
93         return $wrapper?$wrapper:$source;
94     }
95  
96 }
97  
98 ?>

2. [代码]配置     

01 'wrappers'=>array(
02         'ContentService'=>array(
03                 'class'=>'ContentWrapper',
04                 'decorations'=>array(
05                         'DasaiContentDecoration',
06                 )
07         ),
08         'AOPWorker'=>array(//for test
09             'class'=>'DiagnosisWrapper',
10             'decorations'=>array(
11                 'DasaiDiagnosisDecoration'
12             ),
13         ),
14 ),

3. [代码]测试代码     

01 class AOPWorker{
02     public function testAOP(){
03         Debugger::print_r(
04             "\n工人:我要做一大堆操作了
05                 \n工人:... ...
06                 \n工人:好了 做完了\n");
07         return 'OK';
08     }
09  
10 }
11  
12  
13 public function testAOP(){// test aop  测试入口
14         $aop = Wrapper::wrap(new AOPWorker());
15         $aop->testAOP(33347);
16 }
17  
18  
19  
20 class DiagnosisWrapper extends Wrapper{
21  
22     public function unpacking($name$parameters){
23         echo "\nDiagnosisWrapper:喂,有人调用$name,我要解包了.\n";
24     }
25  
26  
27     public function packing($retval,$name$parameters){
28         echo "\nDiagnosisWrapper:喂,调用$name,结果为$retval,重新打包好了.\n";
29     }
30 }
31  
32  
33  
34 class DasaiDiagnosisDecoration extends Decoration {
35     public function before($name,$parameters){
36         echo "\r\nDasaiDiagnosisDecoration:开始调用$name,已经告诉张三李四了.\n";
37     }
38  
39     public function after($retval,$name,$parameters){
40         echo "\nDasaiDiagnosisDecoration:结束调用$name,告诉霍金和Sheldon了.\n";
41     }
42 }
2
3
分享到:
评论

相关推荐

    帮swoft2实现一个aop非侵入式的缓存方式

    帮swoft2 实现一个aop 非侵入式的缓存方式

    PHP-设计模式: AOP切面编程,DI依赖注入,DIC容器DEMO。简单易懂哦

    易于理解的说明, 简单明了的DEMO,从正常的编程方式,演变到依赖注入,再演变到AOP切面编程。 描述了什么是反转控制,什么是容器

    AOP:PHP中的AOP

    AOP旨在实现跨领域关注点的分离(缓存,日志,安全性,事务等) 安装 您可以使用pecl sudo pecl install aop-beta 或者 从github下载AOP,编译并将扩展名添加到您的php.ini中 # Clone the repository on your ...

    使用AOP进行权限控制

    权限控制代码散落在各个类中 权限判断和业务逻辑耦合在一起。

    ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解

    主要介绍了ThinkPHP5 框架引入 Go AOP,PHP AOP编程,结合具体项目项目分析了ThinkPHP5 引入 Go AOP,PHP AOP编程相关概念、原理、操作技巧与注意事项,需要的朋友可以参考下

    aop4php:介绍 AOP 世界的小型 PHP 库

    支持面向方面的编程 (AOP) 的语言更常使用用于一组点的函数 - 切入点。 这些点的功能由程序代码决定,它被礼貌地称为 Advice (AspectJ)。 因此,方面描述了一组特定系统组件的横切关注点。 组件本身仅包括它们应该...

    PHP三层结构(下) PHP实现AOP第1/2页

    本文源码下载地址:http://xiazai.jb51.net/201007/yuanma/TraceLWord.rar 开发环境为 eclipse(pdt) 让我们把注意力集中到中间服务层上来。中间服务层代码比较简单,只是调用数据访问层代码将留言保存到数据库。...

    基于Swoole 4.5+实现的高性能、高灵活性的PHP协程框架.rar

    (https://www.php-fig.org/psr) 实现,基于强大的依赖注入设计,保证了绝大部分组件或类都是 `可替换` 与 `可复用` 的。 框架组件库除了常见的协程版的 `MySQL 客户端`、`Redis 客户端`,还为您准备了协程版的 `...

    基于Swoole原生协程新时代PHP高性能协程全栈框架,内置协程网络服务器及常用协程客户端,常驻内存,不依赖传统的PHP-FPM

    首个基于Swoole原生协程的新时代 PHP 高性能协程全栈框架,内置协程网络服务器及常用的协程客户端,常驻内存,不依赖传统的PHP-FPM,全异步非阻塞IO实现,以类似于同步客户端的写法实现异步客户端的使用,没有复杂的...

    PHP框架 Ding Framewrok v1.6.1

    Ding 是一个 PHP 框架实现了依赖注入、AOP面向方面编程、轻量级、简单和快速的 MVC 模式,syslog、TCP客户端和服务器端非阻塞的套接字、定时器、自定义错误、信号以及异常处理、PAGI 集成、PAMI集成等等,类似 Java ...

    swoft首个基于Swoole原生协程的新时代PHP高性能协程全栈组件化框架

    首个基于 Swoole 原生协程的新时代 PHP 高性能协程全栈组件化框架,内置协程网络服务器及常用的协程客户端,常驻内存,不依赖传统的 PHP-FPM,全异步非阻塞 IO 实现,以类似于同步客户端的写法实现异步客户端的使用...

    基于 Swoole 原生协程的新时代 PHP 高性能协程全栈框架,内置协程网络服务器及常用的协程客户端

    首个基于 Swoole 原生协程的新时代 PHP 高性能协程全栈框架,内置协程网络服务器及常用的协程客户端,常驻内存,不依赖传统的 PHP-FPM,全异步非阻塞 IO 实现,以类似于同步客户端的写法实现异步客户端的使用,没有...

    marcelog-Ding-1.6.1.zip_php tcp

    marcelog Ding是一个PHP框架,实现了依赖注入、AOP面向方面编程、轻量级、简单和快速的MVC模式,syslog、TCP客户端和服务器端非阻塞的套接字、定时器、自定义错误、信号以及异常处理、PAGI 集成、PAMI集成等等,类似...

    marcelog Ding PHP框架 v1.6.1.zip

    marcelog Ding是一个PHP框架,实现了依赖注入、AOP面向方面编程、轻量级、简单和快速的MVC模式,syslog、TCP客户端和服务器端非阻塞的套接字、定时器、自定义错误、信号以及异常处理、PAGI 集成、PAMI集成等等,类似...

    蜂巢平台 云计算应用框架 v0.4.0.1.zip

    蜂巢平台(OpenComb Platform)是一个基于 PHP5.3 实现的深度云计算应用框架。蜂巢采用了扩展模式,系统中的功能和特性,都由扩展提供。 因此,用户可以通过开发和安装扩展来部署各种类型的互联网应用。 “扩展驱动...

    基于springboot实现OA自动化办公系统附数据库文件+文档说明

    多个web资源,这多个web资源用于对外提供服务,此时应把这多个web资源放在一个目录中,以组成一个web应用(或web应用程序) Spring框架是一个开放源代码的J2EE应用程序框架,由Rod Johnson发起,是针对bean的生命...

    PHP实现的支付宝支付功能示例

    本文实例讲述了PHP实现的支付宝支付功能。分享给大家供大家参考,具体如下: 在给app做支付宝支付接口的时候收集内容整理如下: 接口: import('alipay.AopClient', EXTEND_PATH); import('alipay.request....

    swoft 全栈框架

    首个基于 Swoole 原生协程的新时代 PHP 高性能协程全栈框架,内置协程网络服务器及常用的协程客户端,常驻内存,不依赖传统的 PHP-FPM,全异步非阻塞 IO 实现,以类似于同步客户端的写法实现异步客户端的使用,没有...

    蜂巢平台 云计算应用框架 v0.4.0.1

    蜂巢平台(OpenComb Platform)是一个基于 PHP5.3 实现的深度云计算应用框架。蜂巢采用了扩展模式,系统中的功能和特性,都由扩展提供。 因此,用户可以通过开发和安装扩展来部署各种类型的互联网应用。“扩展驱动模式...

Global site tag (gtag.js) - Google Analytics