侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

在laravel框架中如何有效的验证器验证数据流程步骤

Laravel  /  管理员 发布于 4个月前   132

验证是任何现代项目必须具备的,在Laravel中,它是超级简单的开始。

在你的控制器方法中, 你可以调用一个方法, 传入请求, 和一个你想验证的规则数组.


这种方法是正确的吗? 这样做是错的吗?

当然不是,任何告诉你不对的人都需要用湿鱼打一巴掌。这种方法没有错;它是可行的,而且是可测试的。重要的是要记住,虽然它可以被改进,但它可能不需要改进。

下面, 我将带领你了解我在Laravel中的验证之旅, 我做了哪些改变以及为什么。让我们从头开始。


当我开始使用Laravel的时候, 我做的是文档中告诉我的, 简单明了. 

我会扩展app/Http/Controller并在这时调用$this->validate。我的控制器很有资源。

我的典型的存储方法看起来有点像下面的,现代的语法:

namespace App\Http\Controllers\Api;
 
class PostController extends Controller
{
    public function store(Request $request): JsonResponse
    {
        $this->validate($request, [
            'title' => 'required|string|min:2|max:255',
            'content' => 'required|string',
            'category_id' => 'required|exists:categories,id',
        ]);
 
        $post = Post::query()->create(
            attributes: [
                ...$request->validated(),
                'user_id' => auth()->id(),
            ],
        );
 
        return new JsonResponse(
            data: new PostResource(
                resource: $post,
            ),
            status: Http::CREATED->value,
        );
    }
}

除了创建逻辑之外,这个验证的工作方式没有任何问题。

我可以对它进行测试和管理,我知道它将按照我的要求进行验证。

所以,如果你的验证是这样的,那就好办了。


然后我转向了可调用的控制器,因为我更喜欢保持事情的简单性

--在这一点上它看起来是一样的,只是用一个调用方法代替了存储方法。

namespace App\Http\Controllers\Api\Posts;
 
class StoreController extends Controller
{
    public function __invoke(Request $request): JsonResponse
    {
        $this->validate($request, [
            'title' => 'required|string|min:2|max:255',
            'content' => 'required|string',
            'category_id' => 'required|exists:categories,id',
        ]);
 
        $post = Post::query()->create(
            attributes: [
                ...$request->validated(),
                'user_id' => auth()->id(),
            ],
        );
 
        return new JsonResponse(
            data: new PostResource(
                resource: $post,
            ),
            status: Http::CREATED->value,
        );
    }
}

在这之后,我发现表单请求是多么有用--以及在这些类中封装我的验证是如何帮助我的。

从那以后,我的控制器又发生了变化。这一次,它看起来像下面这样:

namespace App\Http\Controllers\Api\Posts;
 
class StoreController
{
    public function __invoke(StoreRequest $request): JsonResponse
    {
        $post = Post::query()->create(
            attributes: [
                ...$request->validated(),
                'user_id' => auth()->id(),
            ],
        );
 
        return new JsonResponse(
            data: new PostResource(
                resource: $post,
            ),
            status: Http::CREATED->value,
        );
    }
}

我不再需要扩展基础控制器,因为我不需要验证方法。

我可以很容易地将表单请求注入我的控制器的调用方法中,所有的数据都会被预先验证。

这使得我的控制器变得非常小和轻量级,因为我已经把验证推到了一个专门的类。

我的表单请求看起来是这样的:

namespace App\Http\Requests\Api\Posts;
 
class StoreRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }
 
    public function rules(): array
    {
        return [
             'title' => ['required', 'string', 'min:2', 'max:255',]
            'content' => ['required', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
        ];
    }
}

有一段时间,我坚持使用这种验证方式,因为同样,它没有什么问题。

如果你的验证看起来像这样,那就好办了。这也是可扩展、可测试和可重复的。

你可以在你使用HTTP请求和需要验证的任何地方注入这个。


不过,我们该何去何从?我们怎样才能改进这个?

这是我问自己的一个问题,并且被卡住了很长时间。让我解释一个场景,它让我对如何处理这个问题产生了疑问。


想象一下,你有一个项目,允许通过一个API、一个网络界面,也许还有命令行来创建帖子。

API和web界面可以共享表单请求,因为两者都可以被注入控制器中。

那么命令行呢?我们需要为此重复验证吗?

有些人可能会说,你不需要对命令行进行同样程度的验证,但你会想要添加一些验证。


我已经玩了一段时间验证器的想法了。

这不是什么新鲜事,所以我也不知道为什么花了这么长时间才想明白 至少对我来说,

验证器是包含验证任何请求--HTTP或其他--所必需的规则和信息的类。

让我告诉你一个可能的样子:

namespace App\Validators\Posts;
 
class StoreValidator implements ValidatorContract
{
    public function rules(): array
    {
        return [
             'title' => ['required', 'string', 'min:2', 'max:255',]
            'content' => ['required', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
        ];
    }
}

它开始很简单,只是一个我想集中存储这些验证规则的地方。

在那里,我可以根据需要对它进行扩展。

namespace App\Validators\Posts;
 
class StoreValidator implements ValidatorContract
{
    public function rules(): array
    {
        return [
             'title' => ['required', 'string', 'min:2', 'max:255',]
            'content' => ['required', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
        ];
    }
 
    public function messages(): array
    {
        return [
            'category_id.exists' => 'This category does not exist, you Doughnut',
        ];
    }
}

我可以添加一些东西,比如当我想定制验证信息时的信息。

我可以添加更多的方法来封装更多的验证逻辑。

但这在实践中是怎样的呢?让我们重新审视一下商店控制器的例子。

我们的控制器看起来是一样的,因为我们已经将验证移出,所以让我们看看表单请求:

namespace App\Http\Requests\Api\Posts;
 
class StoreRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }
 
    public function rules(): array
    {
        return (new StoreValidator())->rules();
    }
}

就这么简单,我可以把卡在一个类里的数组换掉,然后用一个专门针对我们要存储和验证这些信息的类来取代它。


我看到了另一种方法,我觉得有好有坏。让我给你讲讲。

我看到有些人把他们的验证规则放在Eloquent模型中。

现在我对这个方法没有100%的把握,因为我觉得我们会把目的混为一谈--然而,这也是很有创意的。

因为你想做的是把围绕这个模型如何被创建的规则保留在模型本身。

它知道自己的规则。这看起来有点像下面这样:

namespace App\Models;
 
class Post extends Model
{
    public static array $rules = [
             'title' => ['required', 'string', 'min:2', 'max:255',]
            'content' => ['required', 'string'],
            'category_id' => ['required', 'exists:categories,id'],
    ];
 
    // The rest of your model here.
}

这可以很容易地在表单请求中使用,并与你的模型保持一致,

所以你可以从一个关心这个问题的类中的一个中心点来控制它。

namespace App\Http\Requests\Api\Posts;
 
class StoreRequest extends FormRequest
{
    public function authorize(): bool
    {
        return true;
    }
 
    public function rules(): array
    {
        return Post::$rules;
    }
}

这些是你可以验证数据的几种方法。所有这些都是正确的,而且都可以进行测试。

你喜欢用哪种方式来处理你的验证?

你有什么方法没有在这里或文档中提到吗?


  • 上一条:
    在laravel项目中把七牛云空间的大量文件压缩打包下载流程步骤
    下一条:
    在go语言中json、tomal、yml、txt等配置文件读取示例代码
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在laravel框架中的5个HTTP客户端技巧分享(0个评论)
    • 在laravel项目中实现密码强度验证功能推荐扩展包:password-strength(0个评论)
    • Laravel Response Classes 响应类使用优化浅析(0个评论)
    • 在Laravel中使用FilePond上传文件及测试用例(0个评论)
    • 在laravel项目中第三方回调信息处理扩展包:flaky(0个评论)
    • 近期文章
    • 在laravel框架中的5个HTTP客户端技巧分享(0个评论)
    • 在go语言中使用FFmpeg库实现PCM音频文件编码为mp3格式文件流程步骤(0个评论)
    • gopacket免安装Pcap实现驱动层流量抓包流程步骤(0个评论)
    • 在laravel项目中实现密码强度验证功能推荐扩展包:password-strength(0个评论)
    • 在go语言中用filepath.Match()函数以通配符模式匹配字符串示例(0个评论)
    • Laravel Response Classes 响应类使用优化浅析(0个评论)
    • mysql中sql_mode的各模式浅析(0个评论)
    • 百度文心一言今天发布,个人第一批内测体验记录,不好别打我(0个评论)
    • 嘿加密世界让我们谈谈在共识中将中本聪主流化(0个评论)
    • 在go语言中寻找两个切片或数组中的相同元素/共同点/交集并集示例代码(0个评论)
    • 近期评论
    • 博主 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 @ xiaoB 你只管努力,剩下的叫给天意;天若有情天亦老,..
    • xiaoB 在

      2023年国务院办公厅春节放假通知:1月21日起休7天中评论 会不会春节放假后又阳一次?..
    • BUG4 在

      你翻墙过吗?国内使用vpn翻墙可能会被网警抓,你需了解的事中评论 不是吧?..
    • 博主 在

      go语言+beego框架中获取get,post请求的所有参数中评论 @ t1  直接在router.go文件中配就ok..
    • Jade 在

      如何在MySQL查询中获得当月记录中评论 Dear zongscan.com team, We can skyroc..
    • 2016-10
    • 2016-11
    • 2017-07
    • 2017-08
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-09
    • 2020-10
    • 2020-11
    • 2021-01
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客