【问题标题】:How to check data validity based on expected type?如何根据预期类型检查数据有效性?
【发布时间】:2023-04-04 13:53:01
【问题描述】:

我需要根据相关的预期类型验证从 HTTP 请求(通常来自 $_POST 和 $_GET)收到的一些值。

这里是如何定义可能的参数:

$defs = [ 
'op'       => [ 'type' => 'string' ],
'out'      => [ 'type' => 'integer'],
'throttle' => [ 'type' => 'double']
];

PHP 提供了 filter_var() 函数,它实际上净化了值,但不判断格式是否有效。

是否有另一种方法来实现这一点,而不必为每种可能的类型(字符串、布尔值、整数、浮点数、双精度、数组)编写正则表达式?

【问题讨论】:

  • 如果有人已经做到了,他能举个例子吗?谢谢。

标签: php validation


【解决方案1】:

编辑

由于我不太可能有时间进一步开发我的库,因此我正在提供另一个库以供使用。
Respect/Validation (R/V) 有很多功能可以使用并且可以使用现在;也就是说,它不像我的那样正在进行中。

这是相同的工作示例,但使用的是 R/V。

use Respect\Validation\Validator as v;

// these are from your POST, I think
$op = "test";
$out = 10.5;
$throttle = 10.5;

$defs = [ 
    "op"       => ["type" => "string"],
    "out"      => ["type" => "integer"],
    "throttle" => ["type" => "double"]
];

foreach ($defs as $name => $settings) {
    if (v::type($settings["type"])->validate($$name)) {
        echo "<p><i>$name</i> is okay</p>";
    } else {
        echo "<p><i>$name</i> is <b>not</b> okay</p>";
    }
}

关于解释,这与我最初的答案相同 - 除了访问错误。

在 R/V 中,您需要尝试/捕获错误使用不同的验证方法 - assert。见下文。

foreach ($defs as $name => $settings) {
    try {
        v::type($settings["type"])->assert($$name);
        echo "<p>No problem</p>";
    } catch (Respect\Validation\Exceptions\ExceptionInterface $ex) {
        foreach ($ex->getMessages() as $error) {
            echo "<p>$error</p>";
        }
    }
}

在上面的示例中,错误被捕获。 R/V 使用getMessages 返回所有错误的数组。我用它来迭代它们并打印它们。


原答案如下

我创建了一个 WIP 库:https://github.com/JustCarty/Validator

示例

如果我正确理解了这个问题,那么你会这样使用它:

$v = new Validator();

// these are from your POST, I think
$op = "test";
$out = 10.5;
$throttle = 10.5;

$defs = [ 
    "op"       => ["type" => "string"],
    "out"      => ["type" => "integer"],
    "throttle" => ["type" => "double"]
];

foreach ($defs as $name => $settings) {
    if ($v->clearErrors()->setDataType($settings["type"])->validate($$name)) {
        echo "<p><i>$name</i> is okay</p>";
    } else {
        echo "<p><i>$name</i> is <b>not</b> okay</p>";
    }
}

输出

op 没问题
out 不行 没问题
油门 没问题

工作原理

它像任何其他类一样被初始化。只需创建一个变量并使用 new 关键字。
正如您在示例中看到的那样,它是可链接的。

foreach 循环将遍历您的定义并将变量(或字符串)的名称存储在名为 $name 的变量中,并将设置数组存储在变量 $settings 中。
第一步是清除以前的错误。这是因为我们没有初始化每次迭代,我们保留相同的实例并更改其属性。 下一个方法是setDataType。我们访问设置数组的 type 属性,然后设置此验证的数据类型。
下一个方法看起来很奇怪。双美元符号将按以下方式计算(我以第一次迭代为例):

$$name;
$op; // outputs "test"

您可以阅读有关double dollar here 的更多信息。

在失败的 if 语句中可以访问错误。例如,您可以调用$v-&gt;error$v-&gt;errno$v-&gt;errorList 分别检索最后一个错误、错误编号或所有错误。

免责声明

库中还有其他一些可用选项。
请注意,它是WIP,因此可能存在一些问题。

我也会在某个时间点创建一个 README...

【讨论】:

    【解决方案2】:

    更好地使用filter_var函数。
    此处的文档:http://php.net/manual/en/function.filter-var.php

    【讨论】:

    • 所以,您的意思是有必要为每种预期类型选择合适的过滤器。
    • 也可以使用preg_match进行验证
    【解决方案3】:

    当您只想检查某物的类型时,PHP 有两种方法。您使用gettype 函数(参见示例)或is_TYPE 函数(TYPE 是占位符)。在这里您可以看到 is_TYPE 函数的完整列表。 http://php.net/manual/en/book.var.php

    $defs = [ 
        'op'       => [ 'type' => 'string' ],
        'out'      => [ 'type' => 'integer'],
        'throttle' => [ 'type' => 'double']
    ];
    
    $in = [
        'op' => 'test',
        'out' => 123,
        'throttle' => 1.234
    ];
    
    foreach ($in as $k => $v) {
        var_dump(gettype($v) === $defs[$k]['type']);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      相关资源
      最近更新 更多