php之aop实践

PHP之AOP实践

AOP,全称为Aspect Oriented Programming(面向切面编程),是一种编程思想,旨在将横向的功能抽离,形成“切面”。在 PHP 中,可以使用一些框架或者库来实现 AOP,本文将介绍其中一种实现方式 —— Go! AOP PHP。

Go! AOP PHP 简介

Go! AOP PHP 是一个 AOP 库,由于使用了 PHP 强大的“魔术方法”机制,因此实现了非常简单易用的 AOP。

使用 Go! AOP PHP,可以快速地、不侵入地实现以下功能:

  • 日志记录
  • 性能统计
  • 缓存优化
  • 事务管理
  • 权限控制

安装

安装 Go! AOP PHP 通常可以通过 Composer 快速完成:

composer require goaop/framework

基本使用

使用 Go! AOP PHP 需要定义一个 Aspect,它是一个横向的功能,可以理解成“切面”。在 Aspect 中我们可以定义一些 Advise(通知),它们对应了不同的“切点”,例如 before、after、around 等等。

实现一个带有日志记录的“切面”可以这样写:

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

class LogAspect implements Aspect
{
    /**
     * @Before("execution(public App\Services\*->*(..))")
     */
    public function beforeMethodCall(MethodInvocation $invocation)
    {
        $className = get_class($invocation->getThis());
        $methodName = $invocation->getMethod()->name;

        $logger->info(sprintf('Calling %s::%s()', $className, $methodName));
    }
}

在上例中,我们定义了一个名为 LogAspect 的切面,使用注解 @Before("execution(public App\Services*->*(..))") 来匹配所有 App\Services 命名空间下的“公有方法”作为“切点”,在这些方法执行之前记录日志。

定义完 Aspect 之后,我们还需要使用 factory 来创建一个代理类,它会继承原始类,并在其中加入 Aspect 实例中定义的 Advise:

use Go\Aop\Features;
use Go\Aop\Support\AopUtils;

$aspectContainer = AopUtils::getInstance()->getContainer();

$aspectContainer->registerAspect(new LogAspect());
$features = new Features();
$features->setGeneratedClassesTargetDir(__DIR__ . '/gen');
$features->setAopCacheDir(__DIR__ . '/cache');

$aspectKernel = AspectKernelFactory::createKernel('dev', true, $features);
$aspectKernel->init();

$proxyGenerator = $aspectKernel->getContainer()->get('goaop.proxy_generator');
$proxyGenerator->generateProxyClass(App\Services\MyService::class);

完成以上步骤后,就可以将原始类 MyService 的实例替换为代理类的实例,这样所有调用 MyService 实例的方法都会被代理类拦截,并执行 LogAspect 中的 Advise。

总结

本文介绍了 PHP 中一种实现 AOP 的库 —— Go! AOP PHP,介绍了它的安装和基本使用方法。 AOP 编程思想是非常重要的思想,可以帮我们在复杂应用中快速或灵活地实现各种功能,例如日志记录、缓存优化、事务管理等等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:php之aop实践 - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • SpringBoot单元测试使用@Test没有run方法的解决方案

    如果在使用SpringBoot进行单元测试时,使用Junit的@Test注解却出现了”No tests found with test runner ‘JUnit 4′”的错误,则有可能是JUnit和SpringBoot版本不匹配所致。下面是解决方案的完整攻略。 确认版本 首先确认自己使用的JUnit和SpringBoot版本。在pom.xml文件中找到对应…

    other 2023年6月26日
    00
  • 详解css加载会造成阻塞吗

    CSS加载可能会阻塞页面的渲染,尤其是在页面有大量CSS文件或者CSS文件大小较大的情况下。这是因为在浏览器下载页面的过程中,遇到CSS文件的时候,浏览器需要先下载并解析该CSS文件,再根据CSS文件修改HTML DOM树和CSSOM树。只有在CSS文件下载和解析完成后,浏览器才会继续下载并解析HTML文件及其他嵌入式文件,最后将页面渲染出来。因此,CSS文…

    other 2023年6月25日
    00
  • JavaScript 原型继承之构造函数继承

    JavaScript 原型继承之构造函数继承攻略 什么是构造函数继承 构造函数继承(也称为经典继承)是一种使用构造函数来创建对象并继承来自父类的属性和方法的方法。这种方式通过在子类的构造函数中调用父类构造函数以继承属性,然后将子类原型设置为父类实例来继承方法。 如何进行构造函数继承 在子类构造函数中,通过调用父类构造函数,来继承父类的属性: function…

    other 2023年6月27日
    00
  • Spring 静态变量/构造函数注入失败的解决方案

    Spring静态变量/构造函数注入失败的解决方案 在使用 Spring 进行开发的过程中,有时会遇到注入静态变量或者依赖注入到构造函数中的依赖注入失败的问题。本文将介绍这些问题的原因,以及如何解决。 1.为什么静态变量/构造函数注入失败 在使用 Spring 进行依赖注入时,常见的方式是在类的属性编辑和 setter 方法中使用注解进行注入。对于静态变量和构…

    other 2023年6月26日
    00
  • Linux中网络管理命令ipconfig与route的基本使用教程

    Linux中网络管理命令ipconfig与route的基本使用教程 在Linux系统中,网络管理是非常重要的一项任务。ipconfig和route是两个常用的命令,用于配置和管理网络接口和路由表。下面是它们的基本使用教程。 ipconfig命令 ipconfig命令用于配置和管理网络接口。以下是ipconfig命令的基本用法: ipconfig [选项] […

    other 2023年7月30日
    00
  • java+selenium自动化测试学习(一)

    以下是关于“Java+Selenium自动化测试学习(一)”的完整攻略,包括基本概念、步骤和两个示例。 基本概念 Selenium是一种自动化测试工具,可以用于Web应用程序的功能和用户界面。Selenium支持多种编程语言,包括Java、Python、C#等。Java是一种广泛使用的编程语言,也是Selenium最常用的编程语言之一。在使用Java和Sel…

    other 2023年5月7日
    00
  • Spring创建IOC容器的方式解析

    Spring创建IOC容器的方式解析 Spring是一个强大的Java开发框架,它提供了多种方式来创建IOC(控制反转)容器,用于管理和组织应用程序中的对象。以下是Spring创建IOC容器的几种常见方式: 1. XML配置文件方式 使用XML配置文件是最传统和常见的创建IOC容器的方式。在XML配置文件中,我们可以定义Bean的名称、类型、依赖关系等信息。…

    other 2023年10月17日
    00
  • Java日志软件Log4j的基本使用教程

    Java日志软件Log4j的基本使用教程 Log4j是一个流行的Java日志记录工具,它可以帮助开发人员在应用程序中实现灵活的日志记录功能。本教程将详细介绍Log4j的基本使用方法,并提供两个示例说明。 步骤1:添加Log4j依赖 首先,您需要在您的Java项目中添加Log4j的依赖。您可以通过Maven或Gradle等构建工具来完成此操作。以下是使用Mav…

    other 2023年9月6日
    00
合作推广
合作推广
分享本页
返回顶部