AnnotationReader.php 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  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\Constants;
  12. use BackedEnum;
  13. use Hyperf\Constants\Annotation\Message;
  14. use Hyperf\Stringable\Str;
  15. use ReflectionClassConstant;
  16. class AnnotationReader
  17. {
  18. /**
  19. * @param array<ReflectionClassConstant> $classConstants
  20. */
  21. public function getAnnotations(array $classConstants): array
  22. {
  23. $result = [];
  24. foreach ($classConstants as $classConstant) {
  25. $code = $classConstant->getValue();
  26. if ($classConstant->isEnumCase()) {
  27. $code = $code instanceof BackedEnum ? $code->value : $code->name;
  28. }
  29. $docComment = $classConstant->getDocComment();
  30. // Not support float and bool, because it will be convert to int.
  31. if ($docComment && (is_int($code) || is_string($code))) {
  32. $result[$code] = $this->parse($docComment, $result[$code] ?? []);
  33. }
  34. // Support PHP8 Attribute.
  35. foreach ($classConstant->getAttributes() as $ref) {
  36. $attribute = $ref->newInstance();
  37. if ($attribute instanceof Message) {
  38. $result[$code][$attribute->key] = $attribute->value;
  39. }
  40. }
  41. }
  42. return $result;
  43. }
  44. protected function parse(string $doc, array $previous): array
  45. {
  46. $pattern = '/@(\w+)\("(.+)"\)/U';
  47. if (preg_match_all($pattern, $doc, $result)) {
  48. if (isset($result[1], $result[2])) {
  49. $keys = $result[1];
  50. $values = $result[2];
  51. foreach ($keys as $i => $key) {
  52. if (isset($values[$i])) {
  53. $previous[Str::lower($key)] = $values[$i];
  54. }
  55. }
  56. }
  57. }
  58. return $previous;
  59. }
  60. }