Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
guanguans opened this issue Aug 24, 2022 · 0 comments
Open

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

guanguans opened this issue Aug 24, 2022 · 0 comments
Labels
2022 2022 Design Pattern Design Pattern Laravel Laravel PHP PHP

Comments

@guanguans
Copy link
Owner

guanguans commented Aug 24, 2022

laravel-proxy-manager - Laravel 应用中快速的创建不同类型的代理

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 |
+-------+---------------------------+-------------------------------------------+---------------------------------+

参考链接

原文链接

@guanguans guanguans changed the title laravel-proxy-manager - 快速的创建不同类型的代理实例 Laravel 应用中快速的创建不同类型的代理实例 Aug 24, 2022
@guanguans guanguans added PHP PHP Laravel Laravel labels Aug 24, 2022
@guanguans guanguans changed the title Laravel 应用中快速的创建不同类型的代理实例 Laravel 应用中快速的创建不同类型的代理 Aug 24, 2022
@guanguans guanguans added the Design Pattern Design Pattern label Aug 24, 2022
@guanguans guanguans added the 2022 2022 label Nov 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2022 2022 Design Pattern Design Pattern Laravel Laravel PHP PHP
Projects
None yet
Development

No branches or pull requests

1 participant