miladtech / tmp-miladtech-validating
Eloquent模型验证特性。
Requires
- php: ^8.1
- illuminate/contracts: ^8.0.0 || ^9.0.0
- illuminate/database: ^8.0.0 || ^9.0.0
- illuminate/events: ^8.0.0 || ^9.0.0
- illuminate/support: ^8.0.0 || ^9.0.0
- illuminate/validation: ^8.0.0 || ^9.0.0
Requires (Dev)
- mockery/mockery: ^1.3.1
- phpunit/phpunit: ~9.0
README
临时将包名更改为"miladtech/tmp-miladtech-validating",以便在Packagist上发布。
这是一个临时的分支包,直到作者发布新版本,完全支持Laravel v8+
Validating,Laravel的验证特性
Validating是Laravel Eloquent模型的特性,确保在保存之前模型满足其验证标准。如果被认为无效,则模型不会被保存,并会提供验证错误。
Validating支持多个规则集,将模型ID注入到unique
验证规则中,并在验证失败时抛出异常。它小巧灵活,可以直接集成到您的流程中,并帮助您只保存有效数据。
安装
只需进入您的项目目录,其中包含composer.json
文件,并输入
composer require miladtech/validating
概述
首先,将特性添加到您的模型中,并根据需要添加验证规则和消息。
use MiladTech\Validating\ValidatingTrait; class Post extends Eloquent { use ValidatingTrait; protected $rules = [ 'title' => 'required', 'slug' => 'required|unique:posts,slug', 'content' => 'required' ]; }
如果您正在使用一个BaseModel
,也可以将特性添加到其中,并且它将对所有从其扩展的模型起作用。否则,您可以直接使用MiladTech\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 (MiladTech\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 \MiladTech\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
。
控制器使用
此示例通过允许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 \MiladTech\Validating\ValidationException) { return back()->withErrors($e)->withInput(); } parent::render($request, $e); }