eloquent/typhax

此包已被废弃且不再维护。未建议替换包。

灵活的PHP类型提示语法。

0.10.1 2015-11-13 00:53 UTC

README

灵活的PHP类型提示语法。

Current version image Current build status image Current coverage status image

安装和文档

什么是Typhax?

Typhax 是一种用于在参数类型提示中指定 PHP 类型的规范,以及任何需要以人类可读形式描述类型的场合。

它扩展了现有规范在指定类型要求方面的功能,例如在 PHP 文档 和 PHPDoc 的 @param 标签 中使用的规范。

除了标量和类类型提示之外,Typhax 还允许强大的功能,包括指定数组的键和值类型,以及使用布尔逻辑的复合类型(例如 integer|float)。

支持类型

数组

array
array<keyType,valueType>

一个 数组。键类型和值类型可以可选指定。请参阅下面的 可遍历类型 部分。

等同于 is_array() 函数。

布尔值

boolean

一个 布尔值 真或假。值必须是实际的布尔值,而不是等价的整数。

等同于 is_bool() 函数。

可调用

callable

用户定义的回调函数。这正好等同于 PHP 5.4 中引入的 callable 类型提示。

可调用可以是以下之一

  • 包含函数或静态类方法的名称的字符串。
  • 包含对象在索引 0 处和方法名称在索引 1 处的数组。
  • 包含类名称在索引 0 处和方法名称在索引 1 处的数组。
  • 匿名函数
  • 具有 __invoke() 方法的对象。
  • 调用 create_function() 的结果。

等同于 is_callable() 函数。

浮点数

float

一个 浮点数。值必须是真正的浮点数,而不是等价的字符串或整数。

等同于 is_float() 函数。

整数

integer

一个 整数。值必须是真正的整数,而不是等价的字符串、布尔值或任何其他类型的值。

等同于 is_int() 函数。

混合类型

mixed
mixed<keyType,valueType>

混合类型接受任何类型的任何值(包括 null)。

混合类型可以被视为 可遍历类型,如上面的第二个示例。当以这种方式使用时,混合类型表示任何可遍历的类型,例如一个 数组 或实现了 Traversable 接口的对象。这在值必须是集合,但外部类型不重要的情况下很有用。

空值

null

一个 null 值。

等同于 === null

对象

object
ClassName
ClassName<keyType,valueType>

第一个形式,object,表示一个属于任何类的 对象。这等同于 is_object() 函数。

第二个形式,ClassName,表示一个属于类 ClassName对象。这包括 ClassName 的实例、从 ClassName 扩展的类的实例以及实现了 ClassName 接口的对象实例。这等同于 instanceof 操作符。

第三个形式,ClassName<keyType,valueType>,遵循与第二个形式相同的规则,但增加了对象必须实现 Traversable 接口的要求。可以可选地指定键类型和值类型。请参阅下面的 可遍历类型 部分。

关于命名空间

命名空间解析应遵循与 PHP 源代码相同的规则。也就是说;如果类名在当前命名空间中,或者有相关的 use 语句,则可以使用简短的形式。

Cosmos 可以用于帮助在运行时解析类名。

资源

resource
resource{ofType:resourceType}

第一个形式,resource,表示一个属于任何类型的 资源。这等同于 is_resource() 函数。

第二个形式,resource{ofType:resourceType},表示一个返回与 get_resource_type() 传递的 'resourceType' 相等的字符串的 资源

stream
stream{readable:true,writable:true}
stream{readable:true,writable:false}
stream{readable:false,writable:true}

代表一个流资源。可读性(readable)和可写性(writable)属性决定了流模式的模式要求。

流类型等同于Typhax类型resource{ofType:stream}

有关更多信息,请参阅PHP文档中的fopen()关于流模式。

字符串

string

一个字符串。值必须是一个真正的字符串,而不是任何可以转换为字符串的其他类型。

等同于is_string()函数。

可转换为字符串的类型

stringable

代表任何可以转换为有用字符串表示的值的类型。这包括字符串、整数、浮点数和具有__toString()方法的对象。

数组、布尔值、null、资源以及没有__toString()方法的对象不满足“可转换为字符串”的条件。

元组

tuple<typeA,typeB,typeC,...>

一个元组是一个固定大小的数组值,其中每个元素都是特定类型的。

元组通常被称为一个n-元组,其中n是元素的数量。例如,一个定义了第一个元素为字符串、第二个元素为整数的2-元组看起来像tuple

元组数组必须是顺序的。也就是说,数组的键必须是整数,第一个键是0,后续键每个元素递增1。

例如,['foo', 1]满足tuple的约束。

旧类型

以下类型也已被实现,但被认为是过时的。它们主要存在是为了与PHP手册中使用的类型和伪类型保持兼容性,应努力避免使用它们。

  • bool = boolean
  • callback = callable
  • double = float
  • int = integer
  • long = integer
  • number = integer|float
  • numeric = 等同于is_numeric()
  • real = float
  • scalar = integer|float|string|boolean

可遍历类型

Typhax支持指定数组和可遍历对象的键和值类型。

键和值类型的规范如下

primaryType<keyType,valueType>

此规范表示一个类型为primaryType的值,当迭代时,产生类型为keyType的键和类型为valueType的值。

省略可遍历类型的键类型

keyType可以省略

primaryType<valueType>

此规范表示一个类型为primaryType的值,当迭代时,产生从0开始的**连续整数键**,和类型为valueType的值。

在不指定键和值类型的情况下使用array

对于array,键和值类型都可以省略

array

此规范等同于

array<mixed,mixed>

这意味着键和值可以是任何类型。

在可遍历类型中使用 mixed 作为主类型

可遍历类型可以指定 mixed 作为主类型

mixed<keyType,valueType>

此规范表示任何可以迭代、产生类型为 keyType 的键和类型为 valueType 的值的类型。

布尔类型逻辑

Typhax 支持类型规范中的布尔逻辑。有两个运算符,管道符号(|)表示布尔或,加号符号(+)表示布尔与。

此规范

typeA|typeB

表示类型可以是 typeA 类型或 typeB 类型。一个现实世界的例子可能是 integer|float,以接受整数或浮点数。

此规范

typeA+typeB

表示类型既是 typeA 类型又是 typeB 类型。一个现实世界的例子可能是 InterfaceA+InterfaceB,以只接受实现 InterfaceAInterfaceB 的对象。

扩展类型

:ClassName
:ClassName{attribute:value,...}
:ClassName<typeA,typeB,typeC,...>{attribute:value,...}

扩展提供了一种通过自定义逻辑来扩展 Typhax 功能的方法。

空白符

通常,Typhax 不关心类型规范中是否使用了空白符。然而,上述文档应作为推荐的风格指南。

用法

Typhax 包含一个类型表达式解析器,它生成解析类型语法树

use Eloquent\Typhax\Parser\TypeParser;
use Eloquent\Typhax\Renderer\CondensedTypeRenderer;

$parser = TypeParser::create();
$type = $parser->parse('primaryType<keyType,valueType>');

$renderer = CondensedTypeRenderer::create();
echo $renderer->render($type); // outputs 'primaryType<keyType,valueType>'

还包括一个比较器,用于确定两种类型是否等价

use Eloquent\Typhax\Comparator\TypeEquivalenceComparator;

$typeA = $parser->parse('integer|string');
$typeB = $parser->parse('string|integer');
$typeC = $parser->parse('string|integer|null');

$comparator = TypeEquivalenceComparator::create();
var_dump($comparator->isEquivalent($typeA, $typeB)); // outputs 'bool(true)'
var_dump($comparator->isEquivalent($typeB, $typeC)); // outputs 'bool(false)'