【问题标题】:Is it ok to use action helpers not only for controllers?不仅可以将动作助手用于控制器吗?
【发布时间】:2012-03-28 06:38:27
【问题描述】:

我正在寻找在 zf 应用程序中使用会话的最佳方式。 起初我做了这样的事情 - 在控制器超类的 init 方法中我初始化了会话:

class Vovkin_Controller_Action extends Zend_Controller_Action
{
    protected $_session;

    public function init()
    {   
        // here I define namespace 
        // ...
        $this->_session = new Zend_Session_Namespace($nameSpace);
        parent::init();
    }
    ...
}

在以这种方式使用控制器中的会话之后:

public function someAction()
{
    $this->_session->user = $user;
}

但我发现这种方法对于系统的其他部分不是很方便,比如插件、服务等,因为我必须以其他方式初始化会话,但如果可能的话,我希望将它保存在一个地方。所以我决定把它改成这种方法https://stackoverflow.com/a/2506447

现在我有一些操作助手来为具有不同命名空间的会话提供访问权限,它的工作原理如下:

public function someAction()
{
    $this->_helper->session()->user = $user;
}

到目前为止它看起来很有用,因为我可以通过这种方式访问​​系统其他部分(例如服务)中的会话命名空间:

class Vovkin_Model_Service_UserLoginService
{
    public function login()
    {
        $session = Zend_Controller_Action_HelperBroker::getStaticHelper('session')->direct();
        ...
    }   
    ....
}

但是从架构和使用资源的角度来看,以这种方式使用它的正确程度有多少?

谢谢。

【问题讨论】:

  • 我的意见,就用Zend_Registry吧。

标签: zend-framework session architecture


【解决方案1】:

您所参考的答案来自Zend Framework的主要贡献者之一的Rob Allen,因此在某种程度上它是正确的。您可以毫无问题地使用控制器上的动作助手。

但在它之外,它是完全错误的。服务没有动作助手和前端控制器。你不能依赖它(服务到行动助手)。

因此,由于应用程序引导程序用作初始化应用程序的容器,因此从那里获取必要的值是合理的。我建议你的第一件事是使用Zend_Registry。但据我所知,再次初始化会话对象是一样的,因为它不会被擦除,它只是一个引用本机$_SESSION 超全局变量的对象。所以,只需调用

new Zend_Session_Namespace($nameSpace).

但是,这又是错误的。您不应该让您的服务知道会话是如何处理的(从而在其中创建对象):

$session = Zend_Controller_Action_HelperBroker::getStaticHelper('session')->direct()

甚至

$session = Zend_Registry('userSession')

$session = new Zend_Session_Namespace('userSession')

这样你也根本没有使用引导容器。相反,您应该提供一个通用接口来处理会话(它可以是 $_SESSION 甚至是数据库)并将其作为参数注入到服务中(例如__construct($session))。但这是一个全新的主题(依赖注入)。

因此,考虑到 ZendFramework 1.11 的当前状态(已经过时且充满不良做法),您有两种选择:

1) 您将通过控制器使用服务:

因此,您将通过操作助手获取会话,然后将其作为参数传递给您的服务。

new Vovkin_Model_Service_UserLoginService($session)

2)您将独立于控​​制器使用服务,并将通过引导容器获取依赖项:

好吧,最糟糕的是,要获得引导程序,您需要有一个 frontController 依赖项。

$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');

所以,避免它,并使用第一个选项,而是注入依赖项。虽然,如果你真的想要它,直接访问它:

$bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
$bootstrap->get('userSession')

可悲的是,最终,一切都错了。但这是您使用 ZF 1 可以做到的最好的事情。您应该期待 ZF 2 和 Symfony 2 来更好地理解这些概念。

这是一个很好的解释:http://symfony.com/doc/current/book/service_container.html (我知道你用的是ZF,不过没关系,概念才是关键)

【讨论】:

  • 我要谢谢你!不仅为您提供了很好的答案,还因为在此答案之后,我终于决定更深入地研究 DI,并且在两天后,我成为了使用 Symfony2 服务容器的绝佳解决方案!也许这只是现在的情绪,但第一眼看起来令人印象深刻。
猜你喜欢
  • 2016-10-09
  • 2011-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多