Проверка — это особенность моделей Laravel Eloquent, которая гарантирует, что модели соответствуют критериям проверки перед сохранением. Если они не считаются действительными, модель не будет сохранена, а ошибки проверки станут доступны.
Проверка позволяет использовать несколько наборов правил, вводить идентификатор модели в unique
правила проверки и создавать исключения в случае неудачных проверок. Он небольшой и гибкий, поэтому легко вписывается в ваш рабочий процесс и помогает сохранять только действительные данные.
Хотите использовать валидацию в Laravel 4.2+? Загляните в ветку 0.10.x для получения документации и инструкций по установке.
Версия Laravel 4.2 лучше подходит для проверки формы; он поддерживает пользовательские сообщения проверки, правила подтверждения и несколько наборов правил. Поскольку в Laravel 5.0 есть проверка FormRequest
проверка теперь предназначена для обеспечения достоверности ваших основных данных и предоставления проверки формы фреймворку.
Хотите использовать проверку на Laravel 5.0–5.2? Загляните в ветку 2.x для получения документации и инструкций по установке.
В версиях Laravel 5.0–5.2 использовался устаревший контракт ValidationException
из среды Laravel. В Laravel 5.3 мы теперь расширяем основное исключение ValidationException
, что означает, что фреймворк автоматически перенаправляет обратно с ошибками при возникновении ошибки проверки, во многом так же, как это делает FormRequest
.
Просто читайте дальше – эти инструкции для вас!
Просто перейдите в каталог вашего проекта, где находится файл composer.json
, и введите:
композитору требуется Watson/проверка
Посмотрите инструкции по установке для Laravel 4.2+. Ознакомьтесь с инструкциями по установке Laravel 5.0–5.2.
Сначала добавьте признак в свою модель и при необходимости добавьте правила и сообщения проверки.
используйте WatsonValidatingValidatingTrait; класс Post расширяет Eloquent { использовать ValidatingTrait; protected $rules = [ 'title' => 'required', 'slug' => 'required|unique:posts,slug', 'content' => 'required' ]; }
Вы также можете добавить этот признак в BaseModel
если вы его используете, и он будет работать со всеми моделями, находящимися на его основе, в противном случае вы можете просто расширить WatsonValidatingValidatingModel
вместо Eloquent
.
Примечание: вам нужно будет установить свойство $rules
для любых моделей, которые наследуются от BaseModel
, использующего этот признак, или иным образом установить пустой массив в качестве $rules
для BaseModel
. Если вы этого не сделаете, вы неизбежно получите LogicException with message 'Relationship method must return an object of type IlluminateDatabaseEloquentRelationsRelation'
.
Теперь у вас есть доступ к некоторым приятным функциям.
// Проверяем, действительна ли модель. $post->isValid(); // true// Или проверяем, неверно оно или нет. $post->isInvalid(); // false// Как только вы определили достоверность модели, // вы можете получить ошибки. $post->getErrors(); // ошибки MessageBag
Проверка модели также становится очень простой.
if ( ! $post->save()) {// Oops.return redirect()->route('posts.create') ->withErrors($post->getErrors()) ->withInput(); } return redirect()->route('posts.show', $post->id) ->withSuccess("Ваше сообщение успешно сохранено.");
В противном случае, если вы предпочитаете использовать исключения при проверке моделей, вы можете использовать метод saveOrFail()
. Теперь при попытке сохранить недопустимую модель будет возникать исключение.
$post->saveOrFail();
Вам не нужно перехватывать исключение , если вы этого не хотите. Laravel знает, как обрабатывать исключение ValidationException
, и автоматически перенаправляет обратно с вводом формы и ошибками. Если вы хотите справиться с этим самостоятельно, вы можете это сделать.
попробуйте {$post->saveOrFail(); } catch (WatsonValidatingValidationException $e) {$errors = $e->getErrors(); return redirect()->route('posts.create') ->withErrors($ошибки) ->withInput(); }
Обратите внимание: вы можете просто передать исключение методу withErrors()
, например withErrors($e)
и Laravel будет знать, как с ним справиться.
Если вы используете модель и хотите выполнить сохранение без проверки, вы можете это сделать. Это вернет тот же результат, как если бы вы вызвали save()
для модели без признака.
$post->forceSave();
Если вы предпочитаете, чтобы исключения создавались по умолчанию при использовании метода save()
вместо использования saveOrFail()
вы можете просто установить следующее свойство для своей модели или BaseModel
.
/** * Должна ли модель выдавать исключение ValidationException, если * проверка не пройдена. Если не установлено, по умолчанию будет установлено значение false. * * @var boolean */protected $throwValidationExceptions = true;
Если вы хотите выполнить однократное сохранение с использованием исключений или возвращаемых значений, вы можете использовать методы saveOrFail()
и saveOrReturn
.
Чтобы отображать пользовательские сообщения об ошибках проверки, просто добавьте свойство $validationMessages
в свою модель.
/** * Сообщения проверки, передаваемые валидатору. * * @var array */protected $validationMessages = ['slug.unique' => "Этот пул уже используется в другом сообщении."];
Возможно, вы заметили, что мы используем unique
правило для пула, которое не работало бы, если бы мы обновляли сохраняемую модель. К счастью, служба проверки позаботится об этом за вас и добавит первичный ключ модели к правилу, чтобы правило работало должным образом; игнорируя текущую модель.
Вы можете настроить эту функциональность, установив свойство $injectUniqueIdentifier
в своей модели.
/** * Должна ли модель вводить свой идентификатор в уникальные правила проверки * перед попыткой проверки. Если это свойство * не установлено в модели, по умолчанию оно будет иметь значение true. * * @var boolean */protected $injectUniqueIdentifier = true;
По умолчанию мы поддерживаем unique
правило, предоставленное Laravel. Мы также поддерживаем популярное правило felixkiss/uniquewith-validator, но вам необходимо согласиться. Просто добавьте use WatsonValidatingInjectorsUniqueWithInjector
после импорта проверяющего признака.
Если хотите, легко поддерживать и дополнительные правила внедрения. Предположим, вы хотите поддержать дополнительное правило unique_ids
, которое просто принимает первичный ключ модели (по какой-либо причине). Вам просто нужно добавить правило в верблюжьем стиле, которое принимает любые существующие параметры и имя поля и возвращает правило замены.
/** * Подготовьте правило unique_ids, добавив при необходимости идентификатор модели. * * @param array $parameters * @param string $field * @return string */protected function подготовитьUniqueIdsRule($parameters, $field) {// Выполняйте замену только в том случае, если модель сохранилась.if ($this->exists) {return 'unique_ids:' . $this->getKey(); } вернуть 'unique_ids'; }
В этом случае, если модель была сохранена и имеет первичный ключ 10
, правило unique_ids
будет заменено на unique_ids:10
.
Во время процесса проверки признак запускает различные события, к которым вы можете подключиться, чтобы повлиять на процесс проверки.
Чтобы подключиться, вам сначала нужно добавить свойство $observeables
в вашу модель (или базовую модель). Это просто сообщает Eloquent, что ваша модель может реагировать на эти события.
/** * Наблюдаемые события, доступные пользователю * * @var array */protected $observables = ['validating', 'validated'];
Когда произойдет проверка, будет запущено событие eloquent.validating: ModelName
, где параметр $event
будет saving
или restoring
. Например, если вы обновляли модель AppUser
в пространстве имен, событие будет иметь eloquent.validating: AppUser
. Если вы прослушиваете любое из этих событий и возвращаете значение, вы можете полностью предотвратить выполнение проверки.
Event::listen('eloquent.validating:*', function($model, $event) {// Псевдорусская рулетка validation.if (rand(1, 6) === 1) {return false; } });
После выполнения проверки вы также можете подключиться к ряду validated
событий для passed
, failed
и skipped
событий. Если в приведенном выше примере не удалось выполнить проверку, вы можете получить событие eloquent.validated: AppUser
.
В настоящее время в Laravel существует ошибка (см. проблему № 1181), которая не позволяет событиям модели запускаться более одного раза в наборе тестов. Это означает, что первый тест, использующий модельные тесты, пройдет успешно, но все последующие тесты не пройдут. В этой теме перечислено несколько временных решений, которые вы можете использовать, чтобы ваши тесты тем временем прошли успешно.
Поскольку Laravel перешел на Liferaft с целью отслеживания ошибок и запросов на включение, упомянутая выше проблема может быть недоступна. В этом Gist есть пример TestCase.php
, который показывает, как сбросить события всех ваших моделей между тестами, чтобы они работали должным образом.
Существует несколько способов использования модели проверки валидации в ваших контроллерах, однако вот один пример, в котором используется новый FormRequest в Laravel 5 (если вы хотите увидеть другой пример контроллера без FormRequest, отметьте версия этого пакета 4.2+.
В этом примере ваш код остается чистым, позволяя FormRequest обрабатывать проверку вашей формы, а модели — собственную проверку. Включив исключения проверки, вы можете уменьшить количество повторяющегося кода контроллера (блоки try/catch) и обрабатывать исключения проверки модели глобально (запросы вашей формы должны сохранять ваши модели действительными, поэтому, если ваша модель становится недействительной, это исключительное событие).
<?php пространство имен AppHttpControllers;use AppHttpRequestsPostFormRequest;use IlluminateRoutingController;класс PostsController расширяет контроллер {protected $post;публичная функция __construct(Post $post) {$this->post = $post; }// ...публичное хранилище функций(PostFormRequest $request) {// Сообщение выдаст исключение, если оно недействительно. $post = $this->post->create($request->input());// Сообщение было успешно сохранено.return redirect()->route( 'posts.show', $post); } }
Затем вы можете перехватить исключение проверки модели в своем app/Exceptions/Handler.php
и обработать его по своему усмотрению.
рендеринг общедоступной функции ($request, Exception $e) {if ($e instanceof WatsonValidatingValidationException) {return back()->withErrors($e)->withInput(); }parent::render($request, $e); }