您在Zend Framework中实现模型的方法有哪些?
我已经看到了基本的class User extends Zend_Db_Table_Abstract
,然后在你的控制器中调用它:
$foo = new User;
$foo->fetchAll()
但更复杂的用途呢?文档的Quickstart部分提供了这样一个示例,但我仍然觉得我没有在Zend Framework中获得模型的"最佳使用"示例.那里有任何有趣的实现吗?
编辑:我应该澄清(回应CMS的评论)......我知道做更复杂的选择.我对模型概念的整体方法以及其他人如何实现它们的具体例子感兴趣(基本上,手册遗漏的东西和基本的方法光泽的东西)
我为Zend工作,并在Zend_Db_Table组件上做了很多工作.
Zend Framework没有就域模型模式的"模型"概念提供大量指导.模型没有基类,因为模型封装了特定于应用程序的业务逻辑的某些部分.我更详细地写了一篇关于这个主题的博客.
数据库的持久性应该是模型的内部实现细节.该模型通常使用一个或多个表.将模型视为表的扩展是一种常见但不适当的面向对象设计.换句话说,我们应该说模型HAS-A表 - 而不是模型IS-A表.
这是IS-A的一个例子:
class MyModel extends Zend_Db_Table_Abstract { }
这是HAS-A的一个例子:
class MyModel // extends nothing { protected $some_table; }
在真实域模型中,您将在MyModel的方法中使用 $ some_table.
您还可以阅读Martin Fowler对领域模型设计模式的看法,以及他对贫困领域模型反模式的描述,这是不幸的开发人员接受OO编程的程度.
我个人子类均Zend_Db_Table_Abstract
与Zend_Db_Table_Row_Abstract
.我的代码和你的代码之间的主要区别在于明确将子类Zend_Db_Table_Abstract
视为"表"和Zend_Db_Table_Row_Abstract
"行".我很少看到在控制器中直接调用选择对象,SQL或内置ZF数据库方法.我试图隐藏请求特定记录的逻辑,Zend_Db_Table_Abstract
如下所示:
class Users extends Zend_Db_Table_Abstract { protected $_name = 'users'; protected $_rowClass = 'User'; // <== THIS IS REALLY HELPFUL public function getById($id) { // RETURNS ONE INSTANCE OF 'User' } public function getActiveUsers() { // RETURNS MULTIPLE 'User' OBJECTS } } class User extends Zend_Db_Table_Row_Abstract { public function setPassword() { // SET THE PASSWORD FOR A SINGLE ROW } } /* CONTROLLER */ public function setPasswordAction() { /* GET YOUR PARAMS */ $users = new Users(); $user = $users->getById($id); $user->setPassword($password); $user->save(); }
有很多方法可以解决这个问题.不要以为这是唯一的,但我试着遵循ZF设计的意图.(这里有更多我的想法和关于这个主题的链接.)这种方法确实让一点点重,但我觉得它让控制器专注于处理输入和协调视图; 离开模型进行应用程序特定的工作.
不要使用Zend_Db_Table作为您的模型.它只是让你陷入困境.您可以编写自己的模型类,使用Zend_Db_Table与您的数据库进行通信,也可以在此处阅读我的博客文章,以获取允许您在某种程度上将"Model"类和Zend_Db_Table组合在一起的hack.
最重要的是,当您在控制器中直接使用Zend_Db_Table时,您最终会在多个位置执行相同的操作.如果您必须对某些逻辑进行更改,则必须在多个位置进行更改.不好.我的第一个专业项目是这样完成的,因为我是公司中必须学习如何使用ZF的人,现在它已经完全混乱了.
我也倾向于在我的类中编写辅助函数来进行复杂的提取.像$ table-> doNameFetchAll()或$ table-> doOrderFetchAll()之类的东西.
我一直在研究ZF的模型,并且遇到了Matthew Weier O'Phinney的一系列有趣的文章,值得一试:
在模型中使用Zend_Form
将ACL应用于模型
模型基础设施
它不是"生产代码",而且很多东西都留给了想象,但这是一个很好的阅读,并帮助了我很多.
模型与数据库无关.如果我从RSS提要或SOAP服务获取数据或从FS读取文件,该怎么办?
我把所有这些东西放在模型中.在这种情况下,我的模型类可能不会扩展任何东西.我即将编写一个使用其他模型方法的模型.