了解 Laravel Eloquent ORM 中的批量赋值
大量分配
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
Laravel Eloquent ORM提供了一个简单的数据库操作 API。它实现了Active Record模式。每个数据库表都映射到一个模型类,该模型类用于与该表进行交互。
大量分配
让我们来分析一下这个词。
- 质量是指数量众多
- 赋值是指编程中的赋值运算符。
为了简化开发人员的工作,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>
我们的控制器中的 store 方法如下所示:
public function store(Request $request)
{
//perform validation
$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();
}
我们正在手动将每个输入分配给我们的模型,然后保存到数据库中。
如果有一种方法可以自动插入所有传入的输入,而无需手动分配,那该多好?
生活,伴随着大量的任务🥳
Laravel Eloquent ORM 提供了一个create方法,可以帮助您用一行代码保存所有输入。
public function store(UserFormRequest $request)
{
//validation performed in the UserFormRequest
$user = User::create($request->validated());
}
是不是很棒?🤓 只需一行代码,我们就能将所有输入保存到数据库。以后,如果我们在 HTML 表单中添加更多输入字段,就不用担心保存到数据库的问题了。
输入字段的名称属性必须与数据库中的列名匹配。
潜在漏洞
为了便于理解,我们假设用户表中有一个名为 is_admin 的列,其值为true / false。
恶意用户可以注入自己的 HTML 代码,或者使用如下所示的隐藏输入:
<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不能同时选择两者。
好了,就是这样。祝您使用 Laravel Eloquent 进行批量赋值愉快!🥳 👨🏽💻
文章来源:https://dev.to/zubairmohsin33/understanding-mass-assignment-in-laravel-eloquent-orm-331g