laravel-proxy-manager - 集成 Ocramius/ProxyManager 到 Laravel 利用。

性能

  • 疾速创立不同类型的代理实例。
  • 疾速绑定不同类型的代理实例到容器。
  • 疾速扩大为不同类型的代理实例到容器。

装置

$ composer require guanguans/laravel-proxy-manager -vvv
$ php artisan vendor:publish --provider="Guanguans\\LaravelProxyManager\\ProxyManagerServiceProvider"

应用

获取代理管理器实例

app(\Guanguans\LaravelProxyManager\ProxyManager::class);resolve(\Guanguans\LaravelProxyManager\ProxyManager::class);

代理管理器门面办法

<?phpnamespace Guanguans\LaravelProxyManager\Facades;/** * 创立代理 * @method static \ProxyManager\Proxy\AccessInterceptorInterface            createAccessInterceptorScopeLocalizerProxy(object $instance, array $prefixInterceptors = [], array $suffixInterceptors = []) * @method static \ProxyManager\Proxy\AccessInterceptorValueHolderInterface createAccessInterceptorValueHolderProxy(object $instance, array $prefixInterceptors = [], array $suffixInterceptors = []) * @method static \ProxyManager\Proxy\GhostObjectInterface                  createLazyLoadingGhostFactoryProxy(string $className, \Closure $initializer, array $proxyOptions = []) * @method static \ProxyManager\Proxy\VirtualProxyInterface                 createLazyLoadingValueHolderProxy(string $className, \Closure $initializer, array $proxyOptions = []) * @method static \ProxyManager\Proxy\NullObjectInterface                   createNullObjectProxy($instanceOrClassName) * @method static \ProxyManager\Proxy\RemoteObjectInterface                 createRemoteObjectProxy($instanceOrClassName, ?\ProxyManager\Factory\RemoteObject\AdapterInterface $adapter = null) * * 绑定代理 * @method static void                                                      singletonLazyLoadingValueHolderProxy(string $className, ?\Closure $concrete = null) * @method static void                                                      bindLazyLoadingValueHolderProxy(string $className, ?\Closure $concrete = null, bool $shared = false) * @method static void                                                      singletonNullObjectProxy(string $className) * @method static void                                                      bindNullObjectProxy(string $className, bool $shared = false) * @method static void                                                      singletonRemoteObjectProxy(string $className, ?\ProxyManager\Factory\RemoteObject\AdapterInterface $adapter = null) * @method static void                                                      bindRemoteObjectProxy(string $className, ?\ProxyManager\Factory\RemoteObject\AdapterInterface $adapter = null, bool $shared = false) *  * 扩大为代理 * @method static void                                                      extendToAccessInterceptorScopeLocalizerProxy(string $abstract, array $prefixInterceptors = [], array $suffixInterceptors = []) * @method static void                                                      extendToAccessInterceptorValueHolderProxy(string $abstract, array $prefixInterceptors = [], array $suffixInterceptors = []) * @method static void                                                      extendToLazyLoadingGhostFactoryProxy(string $abstract, \Closure $initializer, array $proxyOptions = []) * @method static void                                                      extendToLazyLoadingValueHolderProxy(string $abstract, \Closure $initializer, array $proxyOptions = []) * @method static void                                                      extendToNullObjectProxy(string $abstract) * @method static void                                                      extendToRemoteObjectProxy(string $abstract, ?\ProxyManager\Factory\RemoteObject\AdapterInterface $adapter = null) * * @see \Guanguans\LaravelProxyManager\ProxyManager */class ProxyManager{}

绑定虚构代理示例(懒初始化)

<?phpnamespace App;use App\Foo;use Guanguans\LaravelProxyManager\Facades\ProxyManager;use SebastianBergmann\Timer\ResourceUsageFormatter;use SebastianBergmann\Timer\Timer;class Foo{    /** @var string */    private $bar;    public function __construct(string $bar = 'bar')    {        $this->bar = $bar;        sleep(3);    }    public function getBar(): string    {        return $this->bar;    }}// ProxyManager::bindLazyLoadingValueHolderProxy(Foo::class);ProxyManager::singletonLazyLoadingValueHolderProxy(Foo::class);$formatter = new ResourceUsageFormatter();$timer = new Timer();$timer->start();$timer->start();// 初始代理类时不会调用原类的构造函数dump($foo = app(Foo::class), $formatter->resourceUsage($timer->stop()));// 当真正调用时才会调用原类的构造函数dump($foo->getBar(), $formatter->resourceUsage($timer->stop()));
ProxyManagerGeneratedProxy\__PM__\App\Foo\Generated5320f6306ba550844e07c949e4af382d - App\Foo@proxy {#774  -valueHolder1cdad: null  -initializer7920c: Closure(?object &$wrappedObject, ?object $proxy, string $method, array $parameters, ?Closure &$initializer) {#758    class: "Guanguans\LaravelProxyManager\ProxyManager"    this: Guanguans\LaravelProxyManager\ProxyManager {#755 …}    use: {      $className: "App\Foo"      $classArgs: []    }    file: "/Users/yaozm/Documents/develop/laravel-proxy-manager/src/ProxyManager.php"    line: "282 to 287"  }}"Time: 00:00.008, Memory: 20.00 MB""bar""Time: 00:03.025, Memory: 22.00 MB"

扩大为拜访拦截器代理示例(切面)

ProxyManager::extendToAccessInterceptorValueHolderProxy(    LogManager::class,    [        'error' => static function (            object $proxy,            LogManager $realInstance,            string $method,            array $parameters,            bool &$returnEarly        ){            dump('Before executing the error log method.');        }    ],    [        'error' => static function (            object $proxy,            LogManager $realInstance,            string $method,            array $parameters,            &$returnValue,            bool &$overrideReturnValue        ){            dump('After executing the error log method.');        }    ]);dump($logger = app(LogManager::class));$logger->error('What happened?');
ProxyManagerGeneratedProxy\__PM__\Illuminate\Log\LogManager\Generated9b66c8f3bc457c2c26acc55874d391b3 - Illuminate\Log\LogManager@proxy {#298 ▼  -valueHolder8f21a: Illuminate\Log\LogManager {#168 ▼    #app: Illuminate\Foundation\Application {#6 ▶}    #channels: []    #customCreators: array:1 [▶]    #dateFormat: "Y-m-d H:i:s"    #levels: array:8 [▶]  }  -methodPrefixInterceptors8d709: array:1 [▼    "error" => Closure(object $proxy, LogManager $realInstance, string $method, array $parameters, bool &$returnEarly) {#280 ▶}  ]  -methodSuffixInterceptors2a12b: array:1 [▼    "error" => Closure(object $proxy, LogManager $realInstance, string $method, array $parameters, &$returnValue, bool &$overrideReturnValue) {#278 ▶}  ]}"Before executing the error log method.""After executing the error log method."

命令

$ php artisan proxy:list$ php artisan proxy:clear
╰─ php artisan proxy:list                                                                                       ─╯+-------+---------------------------+-------------------------------------------+---------------------------------+| Index | Original Class            | Proxy Class                               | Proxy Type                      |+-------+---------------------------+-------------------------------------------+---------------------------------+| 1     | App\Foo                   | Generated5320f6306ba550844e07c949e4af382d | Virtual Proxy                   || 2     | Illuminate\Log\LogManager | Generated9b66c8f3bc457c2c26acc55874d391b3 | Access Interceptor Value Holder |+-------+---------------------------+-------------------------------------------+---------------------------------+

参考链接

  • https://github.com/Ocramius/ProxyManager
  • https://www.sitepoint.com/restful-remote-object-proxies-with-proxymanager/

原文链接

  • https://github.com/guanguans/guanguans.github.io/issues/48