在 Laravel 中验证数组键

问题描述 投票:0回答:3

我有以下来自表单提交的数据:

[
  "availabilities" => [
    "z" => ["some data"],
    "2" => ["some data"],
  ]
]

我正在尝试验证

availabilities
数组键以确保它们对应于数据库中的现有 id:

[
    'availabilities' => 'required|integer|exists:days_of_week,id',
]

如果我使用此规则,它会针对主数组,但即使我使用浏览器控制台将 id 更改为“z”之类的内容,

exists
键也会通过验证。它在
integer
规则上失败,因为它也检索一个数组。如何验证数组键?

php laravel laravel-validation
3个回答
12
投票

如果您可以控制输入数据结构,我建议将其修改为以下内容:

  [
  ...,
  "availabilities" => [
    {
      "id": "z",
      "data" : [0 => "foo"]
    },
    {
      "id": 2,
      "data" : [0 => "bar"]
    }
  ]

]

然后调整您的验证规则,例如根据您的数据库进行验证

public function rules {
    return [
        'availabilities' => 'filled',
        'availabilities.*.id' => 'required|integer|exists:days_of_week,id',
        'availabilities.*.data' => 'required|array'
        // etc...
    ];
}

9
投票

您可以通过添加自定义验证器来做到这一点。另请参阅:https://laravel.com/docs/5.2/validation#custom-validation-rules

例如:

\Validator::extend('integer_keys', function($attribute, $value, $parameters, $validator) {
    return is_array($value) && count(array_filter(array_keys($value), 'is_string')) === 0;
});

然后您可以使用以下命令检查输入:

'availabilities' => 'required|array|integer_keys',

在这里找到数组检查:如何检查 PHP 数组是关联数组还是顺序数组?


5
投票

@Jurriën Dokter 的答案是一种解决方法,它使用 PHP 函数而不是 Laravel 规则,它可以工作,但如果你真的想从 Laravel 验证规则中受益,你必须稍微调整验证请求。方法如下:
提出自定义请求:

php artisan make:request NameOfRequest  

将以下函数放入请求中:

protected function prepareForValidation()
{
    $this->merge([
        'availabilities_ids' => array_keys($this->get('availabilities'))
    ]);
}

规则中:

    public function rules()
    {
        return [
            // place your other rules here .. 
            'availabilities'       => 'required|array|min:1',
            'availabilities.*'     => 'array',
            'availabilities_ids'      => 'exists:App\Models\Availability,id'
        ];
    }

通过这种方式,您可以通过在验证之前修改请求参数来使用 Laravel 的本机验证规则。
请参阅此链接了解更多有关

prepareForValidation
https://laravel.com/docs/8.x/validation#prepare-input-for-validation

© www.soinside.com 2019 - 2024. All rights reserved.