我们最近开始使用 Doctrine 2.2 和 Zend Framework 2 的部分内容,以改善组织、减少重复等。今天,我开始提出实现服务层以充当我们的控制器和 Doctrine 实体之间的中介的想法。
现在,我们的大部分逻辑都驻留在控制器中。此外,我们使用操作助手来测试某些权限;然而,在实现 Zend\Di 之后,我想出了一个新方法。我开始创建实体特定的服务模型,它使用 Zend\Di 来注入一个 EntityManager 实例,以及当前用户的权限。
控制器代码如下:
class Project_DeleteController extends Webjawns_Controller_Action
{
public function init()
{
$this->_initJsonContext();
}
public function indexAction()
{
$response = $this->_getAjaxResponse();
$auditId = (int) $this->_getParam('audit_id');
if (!$auditId) {
throw new DomainException('Audit ID required');
}
/* @var $auditService Service\Audit */
$auditService = $this->getDependencyInjector()->get('Service\Audit');
try {
$auditService->delete($auditId);
$response->setStatusSuccess();
} catch (Webjawns\Exception\SecurityException $e) {
$this->_noAuth();
} catch (Webjawns\Exception\Exception $e) {
$response->setStatusFailure($e->getMessage());
}
$response->sendResponse();
}
}
以及我们的服务层之一的示例。构造函数接受两个参数——一个接受 EntityManager,另一个接受一个 Entity\UserAccess 对象——由 Zend\Di 注入。
namespace Service;
use Webjawns\Service\Doctrine,
Webjawns\Exception;
class Audit extends AbstractService
{
public function delete($auditId)
{
// Only account admins can delete audits
if (\Webjawns_Acl::ROLE_ACCT_ADMIN != $this->getUserAccess()->getAccessRole()) {
throw new Exception\SecurityException('Only account administrators can delete audits');
}
$audit = $this->get($auditId);
if ($audit->getAuditStatus() !== \Entity\Audit::STATUS_IN_PROGRESS) {
throw new Exception\DomainException('Audits cannot be deleted once submitted for review');
}
$em = $this->getEntityManager();
$em->remove($audit);
$em->flush();
}
/**
* @param integer $auditId
* @return \Entity\Audit
*/
public function get($auditId)
{
/* @var $audit \Entity\Audit */
$audit = $this->getEntityManager()->find('Entity\Audit', $auditId);
if (null === $audit) {
throw new Exception\DomainException('Audit not found');
}
if ($audit->getAccount()->getAccountId() != $this->getUserAccess()->getAccount()->getAccountId()) {
throw new Exception\SecurityException('User and audit accounts do not match');
}
return $audit;
}
}
- 对于我们想要完成的事情,这是一个合适的模式吗?
- 在发布的服务层中进行权限验证是一种好习惯吗?
- 据我了解,视图逻辑仍然驻留在控制器中,使模型可以灵活地用于各种上下文(JSON、XML、HTML 等)。想法?
到目前为止,我对这种工作方式感到满意,但如果有人看到我们这样做的任何不利之处,请发表您的想法。