如何保护Laravel模型属性 [英] How to protect Laravel model properties
问题描述
在使用其他框架或纯PHP时,我会保护我的模型属性.然后,在需要的地方创建公共获取器和设置器,并使用__get()
和__set()
代理它们.这可以帮助我晚上入睡.
When working with other frameworks, or pure-PHP, I protect my model properties. I then create public getters and setters where required, and proxy to them using __get()
and __set()
. This helps me sleep at night.
最近我开始使用Laravel,我对Eloquent模型的不受保护"感到惊讶.我知道我可以使用$guarded
和$fillable
属性来控制质量分配,但这仍然为意外访问留下了很大的空间.
Recently I started using Laravel and I am surprised at how 'unprotected' the Eloquent models are. I understand that I can use the $guarded
and $fillable
properties to control mass assignment, but that still leaves a lot of room for accidental access.
例如,我的模型具有status
属性.它具有在创建模型时设置的默认值,并且仅应在调用$model->activate()
或$model->deactivate()
时进行修改.但是默认情况下,Laravel允许开发人员直接对其进行修改.据我所知,防止这种情况发生的唯一方法是创建一个setter,并在调用它时引发异常.
For example, my model has a status
property. It has a default value set on model creation, and should only be modified when $model->activate()
or $model->deactivate()
is called. But by default, Laravel allows developers to modify it directly. As far as I can see, the only way to prevent this is to create a setter, and throw an exception if it is called.
我错过了什么吗?也许我只需要放松一下?建立默认情况下安全的Eloquent模型的最佳方法是什么?
Am I missing something? Perhaps I just need to relax? What's the best way to build Eloquent models that are secure by default?
推荐答案
您可以覆盖__get和__set方法.您需要定义一个数组protectedProperties和一个布尔变量protectedChecks,以便您可以控制模型字段.
You can override __get and __set method. You need to define an array protectedProperties and a boolean variable protectedChecks so you can control the model fields.
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中编写类似上面的内容.
If you want to use every model you should write something like above in BaseModel.
这篇关于如何保护Laravel模型属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!