如何保护 Laravel 模型属性
Posted
技术标签:
【中文标题】如何保护 Laravel 模型属性【英文标题】:How to protect Laravel model properties 【发布时间】:2018-03-04 17:41:42 【问题描述】:在使用其他框架或纯 php 时,我会保护我的模型属性。然后,我在需要时创建公共 getter 和 setter,并使用 __get()
和 __set()
代理它们。这有助于我晚上睡觉。
最近我开始使用 Laravel,我对 Eloquent 模型的“不受保护”程度感到惊讶。我知道我可以使用 $guarded
和 $fillable
属性来控制批量分配,但这仍然为意外访问留下了很大的空间。
例如,我的模型有一个status
属性。它在模型创建时设置了默认值,并且只能在调用 $model->activate()
或 $model->deactivate()
时进行修改。但默认情况下,Laravel 允许开发者直接对其进行修改。据我所知,防止这种情况的唯一方法是创建一个 setter,并在调用时抛出异常。
我错过了什么吗?也许我只需要放松一下?构建默认安全的 Eloquent 模型的最佳方法是什么?
【问题讨论】:
【参考方案1】:您可以覆盖 __get 和 __set 方法。您需要定义一个数组 protectedProperties 和一个布尔变量 protectedChecks 以便您可以控制模型字段。
protected $protectedChecks = true;
protected $protectedProperties = [ 'status' ];
protected $fillable = ['status'];
public function __get($key)
return (in_array($key, $this->fillable) && !in_array($key, $this->protectedProperties)) ? $this->attributes[$key] : null;
public function __set($key, $value)
if(!$this->protectedChecks || !in_array($key, $this->protectedProperties))
return parent::__set($key, $value);
trigger_error('Protected Field');
public function activate()
$this->protectedChecks = false;
$this->status = 1;
$this->save(); // this is optional if you want to save the model immediately
$this->protectedChecks = true;
如果你想使用每个模型,你应该在 BaseModel 中编写类似上面的内容。
【讨论】:
【参考方案2】:你可以试试:
<?php
class User extends Eloquent
protected $hidden = array('password', 'token');
【讨论】:
【参考方案3】:我看到你可能来自 symfony 或其他使用 Mapping 作为基础来处理数据库层的系统。忘记你在那里做过的事情,因为 Eloquent 使用 Active Records 是不同的。 最好的方法是:Eloquent: Accessors & Mutators Alo check in laracast 有解释如何使用绝对属性以旧的 php 方式进行操作。
【讨论】:
以上是关于如何保护 Laravel 模型属性的主要内容,如果未能解决你的问题,请参考以下文章
Laravel/Eloquent 建议覆盖 trait 属性?
在 Laravel 中创建模型时使用受保护的 $table 变量