首页 > 代码库 > PHP一个类AOP的实现
PHP一个类AOP的实现
由于项目有一个需求,需要在原来的代码上做一个封装. 由于不想修改原有代码, 查了一下, 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 | } |
PHP一个类AOP的实现
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。