如何为 laravel 中的相关输入字段创建自定义验证规则

How to create custom validation rule for dependent input fields in laravel

在我的输入表单中,我有两个字段; momentFrom & momentTo。如果以下任何条件失败,我需要进行验证以给出错误消息。

我存储数据的代码:

public function store(Request $request, Requisition $requisitionObj) {
    $momentFrom = strtotime($request->txtTravelDate . " " . $request->txtTimeFrom);
    $momentTo = strtotime($request->txtTravelDate . " " . $request->txtTimeTo);

    $timeValidation = $requisitionObj->validateTiming($momentFrom, $momentTo);
    if ($timeValidation['error']) {
        echo 'ERROR: ' . $timeValidation['message'];
        return view('requisitions.create');
    } else {
        /* store form data into requisition object */
        $requisitionObj->travel_date = $request->txtTravelDate;
        $requisitionObj->moment_from = $momentFrom;
        $requisitionObj->moment_to = $momentTo;

        $requisitionObj->save();
        
        return redirect()->route('requisitions.index');
    }
}

我看到 laravel 一次只能验证一个字段的自定义验证规则。但在我的场景中,我需要同时检查两个字段,具体取决于彼此。我怎样才能做到这一点?

提前感谢您的帮助!

正在创建新规则Class

您可以使用 artisan 命令创建自定义规则:php artisan make:rule YourRuleName这将在规则文件夹中创建一个新规则 Class 文件。

默认情况下,创建的文件包含构造函数、传递方法和消息方法。

规则逻辑

如果你有一些复杂的规则需要请求或一些模型,你可以通过构造函数传递它们。

  public function __construct(Request $request, User $user, ....)
    {
    //save them into class variables to access them later
        $this->request = $request;
        $this->user = $user;

    }

否则你可以直接将验证逻辑放入 passes 方法中:

public function passes($attribute, $value){
    //some code
    return #myCondition
}

最后您可以指定验证失败时的消息。

    public function message()
    {
        return 'Your message';
    }

要使用您的规则,只需将其添加到您的规则数组中即可:

$rules = [
'my_attribute' => [new MyCustomRule(),...],
]

最后,我用FormRequestAppServiceProvider解决了这个问题。认为这会对来到这个地方的其他人有所帮助。

首先,我使用以下 artisan 命令创建了 FormRequest 验证器。

php artisan make:request StoreRequisition

然后将主要验证规则和消息添加到其中。

namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;

class StoreRequisition extends FormRequest {
    public function authorize() {
        return true;
    }

    public function rules() {
        $rules = [
        'txtTravelDate' => 'required|date_format:Y-m-d|after_or_equal:today',
        'txtTimeFrom' => 'required|date_format:H:i|travel_time_validate',
        'txtTimeTo' => 'required|date_format:H:i',
        ];
        return $rules;
    }


    public function messages() {
        return [
            'txtTravelDate.required' => 'Travel date is required!',
            'txtTravelDate.date_format' => 'Invalid format for Travel Date!',
            'txtTravelDate.after_or_equal' => 'Travel Date should be today or later!',
            'txtTimeFrom.required' => 'Time From is required!',
            'txtTimeFrom.date_format' => 'Invalid format for Time From!',
            'txtTimeFrom.travel_time_validate' => 'Invalid time selected!',
            'txtTimeTo.required' => 'Time To is required!',
            'txtTimeTo.date_format' => 'Invalid format for Time To!',
            'listFunction.required' => 'Department to be selected!',
            'txtPickLoc.required' => 'Pickup Location is required!',
            'txtDropLoc.required' => 'Drop Location is required!',
            'listPurpose.required' => 'Travel Purpose to be selected!'
        ];
    }
}

然后在 app\Providers\AppServiceProvider 中添加了额外的验证逻辑。

public function boot() {
    Validator::extend(
        'travel_time_validate',
        function ($attribute, $value, $parameters, $validator) {
            $inputs = $validator->getData();
            /* convert time to moments */
            $momentFrom = strtotime($inputs['txtTravelDate'] . " " . $inputs['txtTimeFrom']);
            $momentTo = strtotime($inputs['txtTravelDate'] . " " . $inputs['txtTimeTo']);

            $result = true;
            if ($momentFrom >= $momentTo) {
                $result = false;
            }
            return $result;
        }
    );
}

我的控制器:

public function store(StoreRequisition $request, Requisition $requisitionObj) {

    $validatedData = $request->validated();

    /* store form data into requisition object */
    $requisitionObj->requester_id = Auth::user()->id;
    $requisitionObj->travel_date = $request->txtTravelDate;
    $requisitionObj->time_from = $request->txtTimeFrom;
    $requisitionObj->time_to = $request->txtTimeTo;
    $requisitionObj->purpose_id = $request->listPurpose;

    /* Finally save the record into the database */
    $requisitionObj->save();

    return redirect()->route('requisitions.index');
}

示例如何在 Laravel 8.x / Lumen 8.x.

中制定自定义验证规则
public static function rules(){
    return [
       'number' => [
          'required', 'min:1', 'max:30', 'string', self::testNumber(),
       ],
    ];
}


public static function testNumber(){
    return function($attribute, $value, $fail){
        if ($value === 'foo'){
            $fail('The '.$attribute.' is invalid.');
        }            
    };
}