Я использую метод проверки запроса формы для проверки запроса в 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?
С помощью 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
Правило валидации везде, где вы хотите
Хотя приведенный выше ответ верен, во многих случаях вам может потребоваться создать пользовательскую проверку только для определенного запроса формы. Вы можете использовать laravel FormRequest и использовать внедрение зависимостей для расширения фабрики валидации. Я думаю, что это решение намного проще, чем создание поставщика услуг.
Вот как это можно сделать.
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',
];
}
}
Принятый ответ работает для глобальных правил проверки, но много раз вы будете проверять определенные условия, которые очень специфичны для формы. Вот то, что я рекомендую в этих обстоятельствах (это, кажется, несколько задумано из исходного кода 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!'
];
}
}
Вы должны переопределить 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;
}
Вам не нужно расширять валидатор для проверки элементов массива, вы можете проверить каждый элемент массива с помощью «*», как вы можете видеть в
Проверка массива
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array'],
'items.*' => 'integer'
];
Объект пользовательского правила
Один из способов сделать это с помощью Объект пользовательского правила, таким образом, вы можете определить столько правил, сколько захотите, без необходимости вносить изменения в провайдерах и в контроллере / службе для установки новых правил.
php artisan make:rule NumericArray
В NumericArray.php
namespace App\Rules;
class NumericArray implements Rule
{
public function passes($attribute, $value)
{
foreach ($value as $v) {
if (!is_int($v)) {
return false;
}
}
return true;
}public function message()
{
return 'error message...';
}
}
Тогда в форме запроса есть
use App\Rules\NumericArray;
.
.
protected $rules = [
'shipping_country' => ['max:60'],
'items' => ['array', new NumericArray]
];
Для меня работает решение, которое дает нам 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
Хорошо. Теперь давайте создадим поставщика услуг. Создайте 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 = Validator::make($request->all(), [
'fDesde' => 'date',
'fHasta' => 'date|after_or_equal:fDesde'
], $messages);
Вы должны заметить, что имя метода, который выполняет проверку, имеет префикс validate и имеет стиль casel validateAfterOrEqual, но при использовании правила проверки каждая заглавная буква заменяется подчеркиванием, а буква — строчной.
Все это я беру у https://www.sitepoint.com/data-validation-laravel-right-way-custom-validators// здесь объясню в деталях. благодаря им.
Все ответы на этой странице помогут вам решить проблему, но … Но единственно верный путь по соглашениям Laravel — это решение от Ганеш Карки
Если вы хотите создать проверку по соглашениям Laravel, следуйте этому руководству. Это легко и очень хорошо объясняется. Это мне очень помогло.