如何保护 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 变量

Laravel 保护列免受不可为空/默认值的批量分配

使用新模型和保护的 Laravel 身份验证失败:未定义索引:模型

Laravel 隐藏属性。例如密码 - 安全

如何在 Laravel 模型上设置属性的默认值 [重复]