Ở bài viết trước chúng ta đã tìm hiểu tổng quan về laravel form request, bài viết này sẽ tập chung vào các rule hay dùng khi validate data với laravel.
Tạo một form request với các rule validate dữ liệu tạo user.
public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:8|confirmed',
];
}
Rule trên định nghĩa request tạo user phải bắt buộc(require) có các thông tin name, email, password. name có kiểu là string và nhiều nhất 255 kí tự. email có định dạng là email và phải là duy nhất trong bảng users. password ít nhất 8 kí tự và phải truyền thêm password_confirmation để confirm lại password.
Tạo một request định nghĩa các rule cho việc thay đổi password
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ChangePasswordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'password_old' => ['required', 'string'],
'password_new' => [
'required',
'min:8',
'max:255',
'string',
'regex:/^(?=.*[a-z])(?=.*\d)[A-Za-z\d@$!%*?&]{8,30}$/',
],
'confirm_password' => [
'required',
'same:password_new',
'min:8',
'max:255',
'string',
'regex:/^(?=.*[a-z])(?=.*\d)[A-Za-z\d@$!%*?&]{8,30}$/',
],
];
}
/**
* Get the error messages for the defined validation rules.
*
* @return array<string, string>
*/
public function messages(): array
{
return [
'password_old.required' => trans('validation.required'),
'password_new.required' => trans('validation.required'),
'password_new.min' => trans('validation.min.string'),
'password_new.regex' => trans('messages.regex-password-register'),
'confirm_password.required' => trans('validation.required'),
'confirm_password.min' => trans('validation.min.string'),
'confirm_password.same' => trans('validation.same'),
'confirm_password.regex' => trans('messages.regex-password-register'),
];
}
/**
* Get custom attributes for validator errors.
*
* @return array<string, string>
*/
public function attributes(): array
{
return [
'password_old' => trans('messages.attributes.password-old'),
'password_new' => trans('messages.attributes.password-new'),
'confirm_password' => trans('messages.attributes.confirm-password'),
];
}
}
Tạo form request validate người dùng gửi file
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use App\Constants\PostStatus;
class CreatePostRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'content' => ['nullable', 'string', 'max:1000'],
'status' => ['required', 'integer', Rule::in(PostStatus::ALL)],
'image' => 'required|file|max:10000|mimes:jpg,jpeg,png,gif',
'file' => [
'nullable',
function ($attribute, $value, $fail) {
$mime = $value->getMimeType();
$videoMimeTypes = ['video/mp4', 'video/avi', 'video/mov'];
if (in_array($mime, $videoMimeTypes)) {
if ($value->getSize() > 200 * 1024 * 1024) {
$fail("The $attribute size must not exceed 200MB.");
}
} else {
$imageMimeTypes = ['image/jpeg', 'image/png', 'image/jpg', 'image/gif'];
if (in_array($mime, $imageMimeTypes)) {
if ($value->getSize() > 5 * 1024 * 1024) {
$fail("The $attribute size must not exceed 5MB.");
}
} else {
$fail("The $attribute must be either a video or an image.");
}
}
},
],
];
}
}
Chỉ cho upload file là ảnh hoặc video, nếu là ảnh thì nhỏ hơn 5MB, còn video nhỏ hơn 200MB.
Tạo form request validate search
public function rules(): array
{
return [
'category_id' => 'required|string',
'email' => 'sometimes|email',
'phone' => 'filled|regex:/^[0-9]{10}$/',
'shop_name' => 'bail|required|max:50',
'search' => 'nullable|string|max:50',
'search2' => 'present|string',
];
}
category_id: rule required bắt buộc phải có trong request, không được để trống hoặc null.
email: rule sometimes chỉ validate email khi có email trong request, nếu không có trong request thì không validate.
phone: rule filled, trường không bắt buộc nhưng nếu có mặt trong request thì phải có giá trị không được null và giá trị phải là 10 số.
shop_name: rule bail dừng kiểm tra rule tiếp theo nếu rule hiện tại thất bại, ví dụ không truyền shop_name thì sẽ báo lỗi shop name không được để trống, mà không kiểm tra tiếp rule max 50.
search: rule nullable cho phép truyền lên giá trị null hoặc không truyền lên request.
search2: rule present trường bắt buộc phải có trong request không thể để trống, có thể null.
Tạo form request cho dữ liệu đầu vào là một mảng như sau
{
"form_fields": [
{
"form_field_id": 1,
"is_required": true,
"order": 0,
"status": true
},
{
"form_field_id": 2,
"is_required": false,
"order": 1,
"status": false
}
]
}
Tạo form validate cho dữ liệu trên
public function rules(): array
{
return [
'form_fields.*.form_field_id' => 'required|integer|exists:form_fields,id',
'form_fields.*.is_required' => 'required|boolean',
'form_fields.*.order' => 'required|integer|min:0',
'form_fields.*.status' => 'required|boolean',
];
}
Ý nghĩa của dấu .*
form_fields.*: Xác định rằng các quy tắc được áp dụng cho từng phần tử con của mảng form_fields.
Mỗi phần tử trong mảng form_fields phải có các trường con (form_field_id, is_required, order, status) và phải thỏa mãn các quy tắc tương ứng.
Ví dụ 2: validate user_medias là mảng cái giá trị id, file. nếu id khác null thì file là required
public function rules(): array
{
return [
'user_medias' => ['required', 'array', 'max:9'],
'user_medias.*.id' => ['nullable', 'integer'],
'user_medias.*.file' => ['required_if:user_medias.*.id,!=,null', 'max:5000', 'image'],
];
}
Tạo form request validate thời gian
public function rules(): array
{
return [
'date' => 'required|date|date_format:Y-m-d',
'reservation_start_time' => 'required|date_format:H:i:s|before:reservation_end_time',
'reservation_end_time' => 'required|date_format:H:i:s|after:reservation_start_time',
];
}
public function rules(): array
{
return [
'shop_id' => 'required|integer|exists:shops,id',
'blocked_id' => [
'required',
'integer',
Rule::exists('users', 'id')->where(function ($query) {
$query->where('id', '!=', Auth::id());
})
],
'status' => ['required', 'integer', Rule::in(BlockStatus::ALL)],
];
}
Tạo custom rule với các điều kiện phức tạp
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\DB;
class RequiredIfFormFieldIsRequired implements Rule
{
protected $formFieldId;
protected $shopId;
public function __construct($formFieldId, $shopId)
{
$this->formFieldId = $formFieldId;
$this->shopId = $shopId;
}
public function passes($attribute, $value)
{
// Check if the form_field_id exists and is marked as required
$isRequired = DB::table('shop_form_field')
->where('form_field_id', $this->formFieldId)
->where('shop_id', $this->shopId)
->value('is_required');
// Pass validation if not required or if value is provided
return !$isRequired || !empty($value);
}
public function message()
{
return '値は必須項目です。';
}
}
Sử dụng custom rule
public function rules(): array
{
return [
'shop_id' => 'required|integer|exists:shops,id',
'reservation_start_time' => 'required|date_format:H:i:s|before:reservation_end_time',
'reservation_end_time' => 'required|date_format:H:i:s|after:reservation_start_time',
];
foreach ($this->input('reservation_values', []) as $key => $reservationValue) {
$formFieldId = $reservationValue['form_field_id'] ?? null;
$rules["reservation_values.$key.value"] = [
new \App\Rules\RequiredIfFormFieldIsRequired($formFieldId, $this->input('shop_id'))
];
}
return $rules;
}
Kiểm tra xem form field của shop có setting required không? nếu require thì mới validate require.