ProceedingJoinPoint.php 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Di\Aop;
  12. use Closure;
  13. use Hyperf\Di\Annotation\AnnotationCollector;
  14. use Hyperf\Di\Exception\Exception;
  15. use Hyperf\Di\ReflectionManager;
  16. use ReflectionFunction;
  17. use ReflectionMethod;
  18. class ProceedingJoinPoint
  19. {
  20. public mixed $result;
  21. public ?Closure $pipe = null;
  22. public function __construct(
  23. public Closure $originalMethod,
  24. public string $className,
  25. public string $methodName,
  26. public array $arguments
  27. ) {
  28. }
  29. /**
  30. * Delegate to the next aspect.
  31. */
  32. public function process()
  33. {
  34. $closure = $this->pipe;
  35. if (! $closure instanceof Closure) {
  36. throw new Exception('The pipe is not instanceof \Closure');
  37. }
  38. return $closure($this);
  39. }
  40. /**
  41. * Process the original method, this method should trigger by pipeline.
  42. */
  43. public function processOriginalMethod()
  44. {
  45. $this->pipe = null;
  46. $closure = $this->originalMethod;
  47. $arguments = $this->getArguments();
  48. return $closure(...$arguments);
  49. }
  50. public function getAnnotationMetadata(): AnnotationMetadata
  51. {
  52. $metadata = AnnotationCollector::get($this->className);
  53. return new AnnotationMetadata($metadata['_c'] ?? [], $metadata['_m'][$this->methodName] ?? []);
  54. }
  55. public function getArguments(): array
  56. {
  57. $result = [];
  58. foreach ($this->arguments['order'] ?? [] as $order) {
  59. $result[] = $this->arguments['keys'][$order];
  60. }
  61. // Variable arguments are always placed at the end.
  62. if (isset($this->arguments['variadic'], $order) && $order === $this->arguments['variadic']) {
  63. $variadic = array_pop($result);
  64. $result = array_merge($result, $variadic);
  65. }
  66. return $result;
  67. }
  68. public function getReflectMethod(): ReflectionMethod
  69. {
  70. return ReflectionManager::reflectMethod(
  71. $this->className,
  72. $this->methodName
  73. );
  74. }
  75. public function getInstance(): ?object
  76. {
  77. $ref = new ReflectionFunction($this->originalMethod);
  78. return $ref->getClosureThis();
  79. }
  80. }