openclassrooms/service-proxy

v7.0.2 2024-07-26 14:41 UTC

README

Build Status SensioLabsInsight PHPStan PHP Coverage

Service Proxy 是一个库,提供在类上管理技术代码的功能。

  • 事务上下文
  • 安全访问
  • 缓存管理
  • 事件
  • 日志(尚未实现)

安装

安装 ServiceProxy 最简单的方法是通过 composer

创建以下 composer.json 文件,并运行 php composer.phar install 命令来安装。

{
    "require": {
        "openclassrooms/service-proxy": "*"
    }
}
<?php
require 'vendor/autoload.php';

use OpenClassrooms\ServiceProxy\ServiceProxy;

//do things

概念

拦截器

拦截器用作装饰器来响应方法执行。例如,使用 @Cache 注解是启用缓存拦截器的条件。

有两种类型的拦截器

前缀拦截器

在方法执行之前被调用的拦截器,它们必须实现 OpenClassrooms\ServiceProxy\Interceptor\Contract\PrefixInterceptor。将调用三个方法:

  • prefix:在方法执行之前调用。应返回 OpenClassrooms\ServiceProxy\Interceptor\Response\Response 的实例。
  • supportsPrefix:调用以确定是否应调用拦截器,例如,在缓存拦截器的情况下,它将检查方法是否有 @Cache 注解。
  • getPrefixPriority:调用以确定拦截器的优先级,优先级越高,拦截器越早被调用。

后缀拦截器

在方法执行之后被调用的拦截器,即使在抛出异常的情况下也是如此,它们必须实现 OpenClassrooms\ServiceProxy\Interceptor\Contract\SuffixInterceptor。将调用三个方法:

  • suffix:在方法执行之后被调用,即使抛出异常。应返回 OpenClassrooms\ServiceProxy\Interceptor\Response\Response 的实例。
  • supportsSuffix:调用以确定是否应调用拦截器,例如,在缓存拦截器的情况下,它将检查方法是否有 @Cache 注解。
  • getSuffixPriority:调用以确定拦截器的优先级,优先级越高,拦截器越早被调用。

异常处理

如果您想对方法抛出的异常做出反应,您可以在后缀拦截器中检查该异常。

  • 检查 $instance->method()->threwException()
  • 获取异常(如果没有抛出异常则为 null)$instance->method()->getException()
  • 获取返回值(异常情况下为 null)$instance->method()->getReturnValue()

提前返回

  • 如果前缀拦截器返回一个设置有提前返回参数为 true 的响应,例如 Response($data, true),则方法不会执行,后缀拦截器也不会被调用。
  • 如果后缀拦截器返回一个设置有提前返回参数为 true 的响应,则在方法抛出异常的情况下不会抛出异常。

您可以创建自己的拦截器,或使用内置的拦截器。

处理器

处理器由拦截器用于管理基础设施代码。要使用内置的拦截器,您需要实现内置的处理器契约。

  • 所有处理器都需要实现 OpenClassrooms\ServiceProxy\Handler\Contract\AnnotationHandler
  • 每个处理器都必须有一个唯一名称,您可以使用 getName 方法返回它。
  • 每个处理器都必须返回 true 如果它是默认处理器,否则返回 false,您可以使用 isDefault 方法返回它。
  • 您不能通过注解使用两个具有相同名称的处理程序。
  • 您只能通过注解使用一个默认处理程序。
  • 如果您只有一个通过注解指定的处理程序,它将默认使用。

示例

use OpenClassrooms\ServiceProxy\Annotation\Cache;

/**
 * @Cache(handler="in_memory")
 * to select the in_memory handler
 */

用法

实例化

Symfony

查看 ServiceProxyBundle。该组件为该库提供了一种易于配置的选项。

手册

示例

首先实现处理程序

use OpenClassrooms\ServiceProxy\Handler\Contract\CacheHandler;

class InMemoryCacheHandler implements CacheHandler
{
    public function getName(): string
    {
        return 'in_memory';
    }
    ...
}

class RedisCacheHandler implements CacheHandler
{
    public function getName(): string
    {
        return 'redis';
    }
    ...
}

然后您可以注入处理程序到拦截器中

$cacheInterceptor = new CacheInterceptor([new ArrayCacheHandler(), new RedisCacheHandler()]);
$prefixInterceptors = [
    $cacheInterceptor,
    new EventInterceptor([/* event handlers */]),
    new TransactionInterceptor([/* transaction handlers */]),
    new SecurityInterceptor([/* security handlers */]),
];

$suffixInterceptors = [
    $cacheInterceptor,
    new EventInterceptor(),
    new TransactionInterceptor(),
];

$serviceProxyFactory = new ProxyFactory(
    new Configuration(), //if no proxies directory is provided, the system tmp dir is used
    $prefixInterceptors,
    $SecurityInterceptor,
);
$proxy = $serviceProxyFactory->createProxy(new Class());

内置拦截器

确认

这个库基于 Ocramius\ProxyManager