3nr1c/structure

Structure 提供了一组类来检查变量的数据类型和格式。

0.6-alpha2 2015-09-16 22:35 UTC

This package is not auto-updated.

Last update: 2024-09-28 18:34:21 UTC


README

Structure 提供了一组类来检查变量的数据类型和格式。

目录

许可协议
安装
简介
文档
静态快捷键
类 ScalarS
类 NumericS
类 IntegerS 和 FloatS
类 StringS
类 ArrayS
使用值集
更多信息
变更日志
计划中的功能

许可协议

StructureMIT 许可证 下提供。

安装

您可以使用 Composer 将 Structure 安装到您的项目中。强烈建议使用最新版本。您可以通过将以下内容添加到您的 composer.json 文件中来开始使用它

"require":{
    "3nr1c/structure": "0.*"
}

您也可以使用 "dev-master" 版本,但请自行承担风险。此版本的代码可能会随时更改。

简介

您是否曾经需要检查某些变量的结构?(可能是一个必须具有某些键和值类型的数组,或者一个必须在一定范围内的整数)。如果是这样,您可能已经编写了一些像这样的代码

if (!is_array($c)) {
    throw new \Exception();
} else if (!isset($c["profile"])) {
    throw new \Exception();
} else if (!is_array($c["profile"])) {
    throw new \Exception();
} //...

这只是开始!我猜您还必须对每个键检查其他键和数据类型。 Structure 帮助您处理这些问题。前面的代码变成

$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array("profile" => "array");
if (!$arrayCheck->check($c)) {
    throw new \Exception();
} //...

这里有一些其他示例

$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array(
    "id" => "int",
    "rating" => "float[0,10]",
    "title" => array(
        "en" => "str",
        "es" => "str"
    ),
    "links" => "string[]",
    "subtitles" => "bool"
));
$arrayCheck = new \Structure\ArrayS();
$arrayCheck->setFormat(array(
    "name" => "string",
    "customer_id" => "int",
    "is_admin" => "bool",
    "last_session" => "string"
));

文档

所有 Structure 类都有相同的构造函数

public function __construct($data = null, $null = false);

当运行 check 方法时,$null 参数允许数据为 null。所有类都有以下方法

public function setData($data);
public function getData();

// to avoid the data to be null:
public function setNull($null);
public function getNull();

// to check everything (type and range/format)
public function check($data = null, &$failed = null);

// to format things (specially powerfull in ArrayS)
public function format($data = null);

public static function getLastFail();
public static function clearLastFail();

check 方法的 &$failed 参数允许您创建一个变量,它会告诉您为什么此方法返回 false。您可以使用静态方法 getLastFailclearLastFail 访问最后一个错误信息,并清除它。这些失败变量的可能值在下面的部分中指定。

静态快捷键

主 Structure 类提供了四个静态方法来快速生成检查器

public static function ArrayS($format = null, $data = null, $countStrict = true, $null = false);
public static function NumericS($range = null, $data = null, $null = false);
public static function IntegerS($range = null, $data = null, $null = false);
public static function FloatS($range = null, $data = null, $null = false);
public static function StringS($data = null, $null = false);

所有这些方法分别返回 ArrayS、NumericS、IntegerS、FloatS 或 StringS 对象,其属性设置为由参数传递。

类 ScalarS

此类对变量运行 is_scalar() 测试。如果结果为 false,则 $failed 变量将显示测试变量的类型。

用法

$scalar = new \Structure\ScalarS();
if (!$scalar->check($var, $failed)) {
  print "Error: expected _scalar_, got " . $failed;
}

此类及其所有子类都具有 setValueSet 方法,允许您定义要检查的数据的可能值。此方法可以接受可变数量的参数,或者一个以花括号 {} 之间逗号分隔的值字符串

$scalar->setFormat("value1", "value2", 10, 11, 12);
// or
$scalar->setFormat("{value1, value2, 10, 11, 12, commas and brackets can be escaped: \{\,}");

truefalse 符号评估为布尔值。如果您需要字符串 "true" 和 "false",请转义它们

$scalar->setFormat("{true, false}");
$scalar->check(true); //true
$scalar->check(false); //true
$scalar->check("true"); //false
$scalar->check("false"); //false

$scalar->setFormat("{\\true, \\false}");
$scalar->check(true); //false
$scalar->check(false); //false
$scalar->check("true"); //true
$scalar->check("false"); //true

如果测试的变量是标量但不在定义的集合中,则 $failed 变量将为 "scalar:value"

类 NumericS

此类对变量运行 is_numeric() 测试。可以定义一个范围属性,其语法如下

/^\s*[\(\[]\s*(-?\d+(\.\d+)?|-inf)\s*,\s*(-?\d+(\.\d+)?|\+?inf)\s*[\)\]]\s*$/

即,它使用 数学符号

  • 括号字符 ('(') 表示严格的 (<) 下限
  • 方括号字符 ('[') 表示非严格的 (<=) 下限
  • 括号字符 (') 表示严格的 (>) 上限
  • 方括号字符 (']') 表示非严格的 (>=) 上限

术语 inf 用于表示无穷大。它有一些限制:左值只能是 -inf,右值可以是 inf+inf

如果语法不正确,解析器将抛出 \Exception。下面是一些例子

$numeric = new \Structure\NumericS();
$numeric->setRange("(-2,5]");

$numeric->check(-4.2);// false
$numeric->check(-2);// false
$numeric->check(0.33);// true
$numeric->check(3);// true
$numeric->check(5);// true
$numeric->check(10.42);// false

左边的数字必须小于或等于右边的数字。

如果测试变量的类型正确,但范围不正确,则 $failed 变量的值为 "numeric:range"

类 IntegerS 和 FloatS

它们都继承自 NumericS。唯一的区别是,IntegerScheck 方法使用 is_integer(更严格),而 FloatS 使用 is_float。注意这一点

$numeric = new \Structure\NumericS();
$numeric->check("3.2");// true
$numeric->check("5");// true

$float = new \Structure\FloatS();
$float->check("3.2");// false

$integer = new \Structure\IntegerS();
$integer->check("5");// false

如上例所示,FloatSIntegerS 对数字字符串非常严格。您可以使用属性 $numeric(默认设置为 false)来避免这种严格性

$float = new \Structure\FloatS();
$integer = new \Structure\IntegerS();

$float->setNumeric(true);
$integer->setNumeric(true);

$float->check("3.2");// true
$integer->check("5");// true

如果测试变量的类型正确,但范围不正确,则 $failed 变量的值为 "integer:range""float:range"

类 StringS

此类会对变量运行 is_string() 测试。

用法

$string = new \Structure\StringS();
$string->check($var);

可以使用 setLength 要求最小和最大长度。

$string->setLength(4); // 4 characters or more
$string->setLength(4, 10); // 4 to 10 characters
$string->setLength(0, 10); // up to 10 characters
$string->setLength("(4..10)"); // 4 to 10 characters

如果测试数据是字符串但不匹配长度,则 $fail 变量的值为 "string:length"

类 ArrayS

此类具有以下方法(以及从 Structure 继承的所有方法)

public function setFormat($format);
public function getFormat();
public function setCountStrict();
public function isCountStrict();

public static function isAssociative($data);

setFormat

$format 参数可以有多种形式。类型必须是 arraystring。字符串类型用于定义简单数组,如下

$array->setFormat("int[]");
$array->setFormat("int[10]");
$array->setFormat("bool[]");
$array->setFormat("MyClass[3]");

字符 +* 也可以用于测试简单数组。例如 "[3..5]" 可以用来表示可变数组大小。以下表达式是有效的

$array->setFormat("string[*]"); // checks for 0 or more strings
$array->setFormat("integer[+]"); // checks for 1 or more integers
$array->setFormat("scalar[5+]"); // checks for 5 or more scalars

$array->setFormat("float[3..5]"); // checks for 3 to 5 floats
$array->setFormat("float[..5]"); // checks for a maximum of 5 floats
$array->setFormat("float[3..]"); // checks for at least 3 floats

可以使用竖线 | 混合类型

$array->setFormat("(string|int|bool)[4+]");
$array->setFormat("(float|null)[]");

并且 [] 符号可以“嵌套”,以定义多维数组

$array->setFormat("integer[][]");
$array->setFormat("(integer[]|float[])[]");

// Beware of dimensions. This:
$array->setFormat("integer[2][3]");
// Would check true with this:
$array->check(array(
  array(1, 2),
  array(3, 4),
  array(5, 6)
)); // true

// this:
$array->setFormat("integer|float[]");
// is different from:
$array->setFormat("(integer|float)[]");

数组类型用于表示更复杂的数组结构。如果您期望数组是顺序的(即不是键值对),则格式应该是类型数组。再次提醒,如果所有数组元素都必须是同一类型,则建议使用上述语法。

$array->setFormat(array("integer", "string", "array"));
$array->setFormat(array(
    "int",
    "string",
    array("bool", "int", "float"),
    "numeric[]",
    "string(8..10)"
);

最后,您可以定义关联数组所需的关键字。警告:如果数组有一些您不想检查的键,请确保运行 $array->setCountStrict(false) 命令。

$array->setFormat(array(
    "foo" => "string",
    "foo2" => "string{hello, bye}[]",
    "bar" => "int[3,10)",
    "bar2" => "int[3,10)[4+]",
    "abc" => "array",
    "xyz" => array(
        "integer[]",
        "string(..5)[]",
        array(
            "hello" => "bool"
        )
    )
));

如您所见,它有一个递归定义。

使用值集

有时您想检查变量是否具有您已知的值。让我们假设我们想检查一个数字是否为 3 或 7。使用 Structure 支持的数学符号是不可能的(我们需要使用数学实体的并集和交集)。Structure 中的值集提供此功能。

$numeric = new \Structure\NumericS();
$numeric->setValueSet(3, 7);

$numeric->check(3); //true
$numeric->check(7); //true
$numeric->check(542); //false

// Less efficient, but valid (and needed for ArrayS):
//  $numeric->setValueSet("{3,7}");

此功能适用于所有 Structure 类型。当 ScalarSStringSNumericSIntegerSFloatSBooleanS)继承时,将提供 setValueSet() 方法。

在处理数组时,值集信息可以嵌入到格式声明中。

$format = array(
    "string{a,b,c}",
    "integer{2, 4, 6}"
);

$array = \Structure\Structure::ArrayS($format);

$arrayA = array("a", 2);
$arrayB = array("a", 6);
$arrayC = array("c", 2);
$arrayD = array("f", 2);

$array->check($arrayA); //correct
$array->check($arrayB); //correct
$array->check($arrayC); //correct
$array->check($arrayD); //incorrect

此功能还可以用于检查变量是否匹配单个值,这在数组上下文中非常有用。例如,您可以检查布尔值或整数

$format = array(
    "logged" => "bool{true}",
    "status" => "integer{0}"
);
$array = \Structure\Structure::ArrayS($format);

$test1 = array("logged" => true, "status" => 0);
$test2 = array("logged" => true, "status" => 1); //the status indicates some error code here

$array->check($test1);//true
$array->check($test2);//false

更多信息

您可以通过运行 composer doc(需要 phpdoc)和查看测试用例来阅读更多文档。

变更日志

0.6.0

  • ArrayS:数组可以是可变长度的!例如 "integer[1..5]"、"string[..4]"、"numeric[3..]"
  • ArrayS:可以使用 JSON 字符串定义格式
  • ArrayS:可以使用包含 JSON 格式的文件的路径定义格式
  • ArrayS:修复了 "null|string[]" 类型的格式错误
  • ArrayS:可以用字面量 null 替换 "null" 字符串
  • ArrayS:数组项可以是 "(string{a,b,c}|integer[3,10])[]"
  • ArrayS: "string[3]" 现在可以用来描述关联数组
  • Structure::typeof 现在是一个公共方法

0.5.0

  • 为 ArrayS、ScalarS(值集)和 NumericS(整数范围)编译字符串以避免重新解析
  • 错误报告:所有 check 方法接受第二个参数作为要创建的变量,以返回失败的内容,如果测试结果为 false。可以通过 Structure::getLastFail() 获取最后发生的错误,并通过 Structure::clearLastFail() 移除它
  • ArrayS:简单数组的描述量词:"type[*]""type[+]""type[10+]"
  • ArrayS:值的多个类型:"integer|float""string|null"
  • ArrayS:混合简单数组:"(integer|float)[]"
  • ArrayS:嵌套简单数组:"integer[][]""(integer[]|string[])[]"
  • ScalarS:truefalse 标记可以转义成字符串:"{\\true, \\false}"
  • StringS:长度测试。它可以通过 setLength 定义。对于数组,语法是 "string(min..max)"

计划中的功能

  • 日期格式:时间戳、MySQL 日期/时间/datetime、标准时间
  • 电子邮件、IP、哈希格式
  • 对象:属性(名称、可见性)和方法(名称、可见性、参数)
  • 字符串的正则表达式
  • ArrayS:将一些键标记为可选