dealroadshow/proximity

允许创建PHP代理对象的库

dev-main 2023-11-19 23:15 UTC

This package is auto-updated.

Last update: 2024-09-20 01:02:29 UTC


README

动机

这个库受到了杰出的 Ocramius/ProxyManager 库的启发。目前提到的库缺少一些功能,例如无法从具有非空类型属性的类实例创建代理。不幸的是,这个优秀的库没有得到积极的支持,因此 dealroadshow/proximity 库试图实现一些 ProxyManager 的功能。

用法

您可以通过使用 ProxyFactory 类轻松创建代理实例

<?php

$factory = new \Dealroadshow\Proximity\ProxyFactory(
    new \Dealroadshow\Proximity\ProxyGenerator(),
    '/path/where/proxy/classes/will/be/stored'
);

$myObject = new Foo();
$proxy = $factory->proxy($myObject);

您可能还希望在方法体执行前后拦截对对象方法的调用。为了做到这一点,请使用 拦截器

use Dealroadshow\Proximity\ProxyFactory;
use Dealroadshow\Proximity\ProxyGenerator;
use Dealroadshow\Proximity\MethodsInterception\BodyInterceptorInterface;
use Dealroadshow\Proximity\ProxyInterface;
use Dealroadshow\Proximity\MethodsInterception\BodyInterceptionResult;
use Dealroadshow\Proximity\ProxyOptions;
use Dealroadshow\Proximity\MethodsInterception\ResultInterceptorInterface;
use Dealroadshow\Proximity\MethodsInterception\InterceptionContext;

class Foo
{
    public function bar(): void
    {
        echo 'Bar!', PHP_EOL;
    }
}

$factory = new ProxyFactory(
    new ProxyGenerator(),
    '/path/where/proxy/classes/will/be/stored'
);

$bodyInterceptor = new class implements BodyInterceptorInterface 
{
    public function beforeMethodBody(ProxyInterface $proxy, object $object, string $methodName, array $methodArgs) : BodyInterceptionResult
    {
        echo "Method $methodName() is about to be executed!\n";
        
        return new BodyInterceptionResult(preventMethodBody: false);
    }
};

$resultInterceptor = new class implements ResultInterceptorInterface
{
    public function afterMethodBody(ProxyInterface $proxy, object $object, string $methodName, array $methodArgs, InterceptionContext $context): void
    {
        echo "Method $methodName() just finished execution!\n";
    }
};

$foo = new Foo();
$proxy = $factory->proxy(
    $foo,
    new ProxyOptions(
        ['bar' => [$bodyInterceptor]],
        ['bar' => [$resultInterceptor]],
    )
);

$proxy->bar();

以下将生成输出

Method bar() is about to be executed!
Bar!
Method bar() just finished execution!

您也可以通过将 true 作为第一个参数传递给 BodyInterceptionResult 构造函数来防止从 body interceptors 执行方法体。如果您阻止了体执行,您还可以通过将返回值作为第二个参数传递给 BodyInterceptionResult 构造函数来为该方法提供返回值。

要使用 $context 参数从 result interceptors 替换方法返回值,请使用 $context 参数

public function afterMethodBody(ProxyInterface $proxy, object $object, string $methodName, array $methodArgs, InterceptionContext $context): void
{
    // do some stuff, then:
    $context->returnValue = 'New value';
}