CakePHP模型实例混淆


CakePHP Model instances confusion

经过大量调试后,我注意到CakePHP(2.x)模型使用中有一个非常奇怪的行为:

当我更改Model ID并使用read()时,在一个与同一Model有关系的完全不同的对象实例上,它会覆盖旧的Model数据。

// set the user, by using the 'User' model
$this->User->id = 1;
$this->User->read();
print_r($this->User->data); // works correctly
$instance = new Notification(); // this has a relation to the 'User' model
print_r($instance->User->data); // == $this->User->data! why?!
$instance->User->id = 2;
$instance->User->read();
print_r($this->User->data); // == $instance->User->data!

为什么这些模型相互连接?既然这是一个新实例,它们不应该完全分离吗?我的意思是,我正在为通知设置"用户"模型,而不是为此设置

如果这是默认行为——我如何将()数据读取到不同的实例中,而不改变其他模型?我真的需要手动创建一个新的"用户"实例并将其存储在$instance中的某个位置以避免这种行为吗?这听起来很难看。

模型实例是singleton

问题中的以下两个对象是相同的:

$this->User
$instance->User

因为它们实际上是同一个对象,所以用于访问对象的路径不会修改(用户)对象本身的行为。

这就是ClassRegistry::init的工作原理——它存储对模型实例的引用——当再次查询相同的别名(className)时,它将返回相同的对象。

不要使用新创建模型

这样做是不正常的,而且可能会在未来造成问题或至少混乱。要获得对Notification模型的引用,请根据需要使用$uses、loadModel或ClassRegistry::init

不使用模型::read

我真的需要手动创建一个新的"用户"实例吗

绝对不是,这不是CakePHP模型的工作方式。模型类实际上是数据库的接口,它不是单行的表示形式(调用save时除外)。

避免大量问题的最简单方法是根本不使用Model::read,而是使用任何适当的find调用;一个更完整的代码示例将允许一个更具体的答案。