在Laravel 8中通过验证保护模型

在Laravel 8中通过验证保护模型,laravel,validation,sanitization,laravel-8,Laravel,Validation,Sanitization,Laravel 8,我有数据库表phones和字段phone\u number。我有一个手机模型。我想以固定格式(经过消毒)保存电话,并使用已填充的电话号码(已验证) 代码中有很多地方我或我的同事需要保存手机。我不相信,他们都会费心检查电话号码是否填写正确。我不想指望前端JS验证,或者数据库notnullcheck 所以我认为对手机进行消毒和验证的最佳场所是手机模型本身 我怎样才能在Laravel8.x中以最干净的方式做到这一点 我在互联网上发现了许多类似的问题,但提出的解决方案要么编写大量代码并令人厌恶地扭曲框架

我有数据库表
phones
和字段
phone\u number
。我有一个手机模型。我想以固定格式(经过消毒)保存电话,并使用已填充的
电话号码
(已验证)

代码中有很多地方我或我的同事需要保存手机。我不相信,他们都会费心检查电话号码是否填写正确。我不想指望前端JS验证,或者数据库
notnull
check

所以我认为对手机进行消毒和验证的最佳场所是手机模型本身

我怎样才能在Laravel8.x中以最干净的方式做到这一点

我在互联网上发现了许多类似的问题,但提出的解决方案要么编写大量代码并令人厌恶地扭曲框架,要么人们根本没有抓住问题所在

也许我应该补充一句,我希望这一切自动发生。因此,任何试图以错误格式
$phone->save()
phone::create()
手机的人都将以ValidationException结束

编辑2:提供者/观察者-我看的方向正确吗

编辑3:事件?因此,在我的模型中,我应该做如下操作:

use Notifiable;

protected $dispatchesEvents = [
    'validating' => PhoneSanitize::class,
    'saving'     => PhoneValidate::class,
];
编辑4:或者您认为在模型级别验证数据是个坏主意吗?我读过这篇文章:


我觉得这是个好主意。但如何在拉威尔做到这一点呢?

所以现在我用Observer解决了这个问题

在shell中运行:

php artisan make:observer PhoneObserver --model=Phone
然后在“App/observators”中,您将找到带有一些方法的“phoneobservator”。添加“保存(电话$Phone)”方法,您可以在其中清理和验证电话数据。“saving()”应可用于创建和更新模型

如果您在此处抛出(特别是!)ValidationException并显示错误消息,Laravel将使用该消息将您重定向回表单:

/* App/Observers/PhoneObserver.php */

use App\Models\Phone;
use Illuminate\Validation\ValidationException;

class PhoneObserver
{
    public function saving(Phone $phone) 
    {
        /* Do your sanitisation */
        /* Do your validation */
        if (something wrong) {
            throw ValidationException::withMessage(['phone_number' => 'Phone number has wrong format...']);
        }
    }
}
然后,您必须在“boot()”方法的“App/Providers/EventServiceProvider.php”中“注册”此观察者:

我不知道这是最好的地方还是最干净的方式,但它现在适合我,我的手机会自动保护,不会以错误的格式保存


希望这对别人有帮助。我是拉威尔的新手&我花了好几个星期寻找答案。如果我找到更好的方法,我会在这里发布。

在模型级别验证数据是一个坏主意,因为验证逻辑更多地是关于表单请求的

也就是说,您可以使用来清理(甚至验证)模型中的输入

namespace-App\Models;
使用Illumb\Support\Facades\Validator;
类电话扩展模型
{
// ...
公共函数setPhoneNumberAttribute($value)
{
//你要消毒吗
// ...
//进行验证
验证器::make([
“电话号码”=>$value,
], [
'phone_number'=>['required'],//定义验证规则
])->验证();
$this->attributes['phone_number']=$value;
}
// ...
}

如果验证失败,将抛出
illumb\validation\ValidationException
,并自动重定向用户,或者在AJAX请求的情况下,将返回JSON响应。

是否尝试创建表单验证?你可以找到更多关于它的信息是的,我找到了。但我正在寻找如何在模型中进行验证的方法谢谢。但这真的是个坏主意吗?如果我不仅通过web表单处理这些数据,还通过API或命令行处理这些数据呢?如果您想使用命令行并创建自己的控制台命令,您可能需要使用类似于包的东西来验证Artisan控制台命令中的输入。谢谢,我不知道这个包。但在这种情况下,我必须编写两次验证规则。那么API访问呢?是否有API验证程序包,我将在其中第三次编写相同的验证规则?这不是违反了DRY原则吗?API请求本质上是HTTP请求。因此,对表单和API请求应用相同的验证逻辑是完全正确的。为了避免重复验证规则,您可以将其存储在模型中的静态属性中,如下所示:
publicstatic$rules=['phone_number'=>['required']。然后在模型内部使用
self::$rules
访问它,在模型外部使用
Phone::$rules
访问它。
*/ App/Providers/EventServiceProvider.php */

use App\Models\Phone;
use App\Observers\PhoneObserver.php

public function boot()
{
    Phone::observe(PhoneObserver::class);
}