PHP AOP教程案例

yizhihongxing

下面我将为您详细讲解“PHP AOP教程案例”的完整攻略。

什么是AOP

面向切面编程(Aspect-Oriented Programming, AOP)是一种编程思想,它解决了面向对象编程中的一些横向关注点问题。 AOP 的一个核心功能便是拦截、修改某个对象的某个方法。PHP 的 AOP 有很多库可以使用,这里介绍的是 goaop/aop

安装

使用 composer 安装:

composer require goaop/framework

使用方式

定义切面

切面就是拦截修改某个类的某个方法。我们通过 Annotation 的方式来定义一个切面。例如:

use Go\Aop\Aspect;
use Go\Aop\Intercept\MethodInvocation;
use Go\Lang\Annotation\Around;

class LoggerAspect implements Aspect
{
    /**
     * @param MethodInvocation $invocation Invocation
     *
     * @Around("@execution(MyProject\Annotation\Loggable)")
     */
    public function aroundMethodExecution(MethodInvocation $invocation)
    {
        $method = $invocation->getMethod()->name;
        echo "Before {$method}\n";
        $result = $invocation->proceed();
        echo "After {$method}\n";
        return $result;
    }
}
  1. 类实现了 Go\Aop\Aspect 接口;
  2. 利用 Go\Lang\Annotation\Around 注解来定义切面的类型以及需要修改的方法;
  3. @execution(MyProject\Annotation\Loggable) 表示被 @Loggable 注解的方法将会被拦截修改。

这个切面的作用是在被 @Loggable 注解的方法调用前后分别打印出 "Before" 和 "After" 字符串。

使用切面

利用前文定义的 LoggerAspect 切面,修改 MyController 中的 testAction 方法:

use MyProject\Annotation\Loggable;

class MyController extends Controller
{
    /**
     * @Loggable
     */
    public function testAction()
    {
        return 'Test';
    }
}

testAction 方法上添加 @Loggable 注解后,方法被拦截,进入 LoggerAspectaroundMethodExecution 方法中,打印出对应的日志。

Test:

Before testAction
After testAction

以上就是使用 PHP AOP 的基本流程。

案例演示

这里再举一个常见的案例来说明 AOP 的作用。

问题

假设我们有这样一个场景:我们要在老项目中新增一个接口,需要让这个接口返回的 json 数据,完全按照别的项目返回的 json 数据格式来操作。

但是考虑实际情况,整个老项目中有很多地方都调用到了这个接口,如果我们要在所有这些调用点中修改代码,那就是一件非常麻烦的事情。

那么,那怎样才能让这个接口被调用的时候,能够自动转换 json 数据格式呢?

解决方案

使用 AOP 解决这个问题可以分为以下两个步骤:

  1. 定义转换器:将老项目中的 json 数据转为新的 json 数据;
  2. 编写切面:在老项目中的那个接口方法调用之前,把这个方法返回的 json 数据转换。

第一步:定义转换器

我们需要先定义一个转换器类,实现一个 convert 方法,将老项目中的 json 数据转成新的 json 数据:

class JsonConverter
{
    public function convert($oldJson)
    {
        // 这里是转换逻辑,比如:
        $arr = json_decode($oldJson, true);
        return json_encode($arr, JSON_PRETTY_PRINT);
    }
}

这里我们假设定义了一个 JsonConverter 类来完成 json 转换,实际开发中完全可以根据业务进行相应修改。

第二步:编写切面

在老项目中需要使用 AOP 来切入到接口被调用的方法中,并且在转换 json 数据后保存到返回结果中,这里我们需要编写如下的切面:

class JsonAspect implements Aspect
{
    /**
     * @var JsonConverter $jsonConverter
     */
    private $jsonConverter;

    public function __construct(JsonConverter $jsonConverter)
    {
        $this->jsonConverter = $jsonConverter;
    }

    /**
     * @param MethodInvocation $invocation Invocation
     *
     * @Around("@execution(MyProject\Annotation\JsonSerializable)")
     */
    public function aroundMethodExecution(MethodInvocation $invocation)
    {
        $result = $invocation->proceed();

        // 如果返回的结果是字符串,表示是 json,那么我们就需要处理
        if (is_string($result)) {
            $newJson = $this->jsonConverter->convert($result);
            return $newJson;
        }

        return $result;
    }
}

这里定义了一个名为 JsonAspect 的切面,它的作用是在 @JsonSerializable 注解被使用的接口方法上拦截,获取方法返回结果并将其转换为新的 json 格式。

其中 JsonConverter 是我们在第一步中定义的类,它的实例被传递给了 JsonAspect 切面的构造函数。

示例

现在让我们来看一下一个具体的示例,来模拟刚刚提到的那个场景。

  1. 在老项目中定义一个接口,并且在注解中使用 @JsonSerializable 标记:
class MyController
{
    /**
     * @JsonSerializable
     */
    public function myOldApi()
    {
        return '{"name":"Alice"}';
    }
}
  1. 在切面中实现对这个接口方法返回结果进行转换:
$jsonConverter = new JsonConverter();
$loggerAspect = new JsonAspect($jsonConverter);

$loader = include __DIR__ . '/../vendor/autoload.php';
$annotationLoader = new AnnotationLoader($loader);
$aspectContainer = new AspectContainer();
$aspectContainer->registerAspect($loggerAspect);

$kernel = AspectKernel::getInstance();
$kernel->init([
    'debug' => true,
    'cacheDir' => __DIR__ . '/cache',
    'includePaths' => [
        __DIR__ . '/../src',
        __DIR__ . '/../vendor/goaop/framework/src',
    ],
]);
$kernel->setLoader($annotationLoader);
$kernel->setAspectContainer($aspectContainer);

$controller = new MyController();
$result = $controller->myOldApi();

echo $result;

在上面的代码中,我们初始化 JsonAspect 切面的时候需要传递 JsonConverter 类的实例。然后我们使用 AOP 给 MyController 中的 myOldApi 方法加上了一个切面。当这个方法被调用时,实际返回的结果将会在这个切面中被转换。

以上就是使用 AOP 实现自动修改过滤 json 格式的攻略,希望对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PHP AOP教程案例 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • 浅谈php使用curl模拟多线程发送请求

    当我们需要向一个接口发送大量请求时,使用curl模拟多线程发送请求是一个非常实用的方法。以下是浅谈php使用curl模拟多线程发送请求的完整攻略。 准备工作 在开始之前,我们需要确认服务器是否已安装curl,以及我们是否在PHP的配置文件中启用了curl扩展。可以使用以下命令检查curl是否已安装: curl –version 如果返回了curl的版本信息…

    PHP 2023年5月27日
    00
  • 微课通如何录制微课 微课通录制电脑屏幕及网络课程教程

    微课通如何录制微课 简介 微课通是一款针对微课教学制作的移动应用,支持用户通过手机或平板电脑进行微课的制作和分享。本文将详细讲解微课通如何录制微课,包括录制电脑屏幕及网络课程教程等内容。 准备工作 在进行微课录制前,需要进行以下准备工作: 下载安装微课通应用; 准备要录制的内容,并确保电脑及网络连接良好; 准备好麦克风或外接麦克风,以确保录制的音频质量。 录…

    PHP 2023年5月26日
    00
  • PHP之十六个魔术方法详细介绍

    PHP之十六个魔术方法详细介绍 什么是魔术方法 在PHP中,魔术方法是以两个下划线开始并结束的方法,比如__construct()和__destruct()等。这些方法能够帮助我们在对象的实例化、析构、调用不存在的方法等过程中实现一些特殊的功能。 构造函数和析构函数 构造函数(__construct())和析构函数(__destruct())的用处很明显,前…

    PHP 2023年5月26日
    00
  • 小程序获取当前位置加搜索附近热门小区及商区的方法

    下面是小程序获取当前位置加搜索附近热门小区及商区的方法的完整攻略。 1. 获取当前位置 小程序获取当前位置可以使用微信小程序提供的wx.getLocation API。调用该 API 可以获取用户的当前位置信息,包括经度、纬度、速度等信息。 示例代码: wx.getLocation({ type: ‘gcj02’, // 坐标系类型 success(res)…

    PHP 2023年5月30日
    00
  • scratch编程怎么添加文本? scratch插入文字的教程

    添加文本是Scratch编程中的一项基础操作。我们可以使用Scratch中的文本块来向舞台、角色和其他对象添加文本。下面是如何在Scratch中添加文本的详细攻略: 步骤1:打开Scratch编辑器 首先,需要打开Scratch编辑器。可以使用Scratch官网提供的在线编辑器 (https://scratch.mit.edu/projects/editor…

    PHP 2023年5月30日
    00
  • php调用shell的方法

    下面是关于“php调用shell的方法”的详细攻略。 什么是shell Shell是计算机操作系统中一个命令行界面程序,它接收用户输入的命令,然后将其转换成操作系统能识别的指令,并交由内核处理。在本文中,我们主要关注的是Linux和Unix操作系统中的shell。 php如何调用shell命令 在PHP中可以通过调用系统命令来执行shell操作,常见的调用方…

    PHP 2023年5月23日
    00
  • php+正则将字符串中的字母数字和中文分割

    下面给出“php+正则将字符串中的字母数字和中文分割”的完整攻略。 准备工作 首先需要安装PHP开发环境,包括PHP的安装、web服务器的配置等。此处不再赘述,可以通过搜索引擎查询相关资料。完成环境安装后,可以在编辑器中新建一个php文件,比如命名为splitString.php,用于演示如何使用正则将字符串分割。 分割字符串 在PHP中,使用preg_sp…

    PHP 2023年5月26日
    00
  • windows下clarisse ifx怎么安装?Isotropix clarisse ifx 3.5 sp4安装破解图文教程

    对于安装clarisse ifx 3.5 sp4,我们需要首先下载和解压缩软件包,然后进行安装和破解。 以下是详细的攻略步骤: 下载和解压缩clarisse ifx 3.5 sp4 首先,我们需要去到clarisse ifx官网(https://www.isotropix.com/)下载clarisse ifx 3.5 sp4软件包。 点击“Download…

    PHP 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部