【发布时间】:2011-05-15 15:14:47
【问题描述】:
我有一个应用程序,我在其中使用 PHP 与 Zend 框架和 Doctrine2 作为 ORM。我的问题与控制器最好应该了解多少底层模型和持久层有关。理想情况下,我自己会说这“没什么”——控制器不应该知道实体是如何/何时被持久化的。但是我觉得这并不总是最好的解决方案(?)。
我已尝试遵循“关注点分离”设计准则。我通过创建一个在我的模型上执行 CRUD 操作的服务层来做到这一点。请参阅以下示例:
public function testbuildAction()
{
// create section
$sectionService = new \MyAPP\Model\Service\Acl\SectionService();
$sectionA = $sectionService->createSection('SectionA-NAME');
// create privilege with the above section
$privilegeService = new \MyAPP\Model\Service\Acl\PrivilegeService();
$privilegeA = $privilegeService->createPrivilege(
$sectionA,
\MyAPPFrameWork\Model\Acl\Privilege::PERMISSION_EDIT
);
// create a role with the privilege above. A role must have at least one priv.
$roleService = new \MyAPP\Model\Service\Acl\RoleService();
$role = $roleService->createRole('Role-NAME', $privilegeA);
// this loads a managed User object (managed by EntityManager)
$user = $this->_helper->IdentityLoader();
$user->addRole($role); // add the role to this user
$userService = new \MyAPP\Model\Service\Core\UserService();
$userService->updateUser($user); // persist the updates.
}
如您所见,控制器对持久性一无所知,但要获得此结果,我需要在每次调用服务层的 createXXX() 或 updateXXX() 方法时同时执行 persist() 和 flush() .我宁愿做这样的事情:
public function testbuildAction()
{
// create section
$sectionService = new \MyAPP\Model\Service\Acl\SectionService();
$sectionA = $sectionService->createSection('SectionA-NAME');
// create privilege with the above section
$privilegeService = new \MyAPP\Model\Service\Acl\PrivilegeService();
$privilegeA = $privilegeService->createPrivilege(
$sectionA,
\MyAPPFrameWork\Model\Acl\Privilege::PERMISSION_EDIT
);
// create a role with the privilege above. A role must have at least one priv.
$roleService = new \MyAPP\Model\Service\Acl\RoleService();
$role = $roleService->createRole('Role-NAME', $privilegeA);
// this loads a managed User object (managed by EntityManager)
$user = $this->_helper->IdentityLoader();
$user->addRole($role); // add the role to this user
// persist it all (all service-classes access the same entitymanager).
$roleService->flush(); // everything is persisted
}
但这会导致 Doctrine2 失败,因为它确实以错误的顺序将对象持久保存到数据库 - 权限在部分之前保留(不知道我是否可以指示 Doctrine 以有序的方式执行此操作??)。权限获取的部分 ID 错误,尚未持久化。
无论如何,这里最大的问题是我是否应该尝试推迟刷新,直到所有对象都已创建并已设置关系。目标是让一个事务完成所有写入数据库 - 因此必须由控制器触发(因为它是唯一知道何时完成对象和关系构建的事务),从而“污染”控制器与持久层?
【问题讨论】:
标签: php model-view-controller controller separation-of-concerns doctrine-orm