`

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
分享到:
评论

相关推荐

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

    当需要一个对象时,只需从容器中获取,而无需关心其具体的创建过程。DIC还允许我们进行依赖的自动解析,使得代码更简洁,降低了组件间的耦合度。 在这个压缩包文件"design_pattern"中,你可以找到关于这些概念的...

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

    在这个场景中,我们将探讨如何在Swoft2中实现一个非侵入式的缓存策略,使得缓存功能可以无缝地融入到现有的业务逻辑中,而不需要修改被拦截的方法或类。 首先,我们需要理解非侵入式缓存的概念。非侵入式缓存意味着...

    AOP资源

    3. **Aspect Oriented PHP (AoPHP)**:PHP语言的AOP实现,允许开发者定义切面并自动织入到PHP类中。 在实际开发中,使用AOP可以有效降低系统的复杂性,提高代码的整洁度。通过合理设计切面和切入点,可以避免代码的...

    aop.rar_php a

    这个压缩包可能包含了一个实现AOP概念的PHP框架,让我们深入探讨一下AOP及其在PHP中的应用。 面向切面编程(AOP)的核心思想是将程序中的横切关注点(如日志、异常处理、安全性等)与业务逻辑分离。传统的OOP(面向...

    使用AOP进行权限控制

    面向切面编程(AOP)提供了一种优雅的解决方案,用于分离关注点(Separation of Concerns),即在不修改业务逻辑代码的前提下,通过横切关注点(Cross-cutting Concerns)的方式实现权限控制功能的集中管理。...

    AOP:PHP中的AOP

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

    PHP语言中的面向方面编程实现.pdf

    本文首先介绍了AOP技术的基础概念,然后分析了PHP语言中AOP技术的实现策略,提出了基于PHP语言的AOP实现目标和实现原理。接着,描述了使用AOP技术的软件系统结构和核心文件,并设计了相应的AOP支持类。最后,通过...

    Laravel开发-goaop-laravel-bridge

    Laravel中,你可以定义一个类,使用GoAop的注解来指定切点和通知。例如,下面的代码定义了一个记录日志的切面: ```php &lt;?php use Go\Aop\Aspect; use Go\Lang\Annotation\Before; use Go\Lang\Annotation\Pointcut...

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

    这些附加功能使得代码变得复杂,容易产生“上帝类”问题,即一个类承担了过多的责任,违反了单一职责原则。 为了解决这个问题,我们可以引入面向切面编程(Aspect-Oriented Programming,AOP)。AOP允许我们将关注...

    springboot +mvc+ freemarker +aop实现校友信息管理系统

    该项目利用了基于springboot + vue + mysql的开发模式框架实现的课设系统,包括了项目的源码资源、sql文件、相关指引文档等等。 【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理...

    ThinkPHP类似AOP思想的参数验证的实现方法

    通过上述步骤和代码,我们可以实现一个基于AOP思想的参数验证机制。这种机制的优势在于它的可重用性和灵活性,可以针对不同的业务场景定义不同的验证规则,而无需在每次业务逻辑处理时重复编写验证代码。同时,这种...

    一个能够Hook绝大多数函数类部分opcode的PHP7扩展

    标题中的“一个能够Hook绝大多数函数类部分opcode的PHP7扩展”揭示了这个PHP7扩展的主要功能,即通过hook技术来监控、修改或控制程序执行的行为。Hook是一种编程技术,允许在程序运行时插入自定义代码,以便在特定...

    用php框架实现的cms

    “用php框架实现的cms”这个主题意味着我们正在讨论如何利用PHP框架来构建一个这样的系统。通常,PHP框架如ThinkPHP,Laravel,Symfony等,为开发者提供了许多便利的功能,如路由处理、模型-视图-控制器(MVC)架构...

    JMSAopBundle:向Symfony添加AOP功能

    **JMSAopBundle**是针对Symfony框架的一个扩展,它为开发者提供了面向切面编程(Aspect-Oriented Programming, AOP)的能力。面向切面编程是一种编程范式,旨在提高软件的可重用性,降低模块间的耦合度,使得关注点...

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

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

    PHP面向对象程序设计之类与反射API详解共5页.pdf

    在PHP中,你可以使用`class`关键字来声明一个类,并使用`public`、`private`、`protected`来控制成员的访问权限。例如: ```php class MyClass { public $publicVar; private $privateVar; protected $protected...

    支付宝php-sdk demo原版

    总的来说,这个“支付宝php-sdk demo原版”提供了从支付到通用接口调用的完整示例,对于初学者或者需要快速接入支付宝服务的开发者来说,是一个非常有价值的资源。通过学习和研究这个SDK,开发者可以了解到如何在PHP...

    alipay-sdk-PHP-20150312220100

    开发者通过实例化这个类并调用其方法,可以轻松发起各种请求并处理响应。例如,`AlipayClient`是AopSdk的核心类,它封装了签名、加密等安全操作,并提供了如`createAppApiRequest`这样的方法来创建API请求。 2. **...

    基于PHP的swoft PHP微服务框架.zip

    综上所述,这个压缩包提供了一个基于PHP的Swoft微服务框架的实现,对于想要在PHP环境中实践微服务架构的开发者来说,这是一个非常有价值的资源。通过深入研究和实践,开发者可以掌握如何在PHP中构建高性能、可扩展的...

Global site tag (gtag.js) - Google Analytics