adiletmaks/annotations

KISS PHP 注解库

4.0.0 2021-07-20 06:05 UTC

README

Build Status Coverage Status Scrutinizer Code Quality Latest Stable Version Total Downloads Reference Status License SensioLabsInsight

Minime\Annotations 是第一个 KISS PHP 注解库。

Composer 安装

{
  "require": {
    "minime/annotations": "~3.0"
  }
}

通过终端:composer require minime/annotations:~3.0 🎱

设置

首先以最简单的方式获取 Minime\Annotations\Reader 的实例

$reader = \Minime\Annotations\Reader::createFromDefaults();

或者使用以下方式自行实例化注解读取器

use Minime\Annotations\Reader;
use Minime\Annotations\Parser;
use Minime\Annotations\Cache\ArrayCache;

$reader = new Reader(new Parser, new ArrayCache);

注意,Reader::createFromDefaults() 创建的读取器实例启用了数组缓存。在生产环境中,您可能希望使用像 FileCache 这样的持久化缓存处理器

use Minime\Annotations\Cache\FileCache;

$reader->setCache(new FileCache('app/storage/path'));

读取注解

考虑以下具有一些文档块注解的类

<?php
/**
 * @name Foo
 * @accept ["json", "xml", "csv"]
 * @delta .60
 * @cache-duration 60
 */
class FooController
{
    /**
     * @manages Models\Baz
     */
    protected $repository;

    /**
     * @get @post
     * @redirect Controllers\BarController@index
     */
    public function index(){}
}

让我们使用 Minime\Annotations\Reader 实例从类、属性和方法中读取注解。如下所示

$annotations = $reader->getClassAnnotations('FooController');

$annotations->get('name')     // > string(3) "Foo"
$annotations->get('accept')   // > array(3){ [0] => "json" [1] => "xml" [2] => "csv" }
$annotations->get('delta')           // > double(0.60)
$annotations->get('cache-duration')  // > int(60)

$annotations->get('undefined')  // > null

同样适用于类属性...

$annotations = $reader->getPropertyAnnotations('FooController', 'repository');
$annotations->get('manages')   // > string(10) "Models\Baz"

方法...

$annotations = $reader->getMethodAnnotations('FooController', 'index');
$annotations->get('get')   // > bool(true)
$annotations->get('post')   // > bool(true)
$annotations->get('auto-redirect')   // > string(19) "BarController@index"

以及函数 || 闭包

/** @name Foo */ function foo(){}
$annotations = $reader->getFunctionAnnotations('foo');
$annotations->get('name')   // > string(3) "Foo"

管理注解

注解读取器 Reader::get(*)Annotations 总是返回 AnnotationsBag 实例,因此您可以轻松管理注解

/**
 * @response.xml
 * @response.xls
 * @response.json
 * @response.csv
 * @method.get
 * @method.post
 */
class Foo {}

$annotations = $reader->getClassAnnotations('Foo'); // object<AnnotationsBag>

命名空间

将属于包的自定义注解命名空间是一个好主意。以后,您可以使用 AnnotationsBag api检索所有这些命名空间注解

$AnnotationsBag->useNamespace('response')->toArray();
// > array(3){
// >    ["xml"]  => (bool) TRUE,
// >    ["xls"]  => (bool) TRUE,
// >    ["json"] => (bool) TRUE,
// >    ["csv"]  => (bool) TRUE
// > }

管道过滤器

您还可以轻松地将过滤器“管道化”。这次,让我们“grep”所有以“x”开头并在“response”命名空间内的注解

$AnnotationsBag->useNamespace('response')->grep('/^x/')->toArray();
// > array(3){
// >    ["xml"]  => (bool) TRUE,
// >    ["xls"]  => (bool) TRUE
// > }

遍历结果

如你所料,AnnotationsBag 也是可遍历的

foreach($annotations->useNamespace('method') as $annotation => $value)
{
    // some behavior
}

并集

您还可以在两个注解集合之间执行并集操作

$annotations->union($defaultAnnotations);

有关更多信息,请参阅公共API

默认语法

@(<namespace><namespace-delimiter>)?<annotation-identifier> <type>? <value>?

基本上意味着

  • @ 行必须以文档块注解标签开头
  • 必须有一个注解标识符
    • 注解标识符可以有命名空间,命名空间段由 .\ 分隔
  • 空白
  • 可以有一个注解值
    • 值可以有一个可选的类型 [jsonstringintegerfloat->]
      • 如果不存在,则假定类型从值中提取
    • 空白
    • 可选值
      • 如果不存在,则假定值为 true

以下是一些有效示例

/**
 * Basic docblock showing syntax recognized by the default Minime\Annotations\Parser
 *
 * @implicit-boolean
 * @explicit-boolean true
 * @explicit-boolean false
 *
 * @implicit-string-annotation  hello world!
 * @explicit-string-annotation "hello world!"
 * @string-strong-typed-annotation string 123456
 *
 * @integer-annotation 15
 * @integer-strong-typed-annotation integer 15
 *
 * @float-annotation   0.15
 * @float-strong-typed float 15
 *
 * @json-annotation { "foo" : ["bar", "baz"] }
 * @strong-typed-json-annotation json ["I", "must", "be", "valid", "json"]
 * 
 * @namespaced.annotation hello!
 *
 * @multiline-json-annotation {
 *   "foo" : [
 *      "bar", "baz"
 *    ]
 * }
 *
 * @multiline-indented-string-annotation
 *   ------
 *   < moo >
 *   ------ 
 *         \   ^__^
 *          \  (oo)\_______
 *             (__)\       )\/\
 *                 ||----w |
 *                 ||     ||
 * 
 * @Concrete\Class\Based\Annotation -> { "foo" : ["bar"] }
 */

具体注解

有时您需要注解封装逻辑,而您只能通过将指令映射到正式的 PHP 类来实现。这些“具体”的类型注解可以使用 ->(箭头符号)声明

/**
 * @Model\Field\Validation -> {
 *     "rules" : {
 *         "required" : true,
 *         "max-length" : 100
 *     }
 * }
 */

在上面的示例中:当被提示时,注解解析器将根据声明的 JSON 原型 { "rules" : {...} } 实例化一个 new \Model\Field\Validation()。哇!瞬间变得优雅的注解。

缓存

此包附带两个基本的缓存处理器。 ArrayCache(用于测试)和一个非常简单的 FileCache 处理器用于持久性。缓存处理器可以在 Minime\Annotations\Reader 实例化时设置

use Minime\Annotations\Reader;
use Minime\Annotations\Parser;
use Minime\Annotations\Cache\FileCache;

$cacheHandler = new FileCache('storage/path');
$reader = new Reader(new Parser, $cacheHandler);

或稍后通过 Reader::setCache() 设置

$reader->setCache(new FileCache);

公共 API

Minime\Annotations\Reader

::getClassAnnotations($subject)

获取给定类的所有注解

$reader->getClassAnnotations('Full\Qualified\Class');

::getPropertyAnnotations($subject, $propertyName)

获取给定类属性的注解

$reader->getPropertyAnnotations('Full\Qualified\Class', 'propertyName');

::getMethodAnnotations($subject, $methodName)

获取给定类方法的所有注解

$reader->getMethodAnnotations('Full\Qualified\Class', 'methodName');

::getFunctionAnnotations($fn)

获取给定完全限定函数名或闭包的所有注解

$reader->getFunctionAnnotations('utils\foo');

::getCache()

::setCache(CacheInterface $cache)

::getParser()

::setParser(ParserInterface $cache)

Minime\Annotations\AnnotationsBag

::grep($pattern)

使用有效的正则表达式过滤注解并返回一个包含匹配结果的新 AnnotationBag

::useNamespace($pattern)

隔离指定的注解命名空间。基本来说,这个方法通过命名空间过滤注解,并返回一个新的带有简化注解标识符的 AnnotationBag 对象。

::union(AnnotationsBag $bag)

与指定的 AnnotationBag 执行并集操作

$annotations->union($defaultAnnotations);

::toArray()

::get($key, $default = null)

::getAsArray($key)

::has($key)

::set($key, $value)

::count

Minime\Annotations\Cache\FileCache

::__construct($storagePath = null)

参见与 Minime\Annotations\Reader 相关的示例

use Minime\Annotations\Cache\FileCache;

$reader->setCache(new FileCache('app/tmp/storage/path'));

如果没有给出路径,则假定操作系统临时目录为缓存存储路径。

::clear()

清除整个缓存。参见与 Minime\Annotations\Reader 相关的示例

$reader->getCache()->clear();

Minime\Annotations\Cache\ArrayCache

::clear()

清除整个缓存。参见与 Minime\Annotations\Reader 相关的示例

$reader->getCache()->clear();

贡献

发现了错误?有改进建议?请查看 问题

指南

  1. Fork minime\annotations
  2. 克隆分叉的仓库
  3. 安装 composer 依赖项 $ composer install
  4. 运行单元测试 $ phpunit
  5. 修改代码:修复错误,实现特性
  6. 回到步骤 4

版权

版权所有 (c) 2013-2014 Márcio Almada。根据 MIT 风格许可协议分发。有关详细信息,请参阅 LICENSE。