一文带你了解 Laravel 中的 Mass-Assignment (批量赋值)

Laravel

Laravel Eloquent ORM 提供了简单的 API 与数据库进行交互。它是通过 [Active Record] (https://www.martinfowler.com/eaaCatalog/ac...) 模式来实现的。数据库中的每个表都映射为一个 Model class 文件,并通过该文件与数据库的表进行交互。

批量赋值

现在让我们来分解这个词组。

  • 批量 :意味着字段数量比较多
  • 赋值 :需把前端提交的值赋值给指定的变量

为了使开发人员更方便,Eloquent ORM 提供了批量赋值功能,该功能可以帮助开发者将大量数值插入(更新)到数据库中。

没有批量赋值时 😩

让我们想象一下,一个包含 10 个用户信息的表单。

    <form method="POST" action="/signup">
        <input type="text" name="name" />
        <input type="text" name="user_name" />
        <input type="text" name="password" />
        <input type="text" name="address" />
        <input type="text" name="city" />
        ...
        ...
        ...
        <button type="submit">Signup</button>
    </form>

Controller's store 方法内容如下:

public function store(Request $request)
{
    // 执行验证

    $user = new User;

    $user->name = $request->get('name');
    $user->user_name = $request->get('user_name');
    $user->password = bcrypt($request->get('password'));
    $user->address = $request->get('address');
    $user->city = $request->get('city');

    //....

    $user->save();
}

我们需要将用户信息分别获取并赋值给 Model,然后保存到数据库中。

有没有一种方法,不需要单独获取数据的方式,而是通过批量获取数据呢?

使用批量赋值时 🥳

Laravel Eloquent ORM 提供了 create 方法,它可以帮助你使用一行代码来保存所有的用户信息。

public function store(Request $request)
{
    // 执行验证

    $user = User::create($request->all());
} 

是不是酷酷的 🤓 只用一行代码就可以将用户信息都保存到数据库中。将来,如果我们在 HTML 代码中添加了更多的用户信息,也无需担心被遗漏而不能保存到数据库中。

输入字段 name 属性必须是数据库表中的字段名.

潜在漏洞

为了方便理解,数据库中的 users 表有 is_admin 字段,字段保存的值只能是 true 或 false 。

恶意的用户可以伪造 HTML,通过设置隐藏值,将  is_admin 字段设置为true

    <form method="POST" action="/signup">

        <input type="hidden" name="is_admin" value="1" />

        <input type="text" name="name" />
        <input type="text" name="user_name" />
        <input type="text" name="password" />
        <input type="text" name="address" />
        <input type="text" name="city" />
        ...
        ...
        ...
        <button type="submit">Signup</button>
    </form>

因为我们使用了批量赋值,所以用户的 is_admin 字段被设置为  true 了,而且该用户还拥有了管理员权限,糟糕,这当然不是我们想要的。 😡

避免漏洞

有两种方法可以处理此问题。

第一种:我们可以指定(白名单)哪些字段可以被批量赋值

Laravel Eloquent 提供了一种简单的方法来实现这一点。在您的模型类中,添加 $fillable 属性,并指定数组中列的名称,如下所示:

class User extends Model
{
    protected $fillable = [
        'name',
        'user_name',
        'password',
        'address',
        'city'
        ...
    ];
}

除了以上字段的其他字段只要传参给  create() 方法就会抛出 MassAssignmentException 异常。

第二种、我们可以指定(黑名单)哪些列不能批量赋值。

您可以通过在模型类中添加$guarded 属性来实现这一点:

class User extends Model
{
    protected $guarded = ['is_admin'];
}

除了 is_admin 之外的所有字段现在都可以进行批量赋值。

需要注意的是,$fillable 和 $guarded你只能二选一。

本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://dev.to/zubairmohsin33/understand...

译文地址:https://learnku.com/laravel/t/40904

本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!