之前有写一篇Thinkphp AOP 编程的例子 ​​查看​​

AOP主要功能

日志记录,性能统计,安全控制,事务处理,异常处理等等wn及扩展

AOP主要意图

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

AOP的好处

​​查看aop 的好处例子​​

初识 yii 中的行为

​​点击跳转​​

项目中封装的BaseBehavior

<?php
namespace service\behavior;


use yii\base\Behavior;
use yii\web\Controller;

class BaseBehavior extends Behavior
{
public function beforeActionBase($event)
{
if (static::matchRoutes($this->only_routes)) {
return $this->beforeAction($event);
}
}
public function afterActionBase($event){
if (static::matchRoutes($this->only_routes)) {
return $this->afterAction($event);
}
}

public function events()
{
return [
Controller::EVENT_BEFORE_ACTION => 'beforeActionBase',
Controller::EVENT_AFTER_ACTION => 'afterActionBase'
];
}

public static function matchRoutes($routes)
{
$route = \Yii::$app->requestedRoute;
if (is_array($routes)) {
foreach ($routes as $r) {
if ($r == $route) {
return true;
}
$r = str_replace('/', '\/', $r);
$r = str_replace('*', '.*', $r);
$r = "/^{$r}$/";
if (preg_match($r, $route, $res)) {
return true;
}
}
}
return false;
}
}

封装的功能实践

比如 订单行为: 继承 BaseBehavior ,$only_routes 只有这些路由才回触发行为

我看到一些程序,是把定时任务的事件,放到这边做一个缓存10秒的执行。相当于一个10秒的定时器吧。

也可以把同步事件,写到这边。

这个根据系统的复杂度,和流量决定怎么来做的。

class OrderBehavior extends BaseBehavior
{
protected $only_routes = [
'mch/order/*',
'mch/share/*',
'mch/miaosha/*',
'api/order/*',
'api/share/*',
'api/miaosha/*',
// 'mch/store/index',
'mch/user/*',
'api/user/*'
];

public $store_id;
public $store;
public $share_setting;

public function beforeAction($e)
{
//订单过期检查之类事件

public function afterAction(){
echo "****";
}

行为在验证中的运用

class LoginBehavior extends ActionFilter
{
public function beforeAction($e)
{
$access_token = \Yii::$app->request->get('access_token');
if (!$access_token) {
$access_token = \Yii::$app->request->post('access_token');
}
if (!$access_token) {
\Yii::$app->response->data = new ApiResponse(-1, 'access_token 不能为空');
return false;
}
if (\Yii::$app->user->loginByAccessToken($access_token)) {
return true;
} else {
\Yii::$app->response->data = new ApiResponse(-1, '登录失败,');
return false;
}
}
}

如何在控制层运用行为:

class OrderController extends Controller
{
public function behaviors()
{
return array_merge(parent::behaviors(), [
'login' => [
'class' => LoginBehavior::className(),
],
]);
}
}

可以看处订单控制器,用了上面的login 验证器,同时,还继承了Controller 中的行为,以继承的方式,扩展了行为
那是不是全部控制器都会使用,并执行这么多的行为呢,这就是之前only_rule 的作用了

class Controller extends \yii\web\Controller
{
public function behaviors()
{
return [
'order' => [
'class' => OrderBehavior::className(),
],
'coupon' => [
'class' => CouponBehavior::className(),
],
'pintuan' => [
'class' => PintuanBehavior::className(),
],
'bargain' => [
'class' => BargainBehavior::className(),
],
'lottery' => [
'class' => LotteryBehavior::className(),
],
'step' => [
'class' => StepBehavior::className(),
],
];
}
}

总结

总结一下,Aop 编程,不是很像 extends 继承的关系嘛 ,这样写有啥意义。其实某种程度上是把系统复杂化了,而且增加了看似不必要的操作。
但是做一些saas 系统,或者比较大的系统,aop编程,具有易读性和可扩展性,你啥时候开心了,就插入一个功能,啥时候不开心了,就拔了另外一个功能,而且比较不影响,后面的常规操作。
相对于 继承方式实现‘aop’实际中的例子就很明显,比如在某个接口你想有一些不要继承的类,但是硬生生的运行了,但是对该程序没什么软用。

ok ,think you for your time !

参考代码:
​​​https://github.com/liaoshengping/dingdong_shop.git​