title: Annotation meta:

  • name: description content: Easyswoole提供了一个轻量级的注解解析工具
  • name: keywords content: swoole|swoole extension|swoole framework|EasySwoole|Annotation

Annotation

Easyswoole provides a lightweight annotation resolution tool.

The installation

  1. composer require easyswoole/annotation

Implementation principle

  • convention
    • Each annotation behavior starts with the @ character and is formatted as @METHOD(ARGS)
  • The execution process is as follows:
    • Use PHP reflection to get comment information
    • Explode and explode each line with PHP_EOL
    • Parse the data of each line. If the corresponding METHOD AnnotationTagInterface exists, pass the parsed ARGS to the assetValue METHOD in the AnnotationTagInterface. The user can perform custom parsing of the parsed values in this method.
    • In strict mode, an error is reported if the correct value cannot be resolved.

example

  1. <?php
  2. use EasySwoole\Annotation\Annotation;
  3. use EasySwoole\Annotation\AbstractAnnotationTag;
  4. /*
  5. * Define the param rendering method
  6. */
  7. class param extends AbstractAnnotationTag
  8. {
  9. public function tagName(): string
  10. {
  11. return 'param';
  12. }
  13. public function assetValue(?string $raw)
  14. {
  15. $list = explode(',',$raw);
  16. foreach ($list as $item){
  17. parse_str($item,$ret);
  18. foreach ($ret as $key => $value){
  19. $this->$key = trim($value," \t\n\r\0\x0B\"\'");
  20. }
  21. }
  22. }
  23. }
  24. /*
  25. * Define the timeout rendering method
  26. */
  27. class timeout extends AbstractAnnotationTag
  28. {
  29. public $timeout;
  30. public function tagName(): string
  31. {
  32. return 'timeout';
  33. }
  34. public function assetValue(?string $raw)
  35. {
  36. $this->timeout = floatval($raw);
  37. }
  38. public function aliasMap(): array
  39. {
  40. return [
  41. static::class,
  42. "timeout_alias"
  43. ];
  44. }
  45. }
  46. class A
  47. {
  48. protected $a;
  49. /**
  50. * @param(name=a,type=string,value=2)
  51. * @param(name=b)
  52. * @timeout_Alias(0.5)
  53. * @fuck(easyswoole)
  54. * 这是我的其他说明啊啊啊啊啊
  55. */
  56. function test()
  57. {
  58. }
  59. }
  60. /**
  61. * Instantiate the renderer and register the rendering method to parse
  62. */
  63. $annotation = new Annotation();
  64. $ref = new \ReflectionClass(A::class);
  65. //Do not register fuck parsing
  66. $annotation->addParserTag(new param());
  67. $annotation->addParserTag(new timeout());
  68. $list = $annotation->getClassMethodAnnotation($ref->getMethod('test'));
  69. foreach ($list['param'] as $item){
  70. var_dump((array)$item);
  71. }
  72. foreach ($list['timeout'] as $item){
  73. var_dump((array)$item);
  74. }

::: warning
If @ exists in the first three characters of each comment line, it means that this behavior needs to parse the comment line. By default, it is in non-strict mode. Unregistered tag information will not be parsed. :::

Default annotation parsing tool

Easyswoole comes with a string parsing tool calledEasyswoole \Annotation\ValueParser, which supports unit testing in the following format

The code is shown in:

  1. namespace EasySwoole\Annotation\Tests;
  2. use EasySwoole\Annotation\ValueParser;
  3. use PHPUnit\Framework\TestCase;
  4. class ValueParserTest extends TestCase
  5. {
  6. function testNormal()
  7. {
  8. $str = "int=1";
  9. $this->assertEquals([
  10. 'int'=>"1"
  11. ],ValueParser::parser($str));
  12. $str = "int=1,int2=2";
  13. $this->assertEquals([
  14. 'int'=>"1",
  15. 'int2'=>"2"
  16. ],ValueParser::parser($str));
  17. $str = "int=1,int2='2'";
  18. $this->assertEquals([
  19. 'int'=>"1",
  20. 'int2'=>"2"
  21. ],ValueParser::parser($str));
  22. }
  23. function testArray()
  24. {
  25. $str = "array={1,2,3}";
  26. $this->assertEquals([
  27. 'array'=>['1','2','3']
  28. ],ValueParser::parser($str));
  29. $str = "array={'1','2','3'}";
  30. $this->assertEquals([
  31. 'array'=>['1','2','3']
  32. ],ValueParser::parser($str));
  33. $str = "array={'1','2 , 3'}";
  34. $this->assertEquals([
  35. 'array'=>['1','2 , 3']
  36. ],ValueParser::parser($str));
  37. $str = 'array={"1","2","3"}';
  38. $this->assertEquals([
  39. 'array'=>['1','2','3']
  40. ],ValueParser::parser($str));
  41. $str = "array={1,2,3} ,array2={4,5,6}";
  42. $this->assertEquals([
  43. 'array'=>['1','2','3'],
  44. 'array2'=>['4','5','6']
  45. ],ValueParser::parser($str));
  46. }
  47. function testEval()
  48. {
  49. $str = 'time="eval(time() + 30)"';
  50. $this->assertEquals([
  51. 'time'=>time() + 30,
  52. ],ValueParser::parser($str));
  53. $str = 'time="eval(time() + 30)" , time2="eval(time() + 31)';
  54. $this->assertEquals([
  55. 'time'=>time() + 30,
  56. 'time2'=>time() + 31
  57. ],ValueParser::parser($str));
  58. $str = 'list="eval([1,2,3,4])"';
  59. $this->assertEquals([
  60. 'list'=>[1,2,3,4]
  61. ],ValueParser::parser($str));
  62. }
  63. function testArrayAndEval()
  64. {
  65. $str = 'array="{"1","2",eval(time() + 30)}"';
  66. $this->assertEquals([
  67. 'array'=>['1','2',time() + 30]
  68. ],ValueParser::parser($str));
  69. $str = 'array={"1","2",eval(time() + 30)},str="222"';
  70. $this->assertEquals([
  71. 'array'=>['1','2',time() + 30],
  72. "str"=>'222'
  73. ],ValueParser::parser($str));
  74. $str = "array={1,2,3},time=eval(time())";
  75. $this->assertEquals([
  76. 'array'=>['1','2','3'],
  77. 'time'=>time()
  78. ],ValueParser::parser($str));
  79. }
  80. function testStrMulti()
  81. {
  82. $str = 'mix="first|{1,2,3}|eval(time() + 3)"';
  83. $this->assertEquals([
  84. 'mix'=>['first',['1','2','3'],time() + 3]
  85. ],ValueParser::parser($str));
  86. }
  87. }

IDE support

PHPStorm needs to install the “PHP Annotation” plug-in to provide Annotation autoprompt capability. The plug-in can be searched and installed directly in PHPStorm or downloaded and installed on Github

::: warning https://github.com/Haehnchen/idea-php-annotation-plugin :::

Then write one of the following Annotation prompt classes yourself, the focus is to use the @annotation class Annotation, mark this is an Annotation prompt class, PHPStorm index to this file, you can annotate the class name and class members

  1. <?php
  2. namespace EasySwoole\Validate;
  3. /**
  4. * Annotated document
  5. * @Annotation
  6. * You need to use the Annotation tag up here which is an Annotation prompt class
  7. */
  8. final class ValidateRule
  9. {
  10. /**
  11. * These fields are prompted in parentheses
  12. * @var string
  13. */
  14. protected $name;
  15. /**
  16. * These fields are prompted in parentheses
  17. * @var string
  18. */
  19. protected $column;
  20. /**
  21. * These fields are prompted in parentheses
  22. * @var string
  23. */
  24. protected $alias;
  25. }

You can implement the following aaa method automatic annotation prompt

  1. <?php
  2. use EasySwoole\Validate as Validate;
  3. class a
  4. {
  5. /**
  6. * @Validate\ValidateRule(column="name",alias="The name of the account")
  7. */
  8. function aaa(){
  9. }
  10. }