Zend framework Zend框架:模型、映射器;映射器中的默认字段&;模型中的现场操作?
我正在Zend框架中创建一个简单的ORM,使用DbTable/Mapper/Model方法大致封装公共库应用程序。不过,我不确定我处理与用户相关的类的方式是否正确,因为我在Zend framework Zend框架:模型、映射器;映射器中的默认字段&;模型中的现场操作?,zend-framework,orm,model,datamapper,Zend Framework,Orm,Model,Datamapper,我正在Zend框架中创建一个简单的ORM,使用DbTable/Mapper/Model方法大致封装公共库应用程序。不过,我不确定我处理与用户相关的类的方式是否正确,因为我在Mapper\u User中有一些逻辑,在Model\u User中也有一些逻辑 映射器用户 当设置用户对象的密码时,我在Model\u user->setPassword($value)中进行设置,如您所料,并执行$this->password=md5($value)。同样,这感觉是对的-尝试在Mapper_User->sa
Mapper\u User
中有一些逻辑,在Model\u User
中也有一些逻辑
映射器用户
当设置用户对象的密码时,我在Model\u user->setPassword($value)中进行设置代码>,如您所料,并执行$this->password=md5($value)此方法中的代码>。同样,这感觉是对的-尝试在Mapper_User->save()中执行md5步骤如果从数据库中提取Model_用户
,则code>方法将导致问题,因为密码字段显然已经被散列
这就是我困惑的地方。在我看来,所有与“与用户相关的字段”相关的逻辑都应该存在于其模型或映射器中,但这里我在映射器中有一些逻辑(默认字段),在模型中有一些(字段操作)。这是对的,还是应该尝试以某种方式获取模型中的默认字段,或者映射器中的字段操作
感谢您抽出时间阅读此文章
为@RockyFord编辑:
Mapper\u User
实际上扩展了我编写的一个摘要,因为我不喜欢在500个Mapper\u*.php
文件中编写相同的基本代码,因此这会带来一些官僚作风,但其有效的u构造()非常简单:
<?php
class Mapper_Users {
public function __construct() {
$this->_db = new DbTable_Users();
if(!$this->_db instanceof Zend_Db_Table_Abstract)
throw new Exception('Invalid table data gateway provided');
}
}
?>
这可能需要一段时间才能完全回答,但我将从setPassword
问题开始
您当前的:
public function setPassword($value) {
$this->password = md5($value);
}
现在,这与惯例或最佳实践无关,而是实用性
问问自己:
当检索用户对象的数据库记录并且该数据库记录包含哈希密码时,会发生什么情况
回答:当您构造用户对象并调用$this->setPassword($password)时代码>或等效值,您将对哈希应用哈希
因此,您几乎必须在映射器的save()方法或用于更新密码的方法中对密码进行哈希运算。将数据库表中的哈希值视为密码,将表单字段中键入的值视为该密码的占位符
下一部分:
在我看来,所有与“与用户相关的字段”相关的逻辑要么存在于其模型中,要么存在于其映射器中
这基本上是正确的
属于对象域(Model_User)的所有内容都应在域模型类(Model_User)中处理
映射器仅将数据对象(数据库行、json字符串、xml文件、平面文件、csv文件…)转换(映射)为可以实例化域对象(Model_用户)的表单
因此,对于给定的域对象,最终可能会有多个映射器可用,或者一个映射器可能映射到多个数据源
如果您不再将数据视为“字段”(这可能会使您的头留在数据库中),而将对象视为属性或特征,这可能会对您有所帮助
因为当你进入最基本的层次时,一个Model\u用户
对象就是:
class Model_User {
protected $id;
protected $name;
protected $password;
//continue....
}
所有的getter、setter、constructor和其他方法都非常简单,因此我们可以将值放入这些变量。数据映射器负责用对象的数据填充对象,并将其持久化。调用$user->save()
时,您似乎在混合一些东西,因为您将持久性逻辑放在域对象中。当您使用ActiveRecord
模式而不是DataMappers
时,这是一种常见的方法,这是一件坏事
您的DataMapper
应该负责保存对象$mapper->save($user)代码>并且它只需要更新更改的属性。因此,只有在设置新的哈希值时,密码才会更新
更新:
你说:
[…]尝试在Mapper_User->save()中执行md5步骤代码>方法将导致
如果Model_用户
作为密码从数据库中取出,则会出现问题
字段显然已经被散列了
创建一个名为setPasswordHash()
的方法,并在从数据库中提取时使用它
记住:
与其在地图绘制程序中查找数据库,不如请求它
public __construct(Zend_Db_Table $dbTable) {
$this->dbTable = $dbTable;
}
这一切都是关于依赖注入的。如果您发布一些代码来演示,这会有所帮助,我想我明白了,但我不确定。@RockyFord认为没有依赖注入会更整洁,但我会添加一些!我正在努力构建一个答案,但如果不了解您的想法和编码方式,我真的不知道从哪里开始。感谢@RockyFord,我真的很感谢您-我添加了两个有问题的代码块的一些代码示例,这是否有助于理解我所做的对/错?我现在就告诉您setPassword()中的哈希不会工作很久的。你是如何构造()你的映射程序的?嗨@Keyne谢谢你的回复。save()
方法实际上在Mapper\u User
中,一个Model\u User
对象被传递给它,数据被提取出来,并通过DbTable\u User
保存到数据库中。所以我想我至少有一点是对的!:)@史蒂夫格里菲斯啊!我没看到。抱歉=)还请注意,您最好将crypt()
与河豚一起使用,而不是md5()
不用担心,是的,一旦所有其他问题都解决了,我将从md5切换到冲突较少的东西!再次感谢你的编辑;这难道不意味着任何想要实例化给定映射器的给定控制器也需要知道相应的DbTable吗?e、 g.在某个控制器中的某个操作中:$mapper=newmapper\u User(new DbTable\u User())
class Model_User {
protected $id;
protected $name;
protected $password;
//continue....
}
public __construct(Zend_Db_Table $dbTable) {
$this->dbTable = $dbTable;
}