Валидация
# Использование валидации
Октябрь поставляется с простой, удобной системой валидации (проверки входных данных на соответствие правилам) и получения сообщений об ошибках - классом Validator
.
# Простейший пример валидации
$validator = Validator::make(
['name' => 'Joe'],
['name' => 'required|min:5']
);
Первый параметр, передаваемый методу make
- данные для проверки. Второй параметр - правила, которые к ним должны быть применены.
# Использование массивов для указания правил
Несколько правил могут быть разделены либо прямой чертой (|), либо быть отдельными элементами массива.
$validator = Validator::make(
['name' => 'Joe'],
['name' => ['required', 'min:5']]
);
# Проверка нескольких полей
$validator = Validator::make(
[
'name' => 'Joe',
'password' => 'lamepassword',
'email' => 'email@example.com'
],
[
'name' => 'required',
'password' => 'required|min:8',
'email' => 'required|email|unique:users'
]
);
Как только был создан экземпляр Validator
, метод fails
(или passes
) может быть использован для проведения проверки.
if ($validator->fails()) {
// Переданные данные не прошли проверку
}
Если Validator
нашёл ошибки, то Вы можете получить его сообщения таким образом:
$messages = $validator->messages();
Вы также можете получить массив правил, данные которые не прошли проверку, без самих сообщений:
$failed = $validator->failed();
# Проверка файлов
Класс Validator
содержит несколько изначальных правил для проверки файлов, такие как size
, mimes
и другие. Для выполнения проверки над файлами просто передайте эти файлы вместе с другими данными.
# Работа с сообщениями об ошибках
После вызова метода messages
объекта Validator
Вы получите экземпляр Illuminate\Support\MessageBag
, который имеет набор полезных методов для доступа к сообщениям об ошибках.
# Получение первого сообщения для поля
echo $messages->first('email');
# Получение всех сообщений для одного поля
foreach ($messages->get('email') as $message) {
//
}
# Получение всех сообщений для всех полей
foreach ($messages->all() as $message) {
//
}
# Проверка на наличие сообщения для поля
if ($messages->has('email')) {
//
}
# Получение ошибки в заданном формате
echo $messages->first('email', '<p>:message</p>');
Примечание: По умолчанию сообщения отформатированы согласно синтаксису Bootstrap.
# Получение все сообщений в заданном формате
foreach ($messages->all('<li>:message</li>') as $message) {
//
}
# Сообщения об ошибках и представления
Как только вы провели проверку, вам понадобится простой способ, чтобы передать ошибки в шаблон. Октябрь позволяет удобно сделать это. Например, у нас есть такие роуты:
public function onRegister()
{
$rules = [];
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('register')->withErrors($validator);
}
}
Заметьте, что когда проверки не пройдены, мы передаём объект Validator
объекту переадресации Redirect при помощи метода withErrors
. Этот метод сохранит сообщения об ошибках в одноразовых flash-переменных сессии, таким образом делая их доступными для следующего запроса.
Октябрь постоянно проверяет данные сессии на наличие ошибок и, если они существуют, то автоматически привязывает их к представлению. Таким образом, важно помнить, что переменная errors
будет доступна для всех ваших страниц всегда и при любом запросе. Это позволяет вам считать, что переменная errors
всегда определена и может безопасно использоваться. Переменная errors
- экземпляр класса MessageBag
.
Таким образом, после переадресации вы можете прибегнуть к автоматически установленной в шаблоне переменной errors
:
{{ errors.first('email') }}
# Именованные MessageBag
Если у вас есть несколько форм на странице, то вы можете выбрать имя объекта MessageBag
, в котором будут возвращаться тексты ошибок, чтобы Вы могли их корректно отобразить для нужной формы. Просто передайте имя в качестве второго аргумента в withErrors
:
return Redirect::to('register')->withErrors($validator, 'login');
Получить текст ошибки из MessageBag
с именем login
:
{{ errors.login.first('email') }}
# Доступные правила валидации
Ниже приведен список всех доступных правил и их функции:
- Accepted
- Active URL
- After (Date)
- Alpha
- Alpha Dash
- Alpha Numeric
- Array
- Before (Date)
- Between
- Boolean
- Confirmed
- Date
- Date Format
- Different
- Digits
- Digits Between
- Exists (Database)
- Image (File)
- In
- Integer
- IP Address
- Max
- MIME Types
- Min
- Not In
- Numeric
- Regular Expression
- Required
- Required If
- Required With
- Required With All
- Required Without
- Required Without All
- Same
- Size
- String
- Timezone
- Unique (Database)
- URL
# accepted
Поле должно быть в значении yes, on или 1. Это полезно для проверки принятия правил и лицензий.
# active_url
Поле должно быть корректным URL, доступным через PHP функцию checkdnsrr
.
# after:date
Поле должно быть датой, более поздней, чем date. Строки приводятся к датам PHP функцией strtotime
.
# alpha
Поле можно содержать только только латинские символы.
# alpha_dash
Поле можно содержать только латинские символы, цифры, знаки подчёркивания (_) и дефисы (-).
# alpha_num
Поле можно содержать только латинские символы и цифры.
# array
Поле должно быть массивом.
# before:date
Поле должно быть датой, более ранней, чем date. Строки приводятся к датам PHP функцией strtotime
.
# between:min,max
Поле должно быть числом в диапазоне от min до max. Строки, числа и файлы трактуются аналогично правилу size
.
# boolean
Поле должно быть логическим (булевым). Разрешенные значения: true
, false
, 1
, 0
, "1"
и "0"
.
# confirmed
Значение поля должно соответствовать значению поля с этим именем, плюс foo_confirmation
. Например, если проверяется поле password
, то на вход должно быть передано совпадающее по значению поле password_confirmation
.
# date
Поле должно быть правильной датой в соответствии с PHP функцией strtotime
.
# date_format:format
Поле должно подходить под формату даты format в соответствии с PHP функцией date_parse_from_format
.
# different:field
Значение проверяемого поля должно отличаться от значения поля field.
# digits:value
Значение проверяемого поля должно быть числом и иметь точную длину value.
# digits_between:min,max
Поле должно иметь длину в диапазоне от min до max.
Поле должно быть корректным адресом e-mail.
# exists:table,column
Поле должно существовать в заданной таблице базе данных.
# Простое использование:
'state' => 'exists:states'
# Указание имени поля в таблице:
'state' => 'exists:states,abbreviation'
Вы также можете указать больше условий, которые будут добавлены к запросу "WHERE":
'email' => 'exists:staff,email,account_id,1'
Вы можете передать NULL
в "where", тогда будет осуществлена проверка значения в бд на NULL
:
'email' => 'exists:staff,email,deleted_at,NULL'
# image
Загруженный файл должен быть изображением в формате jpeg, png, bmp или gif.
# in:foo,bar,...
Значение поля должно быть одним из перечисленных (foo, bar и т.д.).
# integer
Поле должно иметь корректное целочисленное значение.
# ip
Поле должно быть корректным IP-адресом.
# max:value
Значение поля должно быть меньше или равно value. Строки, числа и файлы трактуются аналогично правилу size
.
# mimes:foo,bar,...
MIME-тип загруженного файла должен быть одним из перечисленных.
# Простое использование:
'photo' => 'mimes:jpeg,bmp,png'
# min:value
Значение поля должно быть более value. Строки, числа и файлы трактуются аналогично правилу size
.
# not_in:foo,bar,...
Значение поля не должно быть одним из перечисленных (foo, bar и т.д.).
# numeric
Поле должно иметь корректное числовое или дробное значение.
# regex:pattern
Поле должно соответствовать заданному регулярному выражению.
Примечание: при использовании этого правила Вам возможно потребуется перечислять другие правила в виде элементов массива, особенно если выражение содержит символ вертикальной черты (|).
# required
Проверяемое поле должно иметь непустое значение.
# required_if:field,value,...
Проверяемое поле должно иметь непустое значение, если другое поле field имеет любое из значений value.
# required_with:foo,bar,...
Проверяемое поле должно иметь непустое значение, но только если присутствует хотя бы одно из перечисленных полей (foo, bar и т.д.).
# required_with_all:foo,bar,...
Проверяемое поле должно иметь непустое значение, но только если присутствуют все перечисленные поля (foo, bar и т.д.).
# required_without:foo,bar,...
Проверяемое поле должно иметь непустое значение, но только если не присутствует хотя бы одно из перечисленных полей (foo, bar и т.д.).
# required_without_all:foo,bar,...
Проверяемое поле должно иметь непустое значение, но только если не присутствуют все перечисленные поля (foo, bar и т.д.).
# same:field
Поле должно иметь то же значение, что и поле field.
# size:value
Поле должно иметь совпадающий с value размер. Для строк это обозначает длину, для чисел - число, для файлов - размер в килобайтах.
# string:value
Поле должно иметь тип строки.
# timezone
Поле должно содержать идентификатор часового пояса (таймзоны), один из перечисленных в PHP функции timezone_identifiers_list
.
# unique:table,column,except,idColumn
Значение поля должно быть уникальным в заданной таблице базы данных. Если column
не указано, то будет использовано имя поля.
# Простое использование
'email' => 'unique:users'
# Указание имени поля в таблице
'email' => 'unique:users,email_address'
# Игнорирование определённого ID
'email' => 'unique:users,email_address,10'
# Добавление дополнительных условий
Вы также можете указать больше условий, которые будут добавлены к запросу "WHERE"":
'email' => 'unique:users,email_address,NULL,id,account_id,1'
В правиле выше только строки с account_id
равном 1
будут включены в проверку.
# url
Поле должно быть корректным URL.
Примечание: Эта функция использует PHP метод
filter_var
.
# Условные правила
Иногда вам нужно валидировать некое поле только тогда, когда оно присутствует во входных данных. Для этого добавьте правило sometimes
:
$v = Validator::make($data, [
'email' => 'sometimes|required|email',
]);
В примере выше поле для поля email
будет запущена валидация только когда $data['email']
существует.
# Сложные условные правила
Иногда вам может нужно, чтобы поле имело какое-либо значение только если другое поле имеет значение, скажем, больше 100. Или вы можете требовать наличия двух полей только, когда также указано третье. Это легко достигается условными правилами. Сперва создайте объект Validator
с набором статичных правил, которые никогда не изменяются:
$v = Validator::make($data, [
'email' => 'required|email',
'games' => 'required|numeric',
]);
Теперь предположим, что ваше приложения написано для коллекционеров игр. Если регистрируется коллекционер с более, чем 100 играми, то мы хотим их спросить, зачем им такое количество. Например, у них может быть магазин или может им просто нравится их собирать. Итак, для добавления такого условного правила мы используем метод sometimes
.
$v->sometimes('reason', 'required|max:500', function($input) {
return $input->games >= 100;
});
Первый параметр этого метода - имя поля, которое мы проверяем. Второй параметр - правило, которое мы хотим добавить, если переданная Closure
(третий параметр) вернёт true
. Этот метод позволяет легко создавать сложные правила проверки ввода. Вы можете даже добавлять одни и те же условные правила для нескольких полей одновременно:
$v->sometimes(['reason', 'cost'], 'required', function($input) {
return $input->games >= 100;
});
Примечание: Параметр
$input
, передаваемыйClosure
- объектIlluminate\Support\Fluent
и может использоваться для чтения проверяемого ввода и файлов.
# Собственные сообщения об ошибках
Вы можете передать собственные сообщения об ошибках вместо используемых по умолчанию. Если несколько способов это сделать.
# Передача своих сообщений в Validator
$messages = [
'required' => 'The :attribute field is required.',
];
$validator = Validator::make($input, $rules, $messages);
Примечание: строка
:attribute
будет заменена на имя проверяемого поля. Вы также можете использовать и другие строки-переменные.
# Использование других переменных-строк
$messages = [
'same' => 'The :attribute and :other must match.',
'size' => 'The :attribute must be exactly :size.',
'between' => 'The :attribute must be between :min - :max.',
'in' => 'The :attribute must be one of the following types: :values',
];
# Указание собственного сообщения для отдельного поля
Иногда вам может потребоваться указать своё сообщение для отдельного поля:
$messages = [
'email.required' => 'We need to know your e-mail address!',
];
# Указание собственных сообщений в файле локализации
Также можно определять сообщения валидации в файле локализации вместо того, чтобы передавать их в Validator
напрямую. Для этого добавьте сообщения в массив в файл локализации lang/xx/validation.php
вашего плагина.
return [
'required' => 'We need to know your e-mail address!',
'email.required' => 'We need to know your e-mail address!',
];
Далее в Validator::make
используйте метод Lang:get
.
Validator::make($formValues, $validations, Lang::get('acme.blog::validation'));
# Собственные правила проверки
# Регистрация собственного правила валидации
Октябрь изначально содержит множество полезных правил, однако Вам может понадобиться создать собственные. Одним из способов зарегистрировать произвольное правило - через метод Validator::extend
.
Validator::extend('foo', function($attribute, $value, $parameters) {
return $value == 'foo';
});
Переданная Closure
получает три параметра: имя проверяемого поля $attribute
, значение поля $value
и массив параметров $parameters
переданных правилу.
Вместо функции в метод extend
можно передать ссылку на метод класса:
Validator::extend('foo', 'FooValidator@validate');
Обратите внимание, что Вам также понадобится определить сообщение об ошибке для нового правила. Вы можете сделать это либо передавая его в виде массива строк в Validator
, либо вписав в файл локализации.
# Расширение класса Validator
Вместо использования Closure
для расширения набора доступных правил Вы можете расширить сам класс Validator. Для этого создайте класс, который наследует Illuminate\Validation\Validator
. Вы можете добавить новые методы проверок, начав их имя с validate
:
<?php
class CustomValidator extends Illuminate\Validation\Validator
{
public function validateFoo($attribute, $value, $parameters)
{
return $value == 'foo';
}
}
# Регистрация нового класса Validator
Затем Вам нужно зарегистрировать это расширение валидации:
Validator::resolver(function($translator, $data, $rules, $messages, $customAttributes) {
return new CustomValidator($translator, $data, $rules, $messages, $customAttributes);
});
Иногда при создании своего класса валидации Вам может понадобиться определить собственные строки-переменные (типа ":foo") для замены в сообщениях об ошибках. Это делается путём создания класса, как было описано выше, и добавлением функций с именами вида replaceXXX
.
protected function replaceFoo($message, $attribute, $rule, $parameters)
{
return str_replace(':foo', $parameters[0], $message);
}
Если вы хотите добавить свое сообщение без использования Validator::extend
, Вы можете использовать метод Validator::replacer
:
Validator::replacer('rule', function($message, $attribute, $rule, $parameters) {
//
});