minime/annotations

KISS PHP 注解库

3.1.0 2017-09-05 15:36 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。