【问题标题】:Should I use App::import('Model', ...) or ClassRegistry(...)?我应该使用 App::import('Model', ...) 还是 ClassRegistry(...)?
【发布时间】:2011-03-08 20:28:02
【问题描述】:

由于其他答案 (like this),我只是想澄清一下应该在 CakePHP 1.3 中使用什么。

具体来说,我有一种情况需要一个模型依赖另一个模型,所以我想从那个模型中的一个方法加载另一个,用信息做一些事情等等。

documentation for the App Class 说:

在以前的版本中,根据您要加载的类的类型,可以使用不同的函数来加载所需的类。这些函数已被弃用,所有类和库加载现在应通过 App::import() 完成。

我假设这涵盖了ClassRegistry 等的使用,但我只是想明确一点:

我应该使用App::import('Model', ...) 来利用另一个模型还是其他模型?如果有别的,什么?

【问题讨论】:

  • 由于我不能以幕后的方式对修订发表评论,我想我会问:我来到 StackOverflow 的理解是,清楚问题很重要,并且其他人(可能通过搜索引擎)能够在未来轻松找到问题。在这些情况下,让我的 version specific 问题在标题中清晰可见似乎很有意义。我不同意编辑,但我想我明白你的目的,并且会保持不变。我在某处错过的指南中概述了标签与标题的内容吗?

标签: php cakephp frameworks cakephp-1.3


【解决方案1】:

看来,即使自 2008 年以来两年,最好的方法是使用 ClassRegistry::init(),尽管引用了文档。

这在特定类/方法的实际 API/文档中很明显。

App::import()

根据 $name 或要搜索的特定文件查找类。调用 App::import() 不会构造文件中包含的任何类。它只会找到并 require() 文件。

ClassRegistry::init()

加载一个类,在注册表中注册对象并返回该对象的实例。

示例简单使用:获取一个 Post 模型实例 ClassRegistry::init('Post');

如您所见,即使是 API 文档也指出了使用 ClassRegistry 加载模型、为您实例化它们的示例,而不是 App::import(它做的少得多),尽管 CakePHP 中的措辞有所改变“书”文档。

【讨论】:

  • App::import() 存在是有原因的。例如,您需要行为中的模型实例来处理其所有默认关系(belongsTohasManyhasOnehasAndBelongsToMany)。现在,如果您还使用Containable 行为并在find() 提前调用中包含数据,您会通过使用ClassRegistry::init() 获得一组不完整的关系数据(尽管我探索并发布了一些解决方法作为问题和解决方案@ 987654323@,但它过于复杂)。它总是关于什么是适合需要的,没有通用的方法
【解决方案2】:

如果您可以关联模型,那么最好的方法是使用动态绑定关系

$this->bindModel("hasOne" => array("Model2"))

如果您无法关联模型并且只想在一次出现中使用第二个模型,那么您可以使用

ClassRegistry::init('Model2')->find('allThatIWant');

如果你想多次使用它,那么你必须尝试

$this->model2 = & ClassRegistry::init('Model2') 
$this->model2->find('allThatIWant');

【讨论】:

  • 请记住App::import() 是最糟糕的方法。仅作为最后一次尝试时使用。
  • 好吧,现在我更加好奇了。这是否经常在邮件列表或其他东西上讨论,因为即使是 1.3 文档也删除了用于访问模型中的模型的“其他选项”,并建议 App::import()... 有什么可以清楚地解释这一点在文档中?感谢您的回答和帮助!
  • 查看这篇文章的 cmets。 nuts-and-bolts-of-cakephp.com/2008/12/16/…
【解决方案3】:

从 2.6.x 开始,它当然仍然是 ClassRegistry::init()。

有很大的不同。 App::import 只会包含/需要它。另一方面,ClassRegistry::init() 将实例化它并为您获取模型的完全加载对象。

也就是说,例如,您在 AppController 的 beforeFilter 中加载了一个模型。您可以使用 $this->Model->__something 向它添加一些自定义属性。现在,您确实在没有 $controller 对象可用的地方调用 ClassRegistry::init('Model') ,例如,在行为中。 ClassRegistry::init('Model') 返回的对象将包含您的自定义属性 $this->Model->__something

顺便说一句,$controller->loadModel() 似乎是在您有 $controller 对象可用的地方(例如在您的组件中)加载模型的理想方式。

【讨论】:

  • App::import() 存在是有原因的。例如,您需要行为中的模型实例来处理其所有默认关系(belongsTohasManyhasOnehasAndBelongsToMany)。现在,如果您还使用Containable 行为并在find() 提前调用中包含数据,您会通过使用ClassRegistry::init() 获得一组不完整的关系数据(尽管我探索并发布了一些解决方法作为问题和解决方案@ 987654322@,但它过于复杂)。它总是关于什么是适合需要的,没有通用的方法
【解决方案4】:

$this->loadModel('model name') 会做,除非你需要它用于整个控制器,然后只需在模型中定义关系,例如 hasone,belongs... 并调用$this->model->model2

【讨论】:

  • 此时我不在控制器中。我在 Model-B 的一个方法中使用 Model-A。
猜你喜欢
  • 2011-02-13
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 2015-07-19
  • 2015-10-16
  • 2023-03-06
相关资源
最近更新 更多