【问题标题】:Can't store boxed model in RedBean?不能在 RedBean 中存储盒装模型?
【发布时间】:2017-01-31 09:54:03
【问题描述】:

如何在 RedBean 中存储从$bean->box() 返回的模型?

例如,下面的代码不起作用(它只是插入一个空行):

class Model_Comment extends RedBean_SimpleModel {
    public $message;
}

$bean = R::dispense('comment');
$model = $bean->box();
$model->message = "Testing";
R::store($model);

如果我使用$model->unbox()->message = "Testing",它可以工作,但这可能会很快变得烦人......

显然上面的代码只是一个例子,我可以在这里设置message属性$bean,但我希望能够装箱一个bean并将它传递给其他方法。

这是它应该如何工作,还是我在这里遗漏了什么?

【问题讨论】:

    标签: php orm redbean


    【解决方案1】:

    事实证明,这是在处理 PHP 的“神奇”getter 和 setter 方法 __get()__set() 时出现的“陷阱”。

    查看RedBean_SimpleModel的源代码,它实际上在设置属性时使用了神奇的__set()方法来更新它的bean。

    这是陷阱,直接来自PHP documentation

    __set() 在将数据写入不可访问的属性时运行。

    __get() 用于从不可访问的属性中读取数据。

    __isset() 通过在不可访问的属性上调用 isset() 或 empty() 来触发。

    当 unset() 用于不可访问的属性时,会调用 __unset()。

    所以事实证明,__set() 永远不会为现有的(可访问的)类成员调用,即public $message。所以我可以从类中删除所有公共字段,这样可以解决问题,但是我会失去所有自动完成功能和 IDE 中的 lint 检查。

    所以我想出了这个解决方案:

    class MyBaseModel extends RedBeanPHP\SimpleModel {
    
    
        public function __construct(){
            foreach( get_object_vars($this) as $property => $value ){
                if( $property != 'bean' )
                    unset($this->$property);
            }
        }
    
    
    }
    
    
    class Model_Comment extends MyBaseModel {
        public $message;
    }
    

    这在实例化MyBaseModel 时有效地从类MyBaseModel 中删除所有 成员变量,除了 $bean,这当然是RedBeanPHP_SimpleModel 的重要组成部分。

    现在我可以轻松地继承 MyBaseModel 并在我的子类模型中拥有我需要的所有公共字段,并且原始问题中的代码可以正常工作。

    【讨论】:

      猜你喜欢
      • 2012-11-05
      • 2011-10-11
      • 1970-01-01
      • 2012-12-08
      • 2013-11-28
      • 1970-01-01
      • 1970-01-01
      • 2016-05-04
      • 2011-03-13
      相关资源
      最近更新 更多