跳至正文
-
关注
IT极限技术分享汇

ITmax

IT极限技术分享汇

ITmax

  • 首页
  • 商店
  • 我的帐户
  • 结账
  • 购物车
  • 首页
  • 商店
  • 我的帐户
  • 结账
  • 购物车
关

搜索

Laravel 应用中快速的创建不同类型的代理

作者
2022年8月24日 3 分钟阅读
0

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);

代理管理器门面方法

<?php

namespace 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{}

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

<?php

namespace 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

https://segmentfault.com/a/1190000042369392

作者

关注我
其他文章
上一个

Golang 中变量定义的坑

下一个

Reactor 之 多任务并发执行,结果按顺序返回第一个

暂无评论!成为第一个。

发表回复 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Copyright 2026 — IT极限技术分享汇. 备案号:浙ICP备17006560号-2