watson / validating
Eloquent 模型验证特质。
Requires
- php: ^8.1
- illuminate/contracts: ~9.0|~10.0|~11.0
- illuminate/database: ~9.0|~10.0|~11.0
- illuminate/events: ~9.0|~10.0|~11.0
- illuminate/support: ~9.0|~10.0|~11.0
- illuminate/validation: ~9.0|~10.0|~11.0
Requires (Dev)
- mockery/mockery: ^1.4.4
- phpunit/phpunit: ~9.0
- dev-master
- 8.2.0
- 8.1.0
- 8.0.0
- 7.0.0
- 6.1.1
- 6.1.0
- 6.0.0
- 5.0.0
- 4.0.0
- 3.3.0
- 3.2.0
- 3.1.8
- 3.1.7
- 3.1.6
- 3.1.5
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.2
- 3.0.1
- 3.0.0
- 2.x-dev
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.1
- 2.1.0
- 2.0.1
- 2.0.0
- 1.0.9
- 1.0.8
- 1.0.7
- 1.0.6
- 1.0.5
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- 0.10.x-dev
- 0.10.10
- 0.10.9
- 0.10.8
- 0.10.7
- 0.10.6
- 0.10.5
- 0.10.4
- 0.10.3
- 0.10.2
- 0.10.1
- 0.10.0
- 0.9.5
- 0.9.4
- 0.9.3
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.4
- 0.8.3
- 0.8.2
- 0.8.1
- 0.8.0
- 0.7.13
- 0.7.12
- 0.7.11
- 0.7.10
- 0.7.9
- 0.7.8
- 0.7.7
- 0.7.6
- 0.7.5
- 0.7.4
- 0.7.3
- 0.7.2
- 0.7.1
- 0.7.0
- 0.6.3
- 0.6.2
- 0.6.1
- 0.6.0
- 0.5.1
- 0.5.0
- 0.4.1
- 0.4.0
- 0.3.0
- 0.2.0
- 0.1.1
- 0.1.0
This package is auto-updated.
Last update: 2024-09-13 22:58:51 UTC
README
Validating 是一个用于 Laravel Eloquent 模型的特质,确保在保存之前模型满足其验证标准。如果不认为是有效的,则模型不会被保存,并且将提供验证错误。
Validating 允许使用多个规则集,将模型 ID 注入 unique
验证规则,并在验证失败时抛出异常。它小巧灵活,适合您的流程,并帮助您仅保存有效数据。
Laravel 4.2+
正在寻找 Laravel 4.2+ 上的 Validating?请查看 0.10.x 分支的文档和安装说明。
Laravel 4.2 版本更适合进行表单验证;它支持自定义验证消息、确认规则和多个规则集。由于 Laravel 5.0 有 FormRequest
验证,Validating 现在旨在保持核心数据的有效性,并将表单验证留给框架。
Laravel 5.0 - 5.2
正在寻找 Laravel 5.0 到 5.2 上的 Validating?请查看 2.x 分支的文档和安装说明。
Laravel 5.0 - 5.2 版本使用了已弃用的 Laravel 框架的 ValidationException
合同。对于 Laravel 5.3,我们现在扩展了核心验证的 ValidationException
,这意味着当发生验证错误时,框架将自动返回错误,就像 FormRequest
一样。
Laravel 5.3+
继续阅读 - 这些说明适用于您!
安装
只需转到包含 composer.json
文件的您的项目目录,并输入
composer require watson/validating
查看 Laravel 4.2+ 的安装说明。 查看 Laravel 5.0 - 5.2 的安装说明。
概述
首先,将特质添加到您的模型中,并根据需要添加验证规则和消息。
use Watson\Validating\ValidatingTrait; class Post extends Eloquent { use ValidatingTrait; protected $rules = [ 'title' => 'required', 'slug' => 'required|unique:posts,slug', 'content' => 'required' ]; }
如果您正在使用 BaseModel
,也可以将特质添加到其中,并且它将在所有扩展自它的模型上工作。否则,您可以直接扩展 Watson\Validating\ValidatingModel
而不是 Eloquent
。
注意:您需要为扩展自使用该特质的 BaseModel
的任何模型设置 $rules
属性,或者将 BaseModel
的 $rules
设置为空数组。如果不这样做,您最终会遇到 LogicException with message 'Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation'
。
现在,您有了一些令人愉快的功能。
// Check whether the model is valid or not. $post->isValid(); // true // Or check if it is invalid or not. $post->isInvalid(); // false // Once you've determined the validity of the model, // you can get the errors. $post->getErrors(); // errors MessageBag
模型验证也变得非常简单。
if ( ! $post->save()) { // Oops. return redirect()->route('posts.create') ->withErrors($post->getErrors()) ->withInput(); } return redirect()->route('posts.show', $post->id) ->withSuccess("Your post was saved successfully.");
否则,如果您在验证模型时更喜欢使用异常,则可以使用 saveOrFail()
方法。现在,在尝试保存无效模型时将抛出异常。
$post->saveOrFail();
如果您不想,您不需要 捕获异常。Laravel 知道如何处理 ValidationException
并会自动返回带有表单输入和错误的表单。不过,如果您想自行处理,也可以。
try { $post->saveOrFail(); } catch (Watson\Validating\ValidationException $e) { $errors = $e->getErrors(); return redirect()->route('posts.create') ->withErrors($errors) ->withInput(); }
注意,您可以直接将异常传递给 withErrors()
方法,例如 withErrors($e)
,Laravel 将知道如何处理它。
绕过验证
如果你在使用该模型并希望执行跳过验证的保存操作,你可以这样做。这将返回与你在没有特性情况下调用 save()
方法相同的结果。
$post->forceSave();
默认验证异常
如果你希望在使用 save()
方法时默认抛出异常,而不是必须使用 saveOrFail()
,你只需在你的模型或 BaseModel
上设置以下属性。
/** * Whether the model should throw a ValidationException if it * fails validation. If not set, it will default to false. * * @var boolean */ protected $throwValidationExceptions = true;
如果你想使用异常或返回值进行一次性保存,可以使用 saveOrFail()
和 saveOrReturn
方法。
验证消息
要显示自定义验证错误消息,只需将 $validationMessages
属性添加到你的模型中。
/** * Validation messages to be passed to the validator. * * @var array */ protected $validationMessages = [ 'slug.unique' => "Another post is using that slug already." ];
唯一规则
你可能已经注意到我们在 slug 上使用了 unique
规则,如果我们在更新持久化模型时使用,这将不起作用。幸运的是,验证将为你处理这个问题,并将模型的唯一键追加到规则中,这样规则就可以按预期工作;忽略当前模型。
你可以通过在模型上设置 $injectUniqueIdentifier
属性来调整此功能。
/** * Whether the model should inject it's identifier to the unique * validation rules before attempting validation. If this property * is not set in the model it will default to true. * * @var boolean */ protected $injectUniqueIdentifier = true;
默认情况下,我们支持 Laravel 提供的 unique
规则。我们还支持流行的 felixkiss/uniquewith-validator 规则,但你需要选择加入。在你导入验证特性后,只需添加 use \Watson\Validating\Injectors\UniqueWithInjector
。
如果你喜欢,也可以轻松地支持额外的注入规则。比如说,如果你想支持一个名为 unique_ids
的额外规则,它简单地取模型的唯一键(出于某种原因)。你只需要添加一个接受任何现有参数和字段名的驼峰式规则,并返回替换规则的规则。
/** * Prepare a unique_ids rule, adding a model identifier if required. * * @param array $parameters * @param string $field * @return string */ protected function prepareUniqueIdsRule($parameters, $field) { // Only perform a replacement if the model has been persisted. if ($this->exists) { return 'unique_ids:' . $this->getKey(); } return 'unique_ids'; }
在这种情况下,如果模型已保存并且具有唯一的键 10
,则规则 unique_ids
将被替换为 unique_ids:10
。
事件
在验证过程中,特性会触发各种事件,你可以将这些事件挂钩以影响验证过程。
要挂钩,你首先需要将 $observeables
属性添加到你的模型(或基本模型)中。这仅仅让 Eloquent 知道你的模型可以响应这些事件。
/** * User exposed observable events * * @var array */ protected $observables = ['validating', 'validated'];
当即将进行验证时,将触发 eloquent.validating: ModelName
事件,其中 $event
参数将是 saving
或 restoring
。例如,如果你正在更新一个命名空间模型 App\User
,则事件将是 eloquent.validating: App\User
。如果你监听到这些事件之一并返回一个值,你可以完全阻止验证发生。
Event::listen('eloquent.validating:*', function($model, $event) { // Pseudo-Russian roulette validation. if (rand(1, 6) === 1) { return false; } });
在验证发生后,也有多种 validated
事件你可以挂钩,包括 passed
、failed
和 skipped
事件。对于上面的失败验证示例,你可以得到事件 eloquent.validated: App\User
。
测试
目前 Laravel 中存在一个错误(见问题 #1181),这阻止了模型事件在测试套件中多次触发。这意味着第一个使用模型测试的测试将通过,但后续的测试将失败。在该线程中列出了几个临时解决方案,你可以使用这些解决方案在同时使你的测试通过。
由于 Laravel 已经切换到 Liferaft 用于跟踪错误和拉取请求,上面提到的问题可能不可用。此 Gist 有一个示例 TestCase.php
,展示了如何在测试之间重置所有模型的 events,以便它们按预期工作。
控制器使用
在控制器中使用验证模型,您有多种方法,但这里有一个示例,它利用了 Laravel 5 中的新功能 FormRequest(如果您想看一个不使用 FormRequest 的控制器示例,请查看此包的 4.2+ 版本:4.2+ 版本)。
这个示例通过让 FormRequest 处理表单验证,模型处理自己的验证来保持代码的整洁。通过启用验证异常,您可以减少重复的控制器代码(try/catch 块)并全局处理模型验证异常(您的表单请求应该保持模型有效,所以如果模型变得无效,它是一个异常事件)。
<?php namespace App\Http\Controllers; use App\Http\Requests\PostFormRequest; use Illuminate\Routing\Controller; class PostsController extends Controller { protected $post; public function __construct(Post $post) { $this->post = $post; } // ... public function store(PostFormRequest $request) { // Post will throw an exception if it is not valid. $post = $this->post->create($request->input()); // Post was saved successfully. return redirect()->route('posts.show', $post); } }
然后,您可以在 app/Exceptions/Handler.php
中捕获模型验证异常,并按需处理它。
public function render($request, Exception $e) { if ($e instanceof \Watson\Validating\ValidationException) { return back()->withErrors($e)->withInput(); } parent::render($request, $e); }