jmacedo / php-simple-annotation
PHP 注解实现的一个简单直接且没有复杂性的方案。
2.0.1
2020-08-17 19:58 UTC
Requires
- php: ^7.4
- ext-json: *
- ext-mbstring: *
Requires (Dev)
- phpunit/phpunit: ^9.3
This package is auto-updated.
Last update: 2024-09-18 13:09:45 UTC
README
PHP 注解实现的一个简单直接且没有复杂性的方案。
需求
- PHP >= 7.4.*
- ext-json
- ext-mbstring
安装
composer require jmacedo/php-simple-annotation
使用方法
以下类用于本文档的目的
namespace Examples; /** * Class MyAnnotatedClass * * @package Examples * @metadata {"PI": 3.14, "name": "The name", "genre": "The genre", "age": "The age"} * @PI 3.14 * @list ['item 1', 'item 2', 'item 3'] * @uselessClass true */ class MyAnnotatedClass { /** * @value 3.14 * @var double * @description Math constant */ const PI = 3.14; /** @var string */ public $name; /** @var string */ protected $genre; /** @var int */ private $age; /** * MyAnnotatedClass constructor. * * @param string $name * @param string $genre * @param int $age */ public function __construct(string $name = '', string $genre = '', int $age = 0) { $this->name = $name; $this->genre = $genre; $this->age = $age; } /** * A method that says "Hello!". * * @methodName sayHello * @emptyAnnotation */ public function sayHello() { echo 'Hello!'; } }
你可以通过两种方式实例化 Annotation 类
- 第一种
use SimpleAnnotation\Annotation; use Examples\MyAnnotatedClass; $annotation = new Annotation(MyAnnotatedClass::class); // Or $annotation = new Annotation('Examples\MyAnnotatedClass');
- 第二种
use SimpleAnnotation\Annotation; use Examples\MyAnnotatedClass; $myAnnotatedClass = new MyAnnotatedClass(); $annotation = new Annotation($myAnnotatedClass);
获取类的注解
$classAnnotations = $annotation->getClassAnnotations(); var_dump($classAnnotations);
object(SimpleAnnotation\AnnotationParsed)[6]
private 'properties' =>
array (size=6)
'package' => string 'Examples' (length=8)
'metadata' =>
object(stdClass)[5]
public 'PI' => float 3.14
public 'name' => string 'The name' (length=8)
public 'genre' => string 'The genre' (length=9)
public 'age' => string 'The age' (length=7)
'PI' => float 3.14
'list' =>
array (size=3)
0 => string 'item 1' (length=6)
1 => string 'item 2' (length=6)
2 => string 'item 3' (length=6)
'uselessClass' => boolean true
'anotherStringValue' => string 'my string' (length=9)
AnnotationParsed 类实现了 __get 和 __set 魔法方法,因此要访问注解键,只需访问属性即可
echo "PI value is:" . $classAnnotations->PI; echo "PI is also available in: " . $classAnnotations->metadata->PI;
获取方法的注解
$methodsAnnotations = $annotation->getMethodsAnnotations(); var_dump($methodsAnnotations);
array (size=2)
'__construct' =>
object(SimpleAnnotation\AnnotationParsed)[9]
private 'properties' =>
array (size=1)
'param' =>
array (size=3)
0 => string 'string $name' (length=12)
1 => string 'string $genre' (length=13)
2 => string 'int $age' (length=8)
'sayHello' =>
object(SimpleAnnotation\AnnotationParsed)[10]
private 'properties' =>
array (size=2)
'methodName' => string 'sayHello' (length=8)
'emptyAnnotation' => boolean true
对于特定方法
$sayHelloAnnotations = $annotation->getMethodAnnotations('sayHello'); var_dump($sayHelloAnnotations);
object(SimpleAnnotation\AnnotationParsed)[11]
private 'properties' =>
array (size=2)
'methodName' => string 'sayHello' (length=8)
'emptyAnnotation' => boolean true
获取属性的注解
$propertiesAnnotations = $annotation->getPropertiesAnnotations(); var_dump($propertiesAnnotations);
array (size=3)
'name' =>
object(SimpleAnnotation\AnnotationParsed)[12]
private 'properties' =>
array (size=1)
'var' => string 'string' (length=6)
'genre' =>
object(SimpleAnnotation\AnnotationParsed)[13]
private 'properties' =>
array (size=1)
'var' => string 'string' (length=6)
'age' =>
object(SimpleAnnotation\AnnotationParsed)[14]
private 'properties' =>
array (size=1)
'var' => string 'int' (length=3)
对于特定属性
$nameAnnotations = $annotation->getPropertyAnnotations('name'); var_dump($nameAnnotations);
object(SimpleAnnotation\AnnotationParsed)[7]
private 'properties' =>
array (size=1)
'var' => string 'string' (length=6)
就是这样
只需实例化 SimpleAnnotation\Annotation 类,调用方法,并使用你想要的类的注解值。
缓存
默认情况下,没有使用缓存,但有一个可用的缓存处理器,如果你需要的话
此缓存处理器使用文件方法,在我的某些简单基准测试中效果良好
$annotation = new Annotation(MyAnnotatedClass::class); $start = microtime(true); for ($i = 0; $i < $numberOfTimes; $i++) { $classAnnotation = $annotation->getClassAnnotations(); $methodsAnnotations = $annotation->getMethodsAnnotations(); $propertiesAnnotations = $annotation->getPropertiesAnnotations(); } $end = microtime(true); echo 'Time elapsed without cache: ' . ($end - $start) . "\n"; $cache = new SimpleAnnotation\Concerns\Cache\FileCache(__DIR__ . DIRECTORY_SEPARATOR . 'test.txt'); $annotation2 = new Annotation(MyAnnotatedClass::class, $cache); $start2 = microtime(true); for ($i = 0; $i < $numberOfTimes; $i++) { $classAnnotation = $annotation2->getClassAnnotations(); $methodsAnnotations = $annotation2->getMethodsAnnotations(); $propertiesAnnotations = $annotation2->getPropertiesAnnotations(); } $end2 = microtime(true); echo 'Time elapsed with cache: ' . ($end2 - $start2) . "\n";
对于 $numberOfTimes=100
Time elapsed without cache: 0.011738777160645 Time elapsed with cache: 0.00053501129150391
对于 $numberOfTimes=10000
Time elapsed without cache: 1.1012320518494 Time elapsed with cache: 0.055597066879272
对于 $numberOfTimes=100000
Time elapsed without cache: 11.216305971146 Time elapsed with cache: 0.53948402404785
SimpleAnnotation\Concerns\ParsedAnnotation 的具体实现必须实现 JsonSerializable 接口,以便 SimpleAnnotation\Concerns\Cache\FileCache 的实现能正常工作。
如果你使用此库的默认实现,你不必担心这一点。