不能在 RedBean 中存储盒装模型?
Posted
技术标签:
【中文标题】不能在 RedBean 中存储盒装模型?【英文标题】:Can't store boxed model in 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并将它传递给其他方法。
这是它应该如何工作,还是我在这里遗漏了什么?
【问题讨论】:
【参考方案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
并在我的子类模型中拥有我需要的所有公共字段,并且原始问题中的代码可以正常工作。
【讨论】:
以上是关于不能在 RedBean 中存储盒装模型?的主要内容,如果未能解决你的问题,请参考以下文章