Php 如何使用数据表和数据映射器?有必要吗?

Php 如何使用数据表和数据映射器?有必要吗?,php,zend-framework,php-5.3,zend-db,zend-db-table,Php,Zend Framework,Php 5.3,Zend Db,Zend Db Table,我以前有过框架方面的经验,但从未真正深入研究过模型。我不知道这是适用于所有框架还是仅适用于zend,但目前我正在学习zend框架 我一直在浏览示例应用程序,并试图阅读大量文章,但我找不到一个简短而清晰的答案来回答让我困惑的问题 这三个类之间的关系是什么?(模型、模型映射器、数据表) 假设我有一个名为users的数据库表,它有3个字段userID、userName、userPassword示例代码是什么 是否有必要以这种方式构建应用程序的模型部分?如果我只有从数据库检索数据并以数组形式返回结果的函

我以前有过框架方面的经验,但从未真正深入研究过模型。我不知道这是适用于所有框架还是仅适用于zend,但目前我正在学习zend框架

我一直在浏览示例应用程序,并试图阅读大量文章,但我找不到一个简短而清晰的答案来回答让我困惑的问题

这三个类之间的关系是什么?(模型、模型映射器、数据表)

假设我有一个名为
users
的数据库表,它有3个字段
userID、userName、userPassword
示例代码是什么

是否有必要以这种方式构建应用程序的模型部分?如果我只有从数据库检索数据并以数组形式返回结果的函数,这会是一种糟糕的做法吗

请考虑这是一个非常简单的应用程序,具有用户、图像库和消息传递功能。p>


提前感谢。

一般来说,与许多其他框架相比,Zend框架并不强迫您使用特定的模型体系结构。因此,您可以自由地使用最适合您的应用程序的任何体系结构。因此,在众多方法中,使用一种只是一种可能的方法

但要回答您的特定问题:使用映射器的原因很简单,因为存储在关系数据库中的信息不能以1:1的比例转换为对象模型。这被称为,并在相应的维基百科文章中详细描述

对于您的示例应用程序,让我们考虑<代码>消息< /代码>和<代码>用户< /代码>之间的关系。假设有两个表,其中的列在括号中:

users (id, username, email, password)
messages (recipient: users.id, sender: users.id, message)
这将对应于“哑”对象
User
Message
。现在您想加载一条特定的消息。对象
消息
提供了方法
getRecipient()
getSender()
,这两种方法都应该返回
用户
的实例。但是,如果读取数据库中的特定行,它将返回一个数组,而不是包含对所需其他对象的所有引用的对象。这正是映射器的作用所在:它注意将数据库中的“平面”结果转换为对象,并提供对其他对象的所有必要引用。


最后,另一个重要功能是将持久性与普通模型分离。假设有一天您希望从传统的关系数据库引擎切换到XML存储。只要新的持久化层能够提供必要的对象,您就不必接触业务逻辑。

对于简单的应用程序和ZF,只需使用将数据库表绑定到数据库适配器的DbTable模型即可。这不是最佳实践,但很简单,可以让您开始

使用Zend_工具cli,命令将具有此格式
zf创建数据库表名实际表名模块强制覆盖

这将转化为:

zf create db-table Users users
分贝 这将在
/application/models/DbTable/
处创建一个名为
Users.php
的文件,其外观如下:

<?php

class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
    protected $_name = 'users'; //name of table, does not have to match name of class
}
只需创建一个小类,您就可以访问所选数据库适配器的功能。您还可以在DbTable模型中构建方法来定制访问需求

<?php

class Application_Model_DbTable_Users extends Zend_Db_Table_Abstract
{
    protected $_name = 'users'; //name of table, does not have to match name of class

    public function getUser($id) {
       $select = $this->select();//see Zend_Db_Select for info, provides more secure interface for building queries.
       $select->where('id = ?', $id);//can be chained

       $result = $this->fetchRow($select);//returns a row object, if array is needed use ->toArray()
       return $result;
    }
} 

我想确认我所理解的内容

Application\u Model\u User
Application\u Model\u Message
只有变量及其setter和getter方法。基本上,它们是存储模型

Application\u Model\u MessageMapper
具有类似于
getSender
的功能,可以返回
Application\u Model\u User
的实例,映射程序也使用db表类检索数据

现在,我可以在我的控制器中执行类似的操作

$id = $this->getRequest()->getParam('id'); // I received the message ID
$messageMapper = new Application_Model_MessageMapper(); 
$message = $messageMapper->getMessageByID($id); // this method uses Application_Model_DbTable_Message to fetch data, 
// then creates an object type of Application_Model_Message to set its fields and return.

$sender = $messageMapper->getSender($message);  // returns an instance of Application_Model_User after doing the necessary processes.
因此映射程序与db表类对话,从中获取数据,并将该数据设置为要返回的模型对象。

到目前为止,我是否正确理解了这一点?如果是这样的话,我将开始这个项目的工作,并随着我去学习更多

我仍然不知道如何将这些db table类与多对多关系所需的链接表一起使用,但我想如果我得到了基础,我最终会找到答案的


请指出任何我误解的地方。

谢谢,现在它更有意义了,很高兴知道我可以使用ZF而不用担心映射器。对于表之间的关系,我仍然有点困惑。我将试着从手册中找到我的答案。它比文章更有用。再次感谢。所有这些听起来都很好。老实说,我从未使用过fetchAll或getSender()之类的方法,因为我没有练习OO PHP。我有Java的OOP经验。我在PHP中所做的是在每一个数据库场景中使用MySqLQuices()函数,并且我想赶上面向对象的PHP,因为我已经研究了OOP。(对不起,我在评论的中间部分点击了<代码>添加注释< /代码>按钮)。如果我只创建数据表类,并且有用户定义的方法返回数组结果,你会认为这是一个坏的做法吗?例如,
getMessageByID()
使用联接的sql语句返回
用户的结果和
消息的结果?我不建议这样做。原因是使用数组结果很容易出错,而且是不间断的,尤其是在团队中开发时。考虑示例方法<代码> GETMaseById()<代码>:如果您提供了一个数组,另一个开发人员如何知道如何在不查找消息的情况下访问消息接收方的用户ID?您是否记录了方法头中的每个数组键?但是,如果在一行程序中指定返回的类(
@returnmessage
),任何最先进的IDE都将提供所有可用的方法
<?php

class IndexController extends Zend_Controller_Action {

   public function indexAction(){
       $id = $this->getRequest()->getParam('id');//assumes the id is set somehow and posted
       $db = new Application_Model_DbTable_Users();//instantiate model
       $result = $db->getUser($id);//perform query, see Zend_Db_Table_Abstract for API
       //$this->view->user = $result;//send to view as object
       $this->view->user = $result->toArray();//send to view as an array
    } 
} 
$id = $this->getRequest()->getParam('id'); // I received the message ID
$messageMapper = new Application_Model_MessageMapper(); 
$message = $messageMapper->getMessageByID($id); // this method uses Application_Model_DbTable_Message to fetch data, 
// then creates an object type of Application_Model_Message to set its fields and return.

$sender = $messageMapper->getSender($message);  // returns an instance of Application_Model_User after doing the necessary processes.