如何存储从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打包并将其传递给其他方法。
这是应该如何工作,还是我在这里遗漏了什么?
答案 0 :(得分:0)
原来这是由"陷阱引起的。在处理PHP" magic" getter和setter方法__get()
和__set()
。
查看RedBean_SimpleModel
的源代码,它实际上使用了神奇的__set()
方法在设置属性时更新其bean。
gotcha 来自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
中删除了所有成员变量, {<1}}除外 $bean
当然是RedBeanPHP_SimpleModel
的重要组成部分。
现在我可以轻松地将MyBaseModel
子类化,并在子类模型中包含我需要的所有公共字段,并且原始问题中的代码将起作用。