Laravel - Валидация

28 Сентябрь 2020
В черный список
0
Просмотры
60
Laravel - Валидация

# Введение

# Быстрый старт

# Валидация в классах Form Request

# Создание валидаторов вручную

# Работа с сообщениями об ошибках

# Доступные правила валидации

# Добавление правил с условиями

# Валидация массивов

# Собственные правила валидации

 

 

Введение

 

Laravel предоставляет несколько способов для валидации входящих данных. По умолчанию базовый контроллер использует трейт ValidatesRequests, который обеспечивает удобный способ валидации HTTP запросов c большим количеством правил валидации.

 

 

 

Быстрый старт

 

Перед тем как узнать обо всех функциях, давайте рассмотрим полный пример валидации формы и вывод сообщений об ошибках для пользователя.

Определение роутов

 

Во первых, представим что мы имеем следующие роуты в файле routes/web.php:

 

Route::get('post/create', 'PostController@create');

Route::post('post', 'PostController@store');

 

Конечно, роут GET отображает форму для создания нового поста в блоге, в то время как POST будет сохранять новую запись в базе данных.

Создание контроллера

 

Посмотрим на простой контроллер, который обрабатывает эти роуты. Метод store пока оставим пустым:

 

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Показать форму для создания новой записи в блоге.
     *
     * @return Response
     */
    public function create()
    {
        return view('post.create');
    }

    /**
     * Хранить новую запись в блоге.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        // Validate and store the blog post...
    }
}

 

Написание логики валидации

 

Теперь мы готовы заполнить метод store валидацией при создания нового поста. Если проанализировать базовый контроллер (App\Http\Controllers\Controller), вы заметите, что он включает в себя трейт ValidatesRequests, который обеспечивает все контроллеры удобным методом validate.

Метод validate принимает два параметра экземпляр HTTP запроса и правила валидации. Если все правила не нарушены, код будет выполняться далее. Однако, если проверка не пройдена, будет выброшено исключение и сообщение об ошибке автоматически отправится обратно пользователю. По традициям HTTP запроса, ответ будет перенаправлен обратно с заполненными flash-переменными, в то время как на AJAX запрос отправится JSON.

Для лучшего понимания метода validate, вернемся обратно к store:

 

/**
 * Store a new blog post.
 *
 * @param  Request  $request
 * @return Response
 */
public function store(Request $request)
{
    $this->validate($request, [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // The blog post is valid, store in database...
}

 

Как видно, мы передаем экземпляр с данными HTTP запроса и правила валидации в метод validate. Помните, что если проверка завершится неудачей, будет автоматически сгенерирован ответ с сообщением об ошибках, иначе ваш контроллер продолжит работать.

 

Остановка после первой неудачной проверки

 

Иногда нужно остановить выполнение остальных правил после первой неудачной проверки. Для этого используется атрибут bail:

 

$this->validate($request, [
    'title' => 'bail|unique:posts|max:255',
    'body' => 'required',
]);

 

В этом примере, если для атрибута title не выполняется правило required, следующие правило unique проверяться не будет. Правила выполняются именно в той последовательности, в какой они назначаются.

 

Заметка о вложенных атрибутах

 

Если данные HTTP запроса содержат "вложенные" параметры, можно указать их, используя синтаксис с точкой:

 

$this->validate($request, [
    'title' => 'required|unique:posts|max:255',
    'author.name' => 'required',
    'author.description' => 'required',
]);

 

Отображение ошибок валидации

 

Что, если входящие данные не проходят проверку с учетом правил? Как упоминалось ранее, Laravel автоматически перенаправляет пользователя на предыдущую страницу. Кроме того, все ошибки валидации будут автоматически записаны во flash-переменные.

Опять же, обратите внимание, что мы не должны явно передавать сообщения об ошибках в шаблоне роута GET. Это потому, что Laravel будет проверять наличие ошибок в текущем сеансе и автоматически привязывать их к шаблону, если они доступны. Переменная $errors является экземпляром Illuminate\Support\MessageBag. Для получения дополнительных сведений о работе с этим объектом, смотрите в документации.

Переменная $errorsпривязана к посреднику Illuminate\View\Middleware\ShareErrorsFromSession, который входит в группу посредников web . При использовании этого посредника, $errors всегда будет доступна в ваших шаблонах, что позволяет удобно и безопасно ее использовать.

В нашем примере пользователь будет перенаправлен в метод create вашего контроллера и можно отобразить сообщения об ошибках в шаблоне:

 

<!-- /resources/views/post/create.blade.php -->

<h1>Create Post</h1>

@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

<!-- Create Post Form -->

 

Заметка о дополнительных полях

 

По умолчанию в Laravel включены глобальные посредники TrimStrings и ConvertEmptyStringsToNull. Они перечислены в свойстве $middleware класса App\Http\Kernel. Из-за этого нужно часто помечать дополнительные поля как nullable, если не нужно, чтобы валидатор считал не действительным значение null. Например:

 

$this->validate($request, [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
    'publish_at' => 'nullable|date',
]);

 

В этом примере мы указываем что поле publish_at может быть null или должно содержать дату. Если модификатор nullable не добавляется в правило, проверяющий элемент будет рассматривать null как недопустимую дату.

 

Настройка формата вывода ошибок валидации

 

Если вы хотите настроить вывод ошибок валидации, которые будут во flash-переменных после нарушений правил, переопределите метод formatValidationErrors в базовом контроллере. Не забудьте подключить класс Illuminate\Contracts\Validation\Validator:

 

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;

abstract class Controller extends BaseController
{
    use DispatchesJobs, ValidatesRequests;

    /**
     * {@inheritdoc}
     */
    protected function formatValidationErrors(Validator $validator)
    {
        return $validator->errors()->all();
    }
}

 

 

AJAX запросы и валидация

 

В последнем примере мы использовали традиционные формы для отправки данных в наше приложение. Однако многие приложения используют AJAX-запросы. При использовании метода validate во время запроса AJAX, Laravel не будет генерировать ответ с перенаправлением. Вместо этого Laravel генерирует ответ с JSON данными, содержащий в себе все ошибки проверки. Этот ответ будет отправлен с кодом состояния HTTP 422.

Валидация Form Request

 

Создание Form Request

 

Для более сложных сценариев валидаций, будут более удобны Form Requests. Form Requests это специальные классы, которые содержат в себе логику проверки. Для создания класса, используйте artisan-команду make:request:

 

php artisan make:request StoreBlogPost

 

Сгенерированный класс будет размещен в каталоге app/Http/Requests. Если этот каталог не существует, он будет создан. Давайте добавим несколько правил проверки в метод rules:

 

/**
 * Получить правила валидации, применимые к запросу.
 *
 * @return array
 */
public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

 

Так как же здесь работают правила валидации? Все, что нужно сделать — это указать класс Form Request в аргументах метода вашего контроллера. Входящий запрос перед вызовом метода контроллера будет валидироваться автоматически, что позволит загромождать контроллер логикой валидации:

 

/**
 * Store the incoming blog post.
 *
 * @param  StoreBlogPost  $request
 * @return Response
 */
public function store(StoreBlogPost $request)
{
    // The incoming request is valid...
}

 

Если проверка не пройдена, то при традиционном запросе ошибки будут записываться в сессию и будут доступны в шаблонах, иначе, если запрос был AJAX, HTTP-ответ с кодом 422 будет возвращен пользователю, включая JSON с ошибками валидации.

 

Добавление хуков в Form Request

 

Если вы хотите добавить хук "after" в Form Requests, можно использовать метод withValidator. Этот метод получает полностью сформированный валидатор, позволяя вызвать любой из его методов, прежде чем фактически применяются правила:

 

/**
 * Настройка экземпляра валидатора.
 *
 * @param  \Illuminate\Validation\Validator  $validator
 * @return void
 */
public function withValidator($validator)
{
    $validator->after(function ($validator) {
        if ($this->somethingElseIsInvalid()) {
            $validator->errors()->add('field', 'Something is wrong with this field!');
        }
    });
}

 

Авторизация Form Request

 

Класс Form Request содержит в себе метод authorize. В этом методе можно проверить, имеет ли аутентифицированный пользователь права на выполнение данного запроса. Например, можно проверить, есть ли у пользователя право для добавления комментариев в блог:

 

/**
 * Определить авторизован ли пользователь делать такой запрос.
 *
 * @return bool
 */
public function authorize()
{
    $comment = Comment::find($this->route('comment'));

    return $comment && $this->user()->can('update', $comment);
}

 

Так как все Form Request расширяют базовый класс Request, мы можем использовать метод user, чтобы получить доступ к текущему пользователю.Так же обратите внимание на вызов метода route. Этот метод предоставляет доступ к параметрам URI, определенным в роуте (в приведенном ниже примере это {comment}):

 

Route::post('comment/{comment}');

 

Если метод authorize возвращает false, автоматически генерируется ответ с кодом 403 и метод контроллера не выполняется.

Если же логика авторизации организована в другом месте вашего приложения, просто верните true из метода authorize:

 

/**
 * Определить авторизован ли пользователь делать такой запрос.
 *
 * @return bool
 */
public function authorize()
{
    return true;
}

 

Настройка формата вывода ошибок

 

Если вы хотите настроить формат вывода ошибок валидации, которые будут заполнять flash-переменные при неудачном выполнении, переопредилите метод formatErrors в вашем базовом request (App\Http\Requests\Request). И не забывайте подключить класс Illuminate\Contracts\Validation\Validator:

 

/**
 * {@inheritdoc}
 */
protected function formatErrors(Validator $validator)
{
    return $validator->errors()->all();
}

 

Настройка сообщений об ошибках

 

Вы можете кастомизировать сообщения об ошибках, используя в form request метод messages. Этот метод должен возвращать массив атрибутов/правил и их соответствующие сообщения об ошибках:

 

/**
 * Get the error messages for the defined validation rules.
 *
 * @return array
 */
public function messages()
{
    return [
        'title.required' => 'A title is required',
        'body.required'  => 'A message is required',
    ];
}

 

Создание валидаторов вручную

 

Если вы не хотите использовать трейт ValidatesRequests и его метод validate, можно создать экземпляр валидатора вручную с помощью фасада Validator, используя метод make:

 

<?php

namespace App\Http\Controllers;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class PostController extends Controller
{
    /**
     * Store a new blog post.
     *
     * @param  Request  $request
     * @return Response
     */
    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'title' => 'required|unique:posts|max:255',
            'body' => 'required',
        ]);

        if ($validator->fails()) {
            return redirect('post/create')
                        ->withErrors($validator)
                        ->withInput();
        }

        // Store the blog post...
    }
}

 

Первый аргумент, передаваемый в метод make, получает данные для проверки. Вторым аргументом идут правилами проверки, которые должны применяться к данным.

После проверки, если валидация не будет пройдена, вы можете использовать метод withErrors для загрузки ошибок во flash-переменные. При использовании этого метода переменная $errors будет автоматически передаваться в ваши макеты, после перенаправления, что позволяет легко отображать данные пользователю. Метод withErrors принимает экземпляр валидатора и MessageBag или простой массив.

Автоматическое перенаправление

 

Если вы хотите создать экземпляр валидации вручную, но все же воспользоваться автоматической переадресацией трейта ValidatesRequest, можно вызвать метод validate в существующим экземпляре. После того, как проверка терпит неудачу, пользователь будет автоматически перенаправляться, в случае с AJAX-запросом, как и ранее в ответ отправится JSON:

 

Validator::make($request->all(), [
    'title' => 'required|unique:posts|max:255',
    'body' => 'required',
])->validate();

 

MessageBag

 

Если у вас есть несколько форм на одной странице, которые необходимо провалидировать, вам понадобится MessageBag — он позволяет получать сообщения об ошибках для определенной формы. Просто передайте имя в качестве второго аргумента withErrors:

 

return redirect('register')
            ->withErrors($validator, 'login');

 

You may then access the named MessageBag instance from the $errors variable:

 

{{ $errors->login->first('email') }}

 

Хук после валидации

 

Валидатор также позволяет вам использовать функции обратного вызова после завершения всех проверок. Это позволяет легко выполнять дальнейшие проверки и даже добавить больше сообщений об ошибках в коллекции сообщений. Чтобы начать работу, используйте метод after на экземпляре валидатора:

 

$validator = Validator::make(...);

$validator->after(function ($validator) {
    if ($this->somethingElseIsInvalid()) {
        $validator->errors()->add('field', 'Something is wrong with this field!');
    }
});

if ($validator->fails()) {
    //
}

 

Работа с сообщениями об ошибках

 

После вызова метода errors в экземпляре валидатора, вы получаете экземпляр Illuminate\Support\MessageBag, который имеет целый ряд удобных методов для работы с сообщениями об ошибках. Переменная $errors, которая автоматически становится доступной для всех макетов, также является экземпляром класса MessageBag.

 

Извлечение первого для поля сообщения об ошибке

 

Чтобы получить первое сообщения об ошибке для заданного поля используйте метод first:

 

$errors = $validator->errors();

echo $errors->first('email');

 

 

Извлечение всех сообщений об ошибках для одного поля

 

Для того, чтобы получить массив всех сообщений об ошибках для одного поля, необходимо использовать метод get:

 

foreach ($errors->get('email') as $message) {
    //
}

 

Если выполняется проверка поля формы с массивом, можно получить все сообщения для каждого из элементов массива с помощью символа *:

 

foreach ($errors->get('attachments.*') as $message) {
    //
}

 

 

Получение всех сообщений об ошибках для всех полей

 

Чтобы извлечь массив всех сообщений для всех полей, используйте метод all:

 

foreach ($errors->all() as $message) {
    //
}

 

 

Определить наличие сообщения для определенного поля

 

Метод has может определять наличие сообщения об ошибках для данного поля:

 

if ($errors->has('email')) {
    //
}

 

Пользовательские сообщения об ошибках

 

При необходимости, вы можете использовать свои сообщения об ошибках вместо значений по умолчанию. Существует несколько способов для указания кастомных сообщений. Во-первых, можно передать сообщения в качестве третьего аргумента в метод Validator::make:

 

$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!',
];

 

 

Указание собственных сообщений в файлах локализации

 

Также можно определять сообщения в файле локализации вместо того, чтобы передавать их в валидатор напрямую. Для этого добавьте сообщения в массив custom файла локализации resources/lang/xx/validation.php.

 

'custom' => [
    'email' => [
        'required' => 'We need to know your e-mail address!',
    ],
],

 

 

Указание пользовательских атрибутов в файлах локализации

 

Если вы хотите, чтобы :attribute был заменен на кастомное имя, можно указать в массиве attributes файле локализации resources/lang/xx/validation.php:

 

'attributes' => [
    'email' => 'email address',
],

 

Доступные правила валидации

 

 

accepted

 

Поле должно быть в значении yes, on или 1. Это полезно для проверки принятия правил и лицензий.

 

active_url

 

Поле должно иметь действительную A или AAAA DNS-запись согласно функции PHP dns_get_record.

 

after:date

 

Поле проверки должно быть после date. Строки приводятся к датам функцией strtotime:

 

'start_date' => 'required|date|after:tomorrow'

 

Вместо того чтобы приводить строки к датам, вы можете указать другое поле для сравнения даты:

 

'finish_date' => 'required|date|after:start_date'

 

 

after_or_equal:date

 

Поле проверки должно быть после или равно date. Для получения дополнительной информации смотрите правило after

 

alpha

 

Поле должно содержать только алфавитные символы.

 

alpha_dash

 

Поле можно содержать только алфавитные символы, цифры, знаки подчёркивания _ и дефисы -.

 

alpha_num

 

Поле можно содержать только алфавитные символы и цифры.

 

array

 

Поле должно быть PHP-массивом.

 

before:date

 

Поле должно быть датой более ранней, чем заданная дата. Строки приводятся к датам функцией strtotime.

 

before_or_equal:date

 

Поле должно быть более ранней или равной заданной дате. Строки приводятся к датам функцией 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

 

Поле должно соответствовать заданному формату. Необходимо использовать функцию date или date_format при проверке поля, но не обе.

 

different:field

 

Значение проверяемого поля должно отличаться от значения поля field.

 

digits:value

 

Поле должно быть числовым и иметь точную длину значения.

 

digits_between:min,max

 

Длина значения поля проверки должна быть между min и max.

 

dimensions

 

Файл изображения должен иметь ограничения согласно параметрам:

 

'avatar' => 'dimensions:min_width=100,min_height=200'

 

Доступные ограничения: min_width, max_width, min_height, max_height, width, height, ratio.

Ограничение ratio должно быть представлено как ширина к высоте. Это может быть обыкновенная (3/2) или десятичная (1.5) дробь:

 

'avatar' => 'dimensions:ratio=3/2'

 

Поскольку это правило требует несколько аргументов, вы можете использовать метод Rule::dimensions:

 

use Illuminate\Validation\Rule;

Validator::make($data, [
    'avatar' => [
        'required',
        Rule::dimensions()->maxWidth(1000)->maxHeight(500)->ratio(3 / 2),
    ],
]);

 

 

distinct

 

При работе с массивами, поле не должно иметь повторяющихся значений.

 

'foo.*.id' => 'distinct'

 

 

email

 

Поле должно быть корректным адресом e-mail.

 

exists:table,column

 

Поле должно существовать в указанной таблице базы данных.

 

Базовое использование правила Exists

 

 

'state' => 'exists:states'

 

 

Указание пользовательского названия столбца

 

 

'state' => 'exists:states,abbreviation'

 

Иногда может потребоваться подключение к базе данных и использование в запросе exists, этого можно добиться путем добавления к соединению название таблицы, используя синтаксис с точкой:

 

'email' => 'exists:connection.staff,email'

 

Если бы вы хотите модифицировать запрос, можно использовать класс Rule, в данном примере мы будем использовать массив вместо знака |:

 

use Illuminate\Validation\Rule;

Validator::make($data, [
    'email' => [
        'required',
        Rule::exists('staff')->where(function ($query) {
            $query->where('account_id', 1);
        }),
    ],
]);

 

 

file

 

Поле должно быть успешно загруженным файлом.

 

filled

 

Поле не должно быть пустым.

 

image

 

Загруженный файл должен быть в формате jpeg, png, bmp, gif или svg.

 

in:foo,bar,...

 

Значение поля должно быть одним из перечисленных. Поскольку это правило иногда вынуждает вас использовать функцию implode, для этого случая есть метод Rule::in:

 

use Illuminate\Validation\Rule;

Validator::make($data, [
    'zones' => [
        'required',
        Rule::in(['first-zone', 'second-zone']),
    ],
]);

 

 

in_array:anotherfield

 

В массиве должны существовать значения anotherfield.

 

integer

 

Поле должно иметь корректное целочисленное значение.

 

ip

 

Поле должно быть корректным IP-адресом.

 

ipv4

 

Поле должно быть IPv4-адресом.

 

ipv6

 

Поле должно быть IPv6-адресом.

 

json

 

Поле должно быть валидной строкой JSON.

 

max:value

 

Значение поля должно быть меньше или равно value. Размеры строк, чисел и файлов трактуются аналогично правилу size.

 

mimetypes:text/plain,...

 

MIME-тип загруженного файла должен быть одним из перечисленных:

 

'video' => 'mimetypes:video/avi,video/mpeg,video/quicktime'

 

Чтобы определить MIME-тип загруженного файла, фреймворк будет читать содержимое и пытаться угадать MIME-тип, который может отличаться от того, что указал пользователь.

 

mimes:foo,bar,...

 

MIME-тип загруженного файла должен быть одним из перечисленных.

 

Основное использование MIME-правила

 

 

'photo' => 'mimes:jpeg,bmp,png'

 

Даже если необходимо только указать расширение, это правило проверяет MIME-тип файла, читая содержимое файла и пытаясь угадать его.

Полный список MIME-типов и соответствующие им расширения можно найти в: https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types

 

min:value

 

Значение поля должно быть больше value. Размеры строк, чисел и файлов трактуются аналогично правилу size.

 

nullable

 

Поле может быть равно null. Это особенно полезно при проверке примитивов, такие как строки и целые числа, которые могут содержать null значения.

 

not_in:foo,bar,...

 

Поле не должно быть включено в заданный список значений. Метод Rule::notIn можно использовать для конструирования этого правила:

 

use Illuminate\Validation\Rule;

Validator::make($data, [
    'toppings' => [
        'required',
        Rule::notIn(['sprinkles', 'cherries']),
    ],
]);

 

 

numeric

 

Поле должно иметь корректное числовое или дробное значение.

 

present

 

Поле для проверки должно присутствовать во входных данных, но может быть пустым.

 

regex:pattern

 

Поле должно соответствовать заданному регулярному выражению.

 

Примечание: Для использования regex может быть необходимо определить правила в виде массива вместо использования разделителя, особенно если регулярное выражение содержит символ разделителя.

 

required

 

Проверяемое поле должно иметь непустое значение. Поле считается пустым, если одно из следующих значений верно:

  • Если значение равно null.
  • Если значение — пустая строка.
  • Если значение является пустым массивом или пустым объектом Countable.
  • Если значение это загруженный файл без пути.

 

required_if:anotherfield,value,...

 

Поле должно присутствовать и не быть пустым, если anotherfield равно любому value.

 

required_unless:anotherfield,value,...

 

Поле должно присутствовать и не быть пустым, за исключением случая, когда anotherfield равно любому 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 размер. Для строковых данных value соответствует количество символов, для массива size соответствует количеству элементов массива, для чисел — число, для файлов — размер в килобайтах.

 

string

 

Поле должно быть строкой. Если вы хотите, чтобы поле было null, следует доолнитель указать это полю правило nullable.

 

timezone

 

Поле должно содержать идентификатор часового пояса (таймзоны), один из перечисленных в php-функции timezone_identifiers_list.

 

unique:table,column,except,idColumn

 

Значение поля до

Вопросы / Комментарии / Отзывы