php - 正确使用验证时是否需要批量分配保护?

标签 php laravel laravel-5

我第一次在我负责维护的遗留应用程序中同时使用 Laravel (5.4) 和 PHP,在过去的几个月里,我注意到一个痛点,即批量分配.

我相信我对现状有足够的了解,但我不确定我是否真的正确地利用了它。 The official documentation使用用户角色的(好的但极端的)示例说明问题。我理解这一点的重要性以及为什么我应该保护这些变量。但是,我不认为我真的对确定要保护或不保护哪些字段(如果有的话)有深入的了解。

Laravel 的很多不错的功能似乎都没有考虑到批量赋值,这是我沮丧的主要原因。例如,如果我有一个端点有一些可选字段(即您可以不在请求中指定它们),那么执行 mymodel->update(request->all()) 只会更新您提供的字段。如果许多字段都受到保护,如果我想实现相同的行为,我将不得不多次重复 isset() 检查,这似乎是不必要的。 我也知道 request->all() 不应该这样使用,但我只是想说明一点

当您考虑到您可能会使用稳健的验证以及诸如 request->only([...]) 之类的东西来确保您的数据正确且已过滤时,它会变得更加麻烦只为您所期望的。

所以最终我要问的是:

在强大的验证和输入整形方法存在的情况下,批量分配几乎还有什么值得做的吗?总的来说,当我的验证步骤似乎已经解决了这个问题时,我似乎无缘无故地跳过了这么多箍。 如果它仍然值得做,我还缺少什么?是否应该只将批量分配保护委托(delegate)给 super 重要的字段,例如用户的角色,而不是其他任何内容?

最佳答案

其实我没明白你这句话的意思:

If many of the fields were guarded, I would have to have many repeated isset() checks if I wanted to achieve the same behavior

不是可批量分配的字段,只是在请求中出现时被丢弃

但是在用户从请求中传递一个参数如 forbidden_​​param 并且 forbidden_​​param不可批量分配的情况下(两者都不在 fillables 中或者它在守卫中)不会抛出任何错误,并且 eloquent丢弃 forbidden_​​param

如果你的代码中有这个:

if(isset($request->forbidden_param))

当使用批量分配时,你可以从他们那里得到解脱。

Laravel 让你随心所欲地工作

Laravel 不会强制您使用 helpersFacadeDI ……来使用服务。

为了保护模型字段,您可以使用不同的解决方案来:

1.Eloquent保护(Mass Assignable)

您可以从请求中传递参数,然后保护它们免受 Eloquent 。

//in controller
MyModel::update($request->input())

// in model

$fillable = [ ... ]
//or
$guarded = [ ... ]

这是一个常见的模式,我已经看到很多代码都使用了这种场景。

好处是:

  • 倾斜 Controller
  • 如果您只是忘记在其他地方( Controller /验证)控制输入,不用担心容易出错的字段

2. Controller 保护

我见过的另一种模式是在 Controller 的 update 方法中放置准确的参数。

Model::update([
    'permitted_param1' => $request->permitted_param
    'permitted_param2' => $request->permitted_param2
]);

在这种情况下,可以通过以下方式放宽模型中可分配的质量:

$guarded = [];

或者可以使它受益,以防另一个 Controller 上的另一个队友可能忘记控制输入并使用 $request->input()。 不过这是可选的。

这样做的好处:

  • 能够拥有不同的输入名称数据库字段名称
  • 能够在输入模型之前操纵输入(这可以使用修改器或存储库实现)。但如果要更改的字段很少,则实现起来更简单。

在下面的示例中, Controller 使用混合方法:

User::create($request->except('password') + [ 'secret' => bcrypt($request->password)] );

3.在验证器中保护

我见过的最有前途的方法之一是仅使用经过验证的数据,如下所示: 对于 Laravel 8+:

MyModel::update($request->safe()->all());

对于 8 之前的 Laravel:

MyModel::update($request->validated())

并且您可以放宽可批量分配

好处:

  • 您已将验证数据和敏感数据合并到一个地方
  • 更精简的 Controller
  • 您确定已验证所有数据

Note: in case of optional data you can just not to put the required rule

4.存储库模式

另一种方法是使用存储库模式,这会给小项目带来复杂性。

但结果是:

  • 更精简的 Controller 和模型
  • 在存储库中移动查询逻辑
  • 使查询更具可重用性和解耦性

对于使用此设计模式的项目,此控件可以移至存储库。

关于php - 正确使用验证时是否需要批量分配保护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70044107/

相关文章:

php - 交响乐 2 错误 : Call to a member function get() on a non-object

laravel - 从前 100 行中随机抽取 10 行

php - Laravel 通过自定义属性查询

php - 如何使用 get_object_vars 获取属性的层次顺序?

php - CodeIgniter 加入无法选择

php - 如何在这种 laravel 验证回调中访问外部变量?

php - 在laravel 中调用成员函数getClientOriginalExtension()?

php - Curl 在托管服务器上返回 false(已启用curl)

php - Laravel 中别名和提供者的实际需求是什么

mysql - 字符串未保存在 DB varchar 列中