空字符串验证不需要的整数

时间:2018-05-22 14:11:25

标签: php laravel laravel-5.6 dingo-api

我必须验证API的输入字段,其值必须是1到100之间的整数或null,否则甚至不设置(不是必需的)。

因此,我的验证规则是:'privacy_status' => "nullable|integer|min:1|max:100",

这个工作正常,直到我得到一个空字符串作为值。由于Laravel对空字符串的验证仅在字段隐式时才会验证,因此忽略所有其他规则integer, nullable or min, max

protected function isValidatable($rule, $attribute, $value)
{
    return $this->presentOrRuleIsImplicit($rule, $attribute, $value) &&
       $this->passesOptionalCheck($attribute) &&
       $this->isNotNullIfMarkedAsNullable($attribute, $value) &&
       $this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute);
}

protected function presentOrRuleIsImplicit($rule, $attribute, $value)
{
    if (is_string($value) && trim($value) === '') {
        return $this->isImplicit($rule);
    }

    return $this->validatePresent($attribute, $value) || $this->isImplicit($rule);
}

有没有办法正确验证?

2 个答案:

答案 0 :(得分:1)

修改

您始终可以创建自定义验证规则。

Validator::extendImplicit('fail_on_empty_string', function($attribute, $value, $parameters)
{
    return $value === "" ? false : $value;
});

您可以使用以下新规则:

'privacy_status' => "fail_on_empty_string|nullable|integer|min:1|max:100",

旧答案

这在Laravel文档中有描述,是你自己介绍的一个错误(虽然可能是无意识的):https://laravel.com/docs/5.6/validation#a-note-on-optional-fields

  

默认情况下,Laravel在应用程序的全局中间件堆栈中包含TrimStrings和ConvertEmptyStringsToNull中间件。这些中间件由App \ Http \ Kernel类列在堆栈中。因此,如果您不希望验证程序将空值视为无效,则通常需要将“可选”请求字段标记为可为空。

空字符串会自动转换为null,您的验证完全没问题。禁用中间件,更改它或更改验证规则。

答案 1 :(得分:0)

您只需将filled规则传递给它即可。这将允许该字段可以为空,如果它存在于请求中;它不能是空的。

'privacy_policy' => 'filled|integer|min:1|max:100'

如果您希望在present时允许空字符串,请改为显示当前规则。

'privacy_policy' => 'present|nullable|integer|min:1|max:100'

更新

我添加了一个单元测试来证明这是正常的。

public function index()
{
    request()->validate([
        'privacy_policy' => 'filled|integer|min:1|max:100'
    ]);

    return response();
}

然后在测试中:

$this->get(route('test'))->assertStatus(200); // True
$this->get(route('test'), ['privacy_policy' => ''])->assertStatus(200); // False
$this->get(route('test'), ['privacy_policy' => 5])->assertStatus(200); // True