无法在 RedBean 中存储盒装模型?
Can't store boxed model in RedBean?
如何在 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
on $bean
,但我希望能够装箱一个bean并传递它到其他方法。
这是它应该如何工作,还是我在这里遗漏了什么?
原来是 "gotcha" 在处理 PHP 的 "magic" getter- 和 setter 方法时引起的 __get()
和 __set()
.
查看 RedBean_SimpleModel
的源代码,它实际上使用神奇的 __set()
方法在设置 属性 时更新其 bean。
这是问题,直接来自PHP documentation:
__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.
__isset() is triggered by calling isset() or empty() on inaccessible properties.
__unset() is invoked when unset() is used on inaccessible properties.
所以事实证明,__set()
永远不会被现有(可访问的)class 成员调用,即 public $message
。所以我可以从 class 中删除所有 public 字段,这将解决问题,但是我会失去所有自动完成功能和我的 IDE.[= 中的 lint 检查23=]
所以我想出了这个解决方案:
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;
}
这有效地从 class MyBaseModel
实例化时删除 all 成员变量,except $bean
,这当然是 RedBeanPHP_SimpleModel
的重要组成部分。
现在我可以轻松地 subclass MyBaseModel
并在我的 subclass 模型中拥有我需要的所有 public 字段,原始问题中的代码将工作。
如何在 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
on $bean
,但我希望能够装箱一个bean并传递它到其他方法。
这是它应该如何工作,还是我在这里遗漏了什么?
原来是 "gotcha" 在处理 PHP 的 "magic" getter- 和 setter 方法时引起的 __get()
和 __set()
.
查看 RedBean_SimpleModel
的源代码,它实际上使用神奇的 __set()
方法在设置 属性 时更新其 bean。
这是问题,直接来自PHP documentation:
__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.
__isset() is triggered by calling isset() or empty() on inaccessible properties.
__unset() is invoked when unset() is used on inaccessible properties.
所以事实证明,__set()
永远不会被现有(可访问的)class 成员调用,即 public $message
。所以我可以从 class 中删除所有 public 字段,这将解决问题,但是我会失去所有自动完成功能和我的 IDE.[= 中的 lint 检查23=]
所以我想出了这个解决方案:
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;
}
这有效地从 class MyBaseModel
实例化时删除 all 成员变量,except $bean
,这当然是 RedBeanPHP_SimpleModel
的重要组成部分。
现在我可以轻松地 subclass MyBaseModel
并在我的 subclass 模型中拥有我需要的所有 public 字段,原始问题中的代码将工作。