由于项目有一个需求,需要在原来的代码上做一个封装. 由于不想修改原有代码, 查了一下, PHP没有方便的支持AOP的方法,于是参考了网上一些文章,写了个包装器, 可以在不修改原有代码的基础上为函数添加before和after实现.
标签: <无>
1. [代码]核心类
30 | private $decorations = array (); |
32 | public function __construct( $source ){ |
33 | $this ->source = $source ; |
36 | public function __call( $name , $parameters ){ |
37 | $this ->unpacking( $name , $parameters ); |
38 | $this ->tearDown( $name , $parameters ); |
41 | if (method_exists( $this ->source, $name )){ |
42 | $retval = call_user_func_array( array ( $this ->source, $name ), $parameters ); |
45 | $this ->setup( $retval , $name , $parameters ); |
46 | $this ->packing( $retval , $name , $parameters ); |
51 | public function unpacking( $name , $parameters ){ |
54 | public function packing( $name , $parameters ){ |
57 | public function tearDown( $name , $parameters ){ |
58 | if ( $this ->undecorated){ |
61 | foreach ( $this ->decorations as $d ){ |
62 | $d ->before( $name , $parameters ); |
66 | public function setup( $retval , $name , $parameters ){ |
67 | if ( $this ->undecorated){ |
70 | foreach ( $this ->decorations as $d ){ |
71 | $d ->after( $retval , $name , $parameters ); |
75 | public function decarate( $decoration ){ |
76 | $this ->decorations[] = $decoration ; |
81 | public static function wrap( $source ){ |
83 | $wrapperConfig = app()->wrappers[get_class( $source )]; |
85 | $wrapperClass = $wrapperConfig [ 'class' ]; |
86 | $wrapper = new $wrapperClass ( $source ); |
88 | foreach ( $wrapperConfig [ 'decorations' ] as $item ){ |
90 | $wrapper ->decarate( $decoration ); |
93 | return $wrapper ? $wrapper : $source ; |
2. [代码]配置
02 | 'ContentService' => array ( |
03 | 'class' => 'ContentWrapper' , |
05 | 'DasaiContentDecoration' , |
09 | 'class' => 'DiagnosisWrapper' , |
11 | 'DasaiDiagnosisDecoration' |
3. [代码]测试代码
02 | public function testAOP(){ |
13 | public function testAOP(){ |
14 | $aop = Wrapper::wrap( new AOPWorker()); |
20 | class DiagnosisWrapper extends Wrapper{ |
22 | public function unpacking( $name , $parameters ){ |
23 | echo "\nDiagnosisWrapper:喂,有人调用$name,我要解包了.\n" ; |
27 | public function packing( $retval , $name , $parameters ){ |
28 | echo "\nDiagnosisWrapper:喂,调用$name,结果为$retval,重新打包好了.\n" ; |
34 | class DasaiDiagnosisDecoration extends Decoration { |
35 | public function before( $name , $parameters ){ |
36 | echo "\r\nDasaiDiagnosisDecoration:开始调用$name,已经告诉张三李四了.\n" ; |
39 | public function after( $retval , $name , $parameters ){ |
40 | echo "\nDasaiDiagnosisDecoration:结束调用$name,告诉霍金和Sheldon了.\n" ; |