Laravel 10 - 验证规则“字符串或数组”

Laravel 10 - validation rule "string or array"

提问人:clover 提问时间:11/8/2023 更新时间:11/9/2023 访问量:98

问:

我需要为一个动态数组添加验证,该数组的元素可以是字符串或包含字符串的后续数组,但我找不到保存此规则的方法。

我目前的验证:

        $data = $request->validate([
            'answers' => ['required', 'array'],
            'answers.*' => ['required', 'max:255'],
            'answers.*.*' => ['nullable', 'string', 'max:255']
        ]);

输入示例:

  "answers" => array:3 [▼
    4 => array:1 [▼
      0 => "Tests"
      1 => "Tests 2"
    ]
    5 => "Test"
    6 => "Yes"
  ]
php laravel 验证 laravel-10

评论


答:

1赞 Ali Özen 11/8/2023 #1

创建自定义规则类。例如:NestedArrayWithStrings

然后检查:

if (is_array($item))

在 for 循环中等。

像这样添加到验证中:

'answers' => ['required', 'array', new NestedArrayWithStrings],
1赞 nice_dev 11/8/2023 #2

为此,您需要在 Laravel 中定义一个自定义规则。

  • 运行该命令,这将在目录中创建一个新文件。php artisan make:rule NestedArrayWithStringsApp\Rules

  • 若要添加此规则,请先在控制器中导入规则类命名空间。

    use App\Rules\NestedArrayWithStrings;
    
  • 现在,在验证器中将其用作:

$v = Validator::make($request->all(),[
        'answers' => [
            'required',
            'array',
            new NestedArrayWithStrings
        ]
    ]);

if($v->fails()){
    echo $v->errors()->first(); // or similar
}

下面是你的递归代码,用于判断值以及它是否通过:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class NestedArrayWithStrings implements Rule{
    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value){
        if(!is_array($value)) return false;
        foreach($value as $v){
            if(is_array($v)){
               if(!$this->passes($attribute, $v)){
                 return false;
               }
            }else if(!is_string($v)){
                return false;
            }
        }

        return true;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message(){
        return 'Answers can only contain arrays filled with strings.';
    }
}

注意:从技术上讲,前端给出的所有内容都将以字符串形式出现,因此您需要添加额外的检查以及过滤掉您希望拥有的数据类型。is_string

1赞 ZeNix 11/8/2023 #3

所以,我创造了一些可以解决你的问题的东西,我已经尝试过了,而且有效。

首先,您可能想要创建一个新的 Rule 类,正如我在您的问题中评论的那样,例如使用 artisan 命令为其命名。php artisan make:rule DynamicArray

你需要在里面做这样的事情:app/Rules/DynamicArray

public function validate(string $attribute, mixed $value, Closure $fail): void
{
    $this->checkArray($attribute, $value, $fail);
}

private function checkArray(string $attribute, mixed $value, Closure $fail): void
{
    if(!is_array($value)){
        $fail("The $attribute must be an array.");
        return;
    }

    foreach ($value as $element){
        if (is_array($element)) {
            $this->checkArray($attribute, $element, $fail);
        } else if (!is_string($element)) {
            $fail("The $attribute is invalid.");
            return;
        }
    }
}

然后在你的控制器中,你将以这个结束:

    $data = $request->validate([
        'answers' => ['required', 'array', new DynamicArray]
    ]);

    dd($data);

您可以调试$data以检查它是否正常工作:

    dd($data);

它将通过价值:

validation pass

希望能解决您的问题!