Как добавить пользовательские правила валидации при использовании проверки формы запроса в Laravel 5
Я использую метод проверки формы запроса для проверки запроса в laravel 5. Я хотел бы добавить свое собственное правило проверки с помощью метода проверки формы. Ниже приведен мой класс запроса. Я хочу добавить пользовательскую проверку numeric_array с элементами поля.
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array|numericarray']
];
Моя функция cusotom приведена ниже
Validator::extend('numericarray', function($attribute, $value, $parameters) {
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
Как использовать этот метод проверки с помощью проверки формы запроса в laravel5?
Ответы
Ответ 1
Использование Validator::extend()
, как и вы, на самом деле прекрасно, вам просто нужно поместить это в Поставщик услуг следующим образом:
<?php namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ValidatorServiceProvider extends ServiceProvider {
public function boot()
{
$this->app['validator']->extend('numericarray', function ($attribute, $value, $parameters)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
}
public function register()
{
//
}
}
Затем зарегистрируйте поставщика, добавив его в список в config/app.php
:
'providers' => [
// Other Service Providers
'App\Providers\ValidatorServiceProvider',
],
Теперь вы можете использовать правило проверки numericarray
везде, где хотите
Ответ 2
В то время как приведенный выше ответ верен, во многих случаях вам может потребоваться создать пользовательскую проверку только для определенного запроса формы. Вы можете использовать laravel FormRequest и использовать инъекцию зависимостей для расширения проверки factory. Я думаю, что это решение намного проще, чем создание поставщика услуг.
Вот как это можно сделать.
use Illuminate\Validation\Factory as ValidationFactory;
class UpdateMyUserRequest extends FormRequest {
public function __construct(ValidationFactory $validationFactory)
{
$validationFactory->extend(
'foo',
function ($attribute, $value, $parameters) {
return 'foo' === $value;
},
'Sorry, it failed foo validation!'
);
}
public function rules()
{
return [
'username' => 'foo',
];
}
}
Ответ 3
Принятый ответ работает для глобальных правил проверки, но много раз вы будете проверять определенные условия, которые очень специфичны для формы. Вот то, что я рекомендую в этих обстоятельствах (что, похоже, несколько связано с исходным кодом Laravel на строка 75 формы FormRequest.php):
Добавить метод проверки подлинности родительскому запросу. Запросы ваших запросов будут расширяться:
<?php namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Validator;
abstract class Request extends FormRequest {
public function validator(){
$v = Validator::make($this->input(), $this->rules(), $this->messages(), $this->attributes());
if(method_exists($this, 'moreValidation')){
$this->moreValidation($v);
}
return $v;
}
}
Теперь все ваши конкретные запросы будут выглядеть так:
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
class ShipRequest extends Request {
public function rules()
{
return [
'shipping_country' => 'max:60',
'items' => 'array'
];
}
// Here we can do more with the validation instance...
public function moreValidation($validator){
// Use an "after validation hook" (see laravel docs)
$validator->after(function($validator)
{
// Check to see if valid numeric array
foreach ($this->input('items') as $item) {
if (!is_int($item)) {
$validator->errors()->add('items', 'Items should all be numeric');
break;
}
}
});
}
// Bonus: I also like to take care of any custom messages here
public function messages(){
return [
'shipping_country.max' => 'Whoa! Easy there on shipping char. count!'
];
}
}
Ответ 4
Вам необходимо переопределить метод getValidatorInstance
в вашем классе Request
, например, следующим образом:
protected function getValidatorInstance()
{
$validator = parent::getValidatorInstance();
$validator->addImplicitExtension('numericarray', function($attribute, $value, $parameters) {
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
});
return $validator;
}
Ответ 5
Вам не нужно расширять валидатор для проверки элементов массива, вы можете проверить каждый элемент массива на "*", как вы можете видеть в
Проверка массива
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array'],
'items.*' => 'integer'
];
Ответ 6
Для меня работает решение, которое дает нам lukasgeiter, но с той разницей, что мы создаем класс с нашими пользовательскими проверками, например, для laravel 5.2. * Следующий пример - добавить проверку на диапазон дат, в котором вторая дата должна быть равной или более большой, чем первая.
В приложении/Провайдерах создайте ValidatorExtended.php
<?php
namespace App\Providers;
use Illuminate\Validation\Validator as IlluminateValidator;
class ValidatorExtended extends IlluminateValidator {
private $_custom_messages = array(
"after_or_equal" => ":attribute debe ser una fecha posterior o igual a
:date.",
);
public function __construct( $translator, $data, $rules, $messages = array(),
$customAttributes = array() ) {
parent::__construct( $translator, $data, $rules, $messages,
$customAttributes );
$this->_set_custom_stuff();
}
protected function _set_custom_stuff() {
//setup our custom error messages
$this->setCustomMessages( $this->_custom_messages );
}
/**
* La fecha final debe ser mayor o igual a la fecha inicial
*
* after_or_equal
*/
protected function validateAfterOrEqual( $attribute, $value, $parameters,
$validator) {
return strtotime($validator->getData()[$parameters[0]]) <=
strtotime($value);
}
} //end of class
Ok. теперь создайте поставщика услуг. Создайте ValidationExtensionServiceProvider.php внутри приложения/Провайдеров, и мы закодируем
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Validator;
class ValidationExtensionServiceProvider extends ServiceProvider {
public function register() {}
public function boot() {
$this->app->validator->resolver( function( $translator, $data, $rules,
$messages = array(), $customAttributes = array() ) {
return new ValidatorExtended( $translator, $data, $rules, $messages,
$customAttributes );
} );
}
} //end of class
Теперь мы расскажем Laravel о загрузке этого поставщика услуг, добавим массив провайдеров в конец в config/app.php и
//Servicio para extender validaciones
App\Providers\ValidationExtensionServiceProvider::class,
теперь мы можем использовать эту проверку в нашем запросе в правилах функций
public function rules()
{
return [
'fDesde' => 'date',
'fHasta' => 'date|after_or_equal:fDesde'
];
}
или в Validator: make
$validator = Validator::make($request->all(), [
'fDesde' => 'date',
'fHasta' => 'date|after_or_equal:fDesde'
], $messages);
вы должны заметить, что имя метода, которое делает проверку, имеет префикс validate и находится в стиле верблюда case validateAfterOrEqual, но когда вы используете правило проверки, каждая заглавная буква заменяется символом подчеркивания и буквой в строчной букве.
Все это я беру от https://www.sitepoint.com/data-validation-laravel-right-way-custom-validators// здесь, объясняя подробности. благодаря им.