rinvex / tmp-watson-validating
Eloquent模型验证特性。
Requires
- php: ^7.4.0 || ^8.0.0
- illuminate/contracts: ^8.0.0
- illuminate/database: ^8.0.0
- illuminate/events: ^8.0.0
- illuminate/support: ^8.0.0
- illuminate/validation: ^8.0.0
Requires (Dev)
- mockery/mockery: ^1.3.1
- phpunit/phpunit: ~9.0
- dev-master
- 6.0.4
- 6.0.3
- 6.0.2
- 6.0.1
- 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-08-06 23:01:08 UTC
README
临时将包名改为 "rinvex/tmp-watson-validating",以便在Packagist上发布。
这是一个临时分支,直到作者发布新版本,完全支持Laravel v8+
Validating,Laravel的验证特性
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中存在一个bug(请参阅问题#1181),这阻止了在测试套件中模型事件多次触发。这意味着第一个使用模型测试的测试将通过,但任何随后的测试都将失败。该线程中列出了几个临时解决方案,您可以使用它们在短时间内使测试通过。
由于Laravel已切换到Liferaft用于跟踪bug和pull请求,上述提到的问题可能不可用。此Gist有一个示例TestCase.php
,展示了如何在测试之间重置所有模型的events,以便它们按预期工作。
控制器使用
您可以通过多种方式在控制器中使用验证模型,但这里有一个使用Laravel 5中新的FormRequest的示例(如果您想看另一个不使用FormRequest的控制器示例,请查看此包的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); }