| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- <?php
- use Illuminate\Support\Traits\ReflectsClosures;
- if (! function_exists('lazy')) {
- /**
- * Create a lazy instance.
- *
- * @template TValue of object
- *
- * @param class-string<TValue>|(\Closure(TValue): mixed) $class
- * @param (\Closure(TValue): mixed)|int $callback
- * @param int $options
- * @param array<string, mixed> $eager
- * @return TValue
- */
- function lazy($class, $callback = 0, $options = 0, $eager = [])
- {
- static $closureReflector;
- $closureReflector ??= new class
- {
- use ReflectsClosures;
- public function typeFromParameter($callback)
- {
- return $this->firstClosureParameterType($callback);
- }
- };
- [$class, $callback, $options] = is_string($class)
- ? [$class, $callback, $options]
- : [$closureReflector->typeFromParameter($class), $class, $callback ?: $options];
- $reflectionClass = new ReflectionClass($class);
- $instance = $reflectionClass->newLazyGhost(function ($instance) use ($callback) {
- $result = $callback($instance);
- if (is_array($result)) {
- $instance->__construct(...$result);
- }
- }, $options);
- foreach ($eager as $property => $value) {
- $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($instance, $value);
- }
- return $instance;
- }
- }
- if (! function_exists('proxy')) {
- /**
- * Create a lazy proxy instance.
- *
- * @template TValue of object
- *
- * @param class-string<TValue>|(\Closure(TValue): TValue) $class
- * @param (\Closure(TValue): TValue)|int $callback
- * @param int $options
- * @param array<string, mixed> $eager
- * @return TValue
- */
- function proxy($class, $callback = 0, $options = 0, $eager = [])
- {
- static $closureReflector;
- $closureReflector = new class
- {
- use ReflectsClosures;
- public function get($callback)
- {
- return $this->closureReturnTypes($callback)[0] ?? $this->firstClosureParameterType($callback);
- }
- };
- [$class, $callback, $options] = is_string($class)
- ? [$class, $callback, $options]
- : [$closureReflector->get($class), $class, $callback ?: $options];
- $reflectionClass = new ReflectionClass($class);
- $proxy = $reflectionClass->newLazyProxy(function () use ($callback, $eager, &$proxy) {
- $instance = $callback($proxy, $eager);
- return $instance;
- }, $options);
- foreach ($eager as $property => $value) {
- $reflectionClass->getProperty($property)->setRawValueWithoutLazyInitialization($proxy, $value);
- }
- return $proxy;
- }
- }
|