dealroadshow / proximity
允许创建PHP代理对象的库
dev-main
2023-11-19 23:15 UTC
Requires
- php: >=8.2
- nette/php-generator: ^4.0
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'; }