当前位置: 代码迷 >> PHP >> PHP一个种AOP的实现
  详细解决方案

PHP一个种AOP的实现

热度:249   发布时间:2016-04-28 20:39:15.0
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?*/
19class?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.?[代码]测试代码?????

01class?AOPWorker{
02????public?function?testAOP(){
03????????Debugger::print_r(
04????????????"\n工人:我要做一大堆操作了
05????????????????\n工人:... ...
06????????????????\n工人:好了 做完了\n");
07????????return?'OK';
08????}
09?
10}
11?
12?
13public?function?testAOP(){// test aop? 测试入口
14????????$aop?= Wrapper::wrap(new?AOPWorker());
15????????$aop->testAOP(33347);
16}
17?
18?
19?
20class?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?
34class?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}
  相关解决方案