【问题标题】:如何在 laravel 中为依赖输入字段创建自定义验证规则
【发布时间】:2020-11-18 17:30:56
【问题描述】:

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

  • momentFrom 大于或等于 momentTo
  • momentFrom 比现在少。

我的数据存储代码:

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 自定义验证规则,一次只能验证一个字段。但在我的场景中,我需要一次检查两个字段,这取决于对方。我怎样才能做到这一点?

提前感谢您的帮助!

【问题讨论】:

  • before(date) - after(date) 验证将对您有所帮助。详情:laravel.com/docs/7.x/validation#available-validation-rules
  • 我可以不创建自定义验证来放置复杂的逻辑吗?
  • 如果您想要自定义错误消息,请阅读页面:laravel.com/docs/7.x/validation#custom-error-messages
  • 不仅仅是消息,我想在存储数据之前放置自定义验证逻辑。当用户尝试创建请求时,系统必须检查在该日期和时间是否有任何车辆可用。如果不可用,控制器必须向请求表返回错误消息。想知道如何放置这些逻辑并将消息发送回表单。 TIA

标签: php laravel laravel-7


【解决方案1】:

创建新的规则类

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

默认情况下,创建的文件包含一个构造函数、一个passes方法和一个message方法。

规则逻辑

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

  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(),...],
]

【讨论】:

  • 这个解决方案看起来很有希望!我会试试这个,然后带着结果回来。
【解决方案2】:

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

首先,我使用以下工匠命令创建了 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');
}

【讨论】:

    【解决方案3】:

    示例如何在 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.');
            }            
        };
    } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 2021-12-24
      • 1970-01-01
      • 2019-08-12
      • 1970-01-01
      • 2015-12-25
      • 2017-12-01
      相关资源
      最近更新 更多