PHP 实际开发需求中使用到 AOP Aspect

前言

什么是AOP,这里不深入,这里主要是阐述AOP中的Aspect(切面),主要是以实际开发中使用到AOP的一个例子来说明比较有深刻的印象。

例如 ThinkPHP 中的控制器前置操作beforeActionList,又或者中间件,还有自己创建一个基类来实现等等,以上方法在某种意义上也有一些AOP的思想(一般来说 AOP是指将几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为),AOP像OOP一样,只是一种编程范式,AOP并没有规定说,实现AOP协议的代码,要用什么方式去实现。我的理解是 将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程,把和主业务无关的事情,放到代码外面去做,对原有代码毫无入侵性。

AOP可能很多人只是了解过并没有真正使用到实际的项目中,我认为只有在实际项目中去实现才算是有意义的(最好先在个人项目中实践一下)

ar414

实践

环境

网关中某个服务使用了hyperf 2.0

需求

有分页的数据中将Laravel分页器的结果元数据字段转为网关分页规范数据字段

这个的需求有很多方法实现,这里我使用了将 提供分页数据的控制器中的方法 统一进行切面处理,这样的做法,对原有代码毫无入侵性,这就是AOP的好处了,把和主业务无关的事情,放到代码外面去做

Laravel 分页器默认字段

{
   "total": 50,
   "per_page": 15,
   "current_page": 1,
   "last_page": 4,
   "first_page_url": "http://laravel.app?page=1",
   "last_page_url": "http://laravel.app?page=4",
   "next_page_url": "http://laravel.app?page=2",
   "prev_page_url": null,
   "path": "http://laravel.app",
   "from": 1,
   "to": 15,
   "data":[
        {
            // Result Object
        },
        {
            // Result Object
        }
   ]
}

网关分页规范字段

{
   "total": 50,
   "current_page": 1,
   "last_page": 4,
   "data":[
        {
            // Result Object
        },
        {
            // Result Object
        }
   ]
}

具体实现方法

hyperf 2.0 中使用 Aspect 切面
通过配置要切入的类,这里切入的是面向有分页数据的控制器中的具体方法
例如 TestController::getListTest1Controller::getList 这两个方法提供了分页数据

定义切面(Aspect)
一般而言,我们管切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点

class PageResultAspect extends AbstractAspect
{

  public $classes = [
    TestController::class . '::' . 'getList',
    Test1Controller::class . '::' . 'getList',
  ];

  public $annotations = [];

  public function process(ProceedingJoinPoint $proceedingJoinPoint)
  {
        // 切面切入后,执行对应的方法会由此来负责 
      // $proceedingJoinPoint 为连接点,通过该类的 process() 方法调用原方法并获得结果
      $result = $proceedingJoinPoint->process();

      //将结果进行统一处理
      if(isset($result['first_page_url'])) {
          unset($result['first_page_url']);
          unset($result['last_page_url']);
          unset($result['next_page_url']);
          unset($result['path']);
          unset($result['prev_page_url']);
          unset($result['per_page']);
          unset($result['from']);
          unset($result['to']);
      }

      return $result;
  }

}



本作品采用《CC 协议》,转载必须注明作者和本文链接
AR414
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!