如何为 laravel 中的相关输入字段创建自定义验证规则
How to create custom validation rule for dependent input fields in laravel
在我的输入表单中,我有两个字段; 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 一次只能验证一个字段的自定义验证规则。但在我的场景中,我需要同时检查两个字段,具体取决于彼此。我怎样才能做到这一点?
提前感谢您的帮助!
正在创建新规则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(),...],
]
最后,我用FormRequest
和AppServiceProvider
解决了这个问题。认为这会对来到这个地方的其他人有所帮助。
首先,我使用以下 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.');
}
};
}
在我的输入表单中,我有两个字段; 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 一次只能验证一个字段的自定义验证规则。但在我的场景中,我需要同时检查两个字段,具体取决于彼此。我怎样才能做到这一点?
提前感谢您的帮助!
正在创建新规则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(),...],
]
最后,我用FormRequest
和AppServiceProvider
解决了这个问题。认为这会对来到这个地方的其他人有所帮助。
首先,我使用以下 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.');
}
};
}