guanguans/laravel-proxy-manager

Proxy Manager integration for Laravel. - Laravel ็š„ไปฃ็†็ฎก็†ๅ™จ้›†ๆˆใ€‚

Maintainers

๐Ÿ‘ guanguans

Package info

github.com/guanguans/laravel-proxy-manager

pkg:composer/guanguans/laravel-proxy-manager

Fund package maintenance!

Wechat

Statistics

Installs: 20

Dependents: 0

Suggesters: 0

Stars: 4

Open Issues: 0

1.2.0 2024-03-13 09:20 UTC

Requires

Suggests

Provides

None

Conflicts

None

Replaces

None

MIT 07dd223529e227f17ec213f8875344d1efdbb420

aopproxylaravelproxy patternservice proxieslazy loading


README

็ฎ€ไฝ“ไธญๆ–‡ | ENGLISH

Proxy Manager integration for Laravel. - Laravel ็š„ไปฃ็†็ฎก็†ๅ™จ้›†ๆˆใ€‚

๐Ÿ‘ tests
๐Ÿ‘ check & fix styling
๐Ÿ‘ codecov
๐Ÿ‘ Latest Stable Version
๐Ÿ‘ Total Downloads
๐Ÿ‘ License
๐Ÿ‘ GitHub release (latest by date)

Feature

  • Quickly create different types of proxy instances.
  • Quickly bind different types of proxy instances to container.
  • Quickly extend to different types of proxy instances to container.

Requirement

  • PHP >= 7.4
  • Laravel >= 7.0

Installation

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

Usage

test examples

Get proxy manager instance

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

Proxy manager facade methods

<?php

namespace Guanguans\LaravelProxyManager\Facades;

/**
 * Create proxy.
 * @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)
 * 
 * Bind proxy.
 * @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)
 *
 * Extend to proxy.
 * @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{}

Binding virtual proxy example(Lazy Init)

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

// The constructor of the original class is not triggered when the proxy class is initialized
dump($foo = app(Foo::class), $formatter->resourceUsage($timer->stop()));
// The constructor of the original class will only be triggered when it is actually called
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"

Extend to access interceptor value holder proxy example(Aop)

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."

Commands

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

Testing

$ composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.