用动态代理实现AOP切面编程,PHP代码演示

代码:

<?php
class DynamicProxy
{
	private $obj;

	private $regPrePosts=[];
	
	public function __construct($obj)
	{
		$this->regPrePosts=[];
		$this->obj=$obj;
	}

	public function registerPrePost($type, $obj)
	{
		if('pre'==$type){
			$this->regPrePosts['pre'][]=$obj;
		}
		else{
			$this->regPrePosts['post'][]=$obj;
		}
	}

	public function __call($name, $arguments)
	{
		// return $this->regPrePosts;
		// 使用反射类
		$reflection = new ReflectionClass($this->obj);

		$method=$reflection->getMethod($name);

		// 前置操作
		if(isset($this->regPrePosts['pre'])){
			echo 'before actions:', PHP_EOL;
			foreach ($this->regPrePosts['pre'] as $obj) {
				try{
					$obj->handle($arguments);
				}
				catch(\Exception $e){
					echo 'error:', $e->getMessage(), PHP_EOL;
					return ;
				}
			}
		}

		// 执行反射函数
		$return=$method->invokeArgs($this->obj, $arguments);

		// 后置操作
		if(isset($this->regPrePosts['post'])){
			echo 'after actions:', PHP_EOL;
			foreach ($this->regPrePosts['post'] as $obj) {
				$obj->handle($return);
			}
		}
	}
}

// 具体类
class ConcreteClass1
{
	public function doOneThing($action_name)
	{
		echo '* action name:', $action_name, PHP_EOL;

		return true;
	}
}

// 另一个具体类
class ConcreteClass2
{
	public function doAnotherThing($action_name, $token)
	{
		echo '* another action name:', $action_name, PHP_EOL;
	}
}

// 日志类
class Log
{
	public function handle($log)
	{
		echo 'Log:';

		print_r($log);

		echo PHP_EOL;
	}
}

// 认证类
class Auth
{
	public function handle($token)
	{
		if('abc123456'==$token[1]){
			echo 'authenticated succeed.', PHP_EOL;
		}
		else {
			// echo 'authenticated faild.', PHP_EOL;
			throw new \Exception('authenticated faild.');
		}
	}
}

// 演示
$DynamicProxy=new DynamicProxy(new ConcreteClass1);
$DynamicProxy->registerPrePost('pre',new Auth);
$DynamicProxy->registerPrePost('pre', new Log);
$DynamicProxy->registerPrePost('post', new Log);

$call=$DynamicProxy->doOneThing('index', 'abc123456');
print_r($call);

echo '--------', PHP_EOL;

$DynamicProxy=new DynamicProxy(new ConcreteClass2);
$DynamicProxy->registerPrePost('pre',new Auth);
$DynamicProxy->doAnotherThing('create', 'abc123456-wrong_token');

示例结果:

before actions:
authenticated succeed.
Log:Array
(
    [0] => index
    [1] => abc123456
)

* action name:index
after actions:
Log:1
--------
before actions:
error:authenticated faild.
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页