【问题标题】:Creation of a closure as class variable in constructor of Eloquent Model在 Eloquent 模型的构造函数中创建一个闭包作为类变量
【发布时间】:2015-02-23 19:08:40
【问题描述】:

我正在尝试在 Eloquent 模型的构造函数中创建一个 lambda 样式的闭包作为动态命名的类变量。

除了创建模型(也就是说,读取、更新和删除工作正常)之外,实例化对象时它工作正常。

我可以通过在实例化对象之前显式声明类变量来解决这个问题,但是,这只是一个技巧,我需要能够动态地创建类变量(作为闭包)。

以下代码有效,但如果我删除声明 $public foo; 则会失败

public $foo;
public function __construct() {
    $foo = 'foo';
    $this->{$foo} = function ($args) { return 'foo';};
}

我收到以下错误:

异常 'ErrorException' 带有消息 'Object of Class Closure could 不转换为字符串'中 /Users/Sites/.../vendor/laravel/framework/src/Illuminate/Support/helpers.php:900

就像我提到的,这只发生在创建/插入对象时(对不起,如果这听起来含糊不清,但任何熟悉 Laravel 的人都应该知道我的意思)......在其他情况下实例化模型(读取/更新/删除)有效正好。任何关于可能导致问题的想法将不胜感激!

【问题讨论】:

  • 如果你试图存储这个对象,那么你会遇到这个问题......你有没有考虑过创建一个访问器方法?
  • 你能解释一下为什么会这样吗?访问器方法并不是一个真正的选择。
  • 没什么好解释的,就是“设计行为”。 PHP 不能做你想做的事......你不能将闭包强制转换为字符串,因此你不能序列化,因此不能将闭包存储在会话等中。
  • 是的,PHP 可以并且确实可以做我想做的事(正如我的帖子中提到的)......问题似乎在于使用 Eloquent/Laravel 存储记录。
  • @hunter 你为什么想要这样的功能?

标签: php laravel eloquent


【解决方案1】:

在您的模型上覆盖 setAttributegetAttribute

protected $closures = [];

public function setAttribute($key, $value)
{
    if ($value instanceof \Closure)
    {
        $this->setClosureProperty($key, $value);
    }

    parent::setAttribute($key, $value);
}

public function getAttribute($key)
{
    if (array_key_exists($key, $this->closures)
    {
        return $this->closures[$key];
    }

    return parent::getAttribute($key);
}

public function setClosureProperty($key, \Closure $value)
{
    $this->closures[$key] = $value;
}

这样,cloures 不会被保存在attributes 数组中,因此不会被保存并转换为字符串。

【讨论】:

  • 印象深刻:很好的解决方案
  • @JarekTkaczyk - 我正在使用闭包动态定义模型关系(在基类中)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-23
  • 2019-05-25
  • 1970-01-01
  • 2019-09-06
  • 1970-01-01
相关资源
最近更新 更多