zheltikov/php-type-assert

2.5.1 2021-11-02 09:34 UTC

This package is auto-updated.

Last update: 2024-08-29 05:44:13 UTC


README

PHP 类型检查/断言库,用于编写更紧凑和安全的代码。

安装

由于这是一个 Composer 包,您可以通过以下方式安装它:

$ composer require zheltikov/php-type-assert

用法

此库在 \Zheltikov\TypeAssert 命名空间中公开了三个函数

  • is_(mixed, string): bool
  • as_(mixed, string): mixed
  • null_as_(mixed, string): mixed|null

示例

您可以使用以下方式使用这些函数

<?php

require_once(__DIR__ . '/../vendor/autoload.php');

use Zheltikov\TypeAssert\{is_, as_, null_as_};

// Using `is_()` to check types
is_(1, 'int');        // true
is_('foo', 'int');    // false
is_(1, 'num');        // true
is_(1.5, 'num');      // true
is_('foo', 'num');    // false
is_('mykey', '?arraykey');  // true
is_('bar', '!num');    // true
is_('X', 'char');    // true

// Enforcing types with `as_()`
as_(1, 'int');        // 1
as_('foo', 'int');    // TypeAssertionException
as_(123, '?num');     // 123
as_('bar', '?num');   // TypeAssertionException

// Get `null` if the type does not match with `null_as_()`
null_as_(1, 'int');        // 1
null_as_('foo', 'int');    // null
null_as_(123, '?num');     // 123
null_as_('bar', '?num');   // null

// As you can see performing type checks with these functions is much more
// compact that doing it with `if`s
// For example, instead of...

if (is_int($value) || is_float($value)) {
    // do something
}

// ...use...

if (is_($value, 'num')) {
    // do something
}

// ...or even...

as_($value, 'num');
// do something

以下是每个函数的简单解释

is_(mixed, string): bool

参数

  • mixed $value
  • string $type

检查 $value 中的值是否具有 $type 中指定的类型,并返回一个布尔结果。

as_(mixed, string): mixed

参数

  • mixed $value
  • string $expected

执行与 is_ 相同的检查。然而,如果值具有不同的类型,则抛出 TypeAssertionException。如果类型匹配,则返回原始值。

null_as_(mixed, string): mixed|null

参数

  • mixed $value
  • string $expected

类似于 as_,但如果类型不匹配则返回 null。

支持类型和类型解释

以下是一份支持类型及其内部检查方式的列表

TODO

  • 支持内置 PHP 类型
  • 支持 nullnonnull
  • 支持 emptynonempty
  • 支持 mixedvoid
  • 支持 num
  • 支持 arraykey
  • 支持可空类型
  • 支持否定类型
  • 支持 classnameinterfacenametraitname
  • 支持 char
  • 支持 Stringish:任何类似字符串的值
  • 支持自定义类名
  • 支持 truefalse
  • 支持 positivenonpositivenotpositive
  • 支持 negativenonnegativenotnegative
  • 支持元组。例如:tuple(int, ?DateTime, bool)
  • 支持封闭形状。例如:shape('id' => int, 'name' => string)
  • 支持开放形状。例如:shape('id' => int, 'name' => string, ...)
  • 支持可选形状字段。例如:shape('id' => int, ?'name' => string)
  • 支持枚举
    • 按枚举类型检查
    • 按枚举字段名检查
  • 支持数组泛型
    • 按值。例如:array<User>
    • 按键和值。例如:array<string, int>
  • 支持联合。例如:int|string|null
  • 支持交集。例如:Exception&Throwable
  • 模块化,能够定义自定义检查函数和类型
  • 缓存一些检查函数
  • 支持类型别名定义
  • 支持类型优先级检查定义
  • 支持注释
  • 支持格式化字符串(如 sprintfsscanf
  • 支持正则表达式
  • 支持命名参数
  • 支持开放元组:tuple(int, ...)tuple(..., int)tuple(int, ..., int)
  • 支持错误(类型不匹配)报告,供人类使用:)
  • 支持调用类型
    • 支持固定数量参数:(function(string, int): array<string, int>)
    • 支持可变数量参数:(function(string, ...): int)
  • 支持原始整数
  • 支持原始浮点数
  • 支持形状整数键
  • as_ 函数应转换(转换)值,而不是检查它。使用某些(可扩展的)转换类。

性能

您可能会问这个解析过程对整体请求性能的影响。您可能会惊讶地发现,这个库中包含的解析器性能实际上相当不错。

进行了一些测试,其中解析以下类型的字符串

shape(
    'id' => int & positive,
    'name' => string,
    'price' => float & positive,
    'score' => null | (int & positive),
    'description' => string,
    'photo_id' => int & positive,
    'category_id' => int & positive
)

这个测试是在PHP v7.4和PHP v8.0以及启用JIT编译的情况下进行的,结果相当不错!

注意:这些性能测试是在commit d9fedd23...时进行的,因此它们可能不适用于最新库版本。