php - Laravel/Eloquent 模型属性可见性

标签 php laravel eloquent visibility accessor

我以前使用的 ORM 将数据库列直接映射到类属性,这允许您查看特定属性的可见性,就像您通常会限制对某些属性的访问一样,例如密码。

使用 Eloquent 我似乎无法复制它,因为数据库列映射到不包含可见性的内部属性数组。

我的愿望是将对用户密码的访问范围仅限于对象,即私有(private)。

设置具有可见性的类属性不起作用,因为此属性超出了 Eloquent 模型属性的范围,因此该属性未映射到列。

Eloquent $hidden 和 $guarded 属性不起作用,因为它们处理批量输出(toArray、toJSON)和批量赋值,而不是直接赋值。

我尝试使用访问器/修改器(getters/setters)来实现混合结果。

指定访问器的可见性不起作用,因为调用的访问器方法(例如 getPasswordAttribute)是从 Eloquent\Model->getAttribute 方法调用的,因此 public/protected 将始终有效,而 private 将始终失败,无论在哪里访问它的属性。

然而,有效的是停止 Eloquent 访问器完全返回属性,这样任何对 $user->password 或 $user->getAttribute ('password') 的请求都会失败,然后有一个单独的方法,按顺序定义可见性仅在允许的范围内直接从 Eloquent 属性数组返回属性,例如

/**
 * Return password string only for private scope
 * @return string
 */

private function getPassword ()
{
    return $this->attributes['password'];
}

/**
 * Don't return password with accessor
 * @param string $password Password
 * @return void
 * @throws Exception
 */

public function getPasswordAttribute ($password)
{
    throw new Exception ('Password access denied');
}

对于任何想要 setter 方法可见性的人,同样的方法也适用于 mutators(setters)。

这看起来是否正确,或者是否有更好的“Laravel 批准”方式来处理这个问题? :)

最佳答案

我不知道这样做的“批准”方式,但是你总是可以覆盖 Eloquent 的 __get() 魔术方法来检查私有(private)字段?

debug_backtrace() 检查有点老套;如果没有,我实际上无法让它按预期工作,因为 getPassword() 方法(或者基本上该类中调用 $this->password 的任何方法)仍然存在使用 __get。这只是检查调用 __get 的类是该类本身,而不是另一个类。

它不应该太低效,因为在执行回溯之前,in_array 检查对于非私有(private)属性将失败。不过,可能有更好的方法!

private $private = array(
    'password'
);

public function __get($key)
{
    // check that the class calling __get is this class, and the key isn't 'private'
    if (in_array($key, $this->private) && debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2)[1]['class'] != get_class()) {
        throw new \Exception('Private');
    }

    // anything else can return as normal
    return parent::__get($key);
}

public function getPassword()
{
    // calling this method elsewhere should work
    return $this->password;
}

关于php - Laravel/Eloquent 模型属性可见性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27170121/

相关文章:

javascript - jQuery FileUpload 发送的文件数据在哪里?

php - 使用 create 方法从 laravel 获取最后插入的 id

laravel - 仅删除单个方法的 csrf token - Laravel

php - LARAVEL - 将变量从 Controller 传递到 View

php - Laravel Eloquent - 使用数据透视表的 id 作为另一个表中的外键

mysql - 获取两个给定日期之间的数据不会返回任何内容 Eloquent

php - 使用表单发布XML值

php - 如何选择表中的上一个/下一个行,其中列值

laravel - Eloquent 搜索/自定义属性的位置

scripting - PHP脚本任意停止运行没有错误