【问题标题】:How do I reuse code in Zend Framework如何在 Zend Framework 中重用代码
【发布时间】:2011-03-04 01:56:27
【问题描述】:

我正在开发一个 Web 应用程序,该应用程序要求用户在查看或执行任何操作之前先登录。此应用的任何部分都不应在未登录的情况下访问。(当然,登录控制器除外)

目前我正在使用会话来处理身份验证,并且我已将代码放入 init() 函数中的每个控制器中,以检查它们的会话是否有效。

这是一个临时的解决方法,但它是多余且低效的。

我希望我的 init() 函数类似于以下,但我不知道如何实现它:

public function init()
{
    // If user not logged in redirect to login controller
    $myLibrary = Zend_Library_MyLibrary();
    $myLibrary->CheckAuth();
}

所以我的问题真的有两个部分:

  1. 存储将在多个控制器中使用的代码的最佳位置在哪里?
  2. 然后如何从控制器调用该函数?

谢谢。

【问题讨论】:

    标签: php zend-framework code-reuse


    【解决方案1】:

    跨多个控制器重用的代码最好放在ActionHelper 中。但是,对于您的情况,我建议写一个Controller plugin。那些钩到Dispatch process at various stages

    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {
        if(!Zend_Auth::getInstance()->hasIdentity())
        {
            $request->setControllerName('auth');
            $request->setActionName('login');
            // Set the module if you need to as well.
        }
    }
    

    以上假设您使用的是Zend_Authauthenticate and manage your user identities

    您需要一个插件而不是助手,因为检查用户是否登录应该会自动发生,而您不必在某处调用checkAuth() 方法。当然,也没有什么能阻止您添加 ActionHelper,例如

    class My_Helper_CheckAuth extends Zend_Controller_Action_Helper_Abstract
    {
        public function checkAuth()
        {
            return Zend_Auth::getInstance()->hasIdentity();
        }
        public function direct()
        {
            return $this->checkAuth();
        }
    }
    

    在引导程序中注册帮助程序后,您可以在每个控制器中使用它来检查用户是否已通过身份验证:

    if ( $this->_helper->checkAuth() === FALSE) {
        // do something
    }
    

    另请参阅这些教程:

    【讨论】:

    • 有一个部分我不明白。如果在调度期间使用 ControllerPlugin 检查身份验证,那不会导致无限循环吗?示例:他们尝试访问一个页面 -> Dispatch 未检测到身份验证 -> 重定向到登录页面 -> Dispatch 未检测到身份验证 -> 重定向到登录页面 -> 等等......等等...... PS:还有其他实例ActionHelper 会让我的生活变得更轻松,感谢您的大力响应。
    • @Mario 是的,这确实会造成无限循环。您可以使用 ACL 来解决这个问题(这将是一个很好的其他问题),或者只是将一些代码添加到 dispatchLoopStartup 方法,检查当前的 $request->getAction/ControllerName() 是否是登录页面。很抱歉没有一开始就指出来。
    • 这就是我的想法......我只需要在身份验证检查期间适应登录页面。无论如何,我迫不及待地想同时使用 Controller 插件和 ActionHelper。感谢您的所有帮助。
    【解决方案2】:

    http://zendframework.com/manual/en/zend.controller.plugins.html

    注册一个前端控制器插件并挂钩到调度过程的早期部分是我的做法。

    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin(new Zend_Controller_Plugin_AuthCheck());
    

    把它放在你的 index.php 中。

    class AuthCheck extends Zend_Controller_Plugin_Abstract {
        public function preDispatch($request){
            // Check Auth
    
        }
    }
    

    【讨论】:

    • 补充说明,如果还不清楚的话;无论您在preDispatch 中输入什么,都将始终运行,因此您不必直接调用它。
    【解决方案3】:

    虽然,对于这个特定示例,您最好的选择是(可能)使用前端控制器插件,您也可以通过扩展 Zend_Controller_Action 来重用代码。如果您一直在使用 Zend_Auth,下面是一个人为的示例。这将进入library/Application/Controller 并命名为Action.php。如果您使用不同的命名空间,您可以将应用程序目录的名称交换为该名称 (library/[namespace]/Controller/Action.php) 并相应地重命名该类。

    class Application_Controller_Action extends Zend_Controller_Action
    {
        protected $_loggedIn;
        protected $_username;
        protected $_flashMessenger = null;
    
        public function init()
        {
            $auth = Zend_Auth::getInstance();
            $this->_loggedIn = $auth->hasIdentity();
            if($this->_loggedIn)
            {
                $user = $auth->getIdentity();
                $this->_username = $this->view->escape($user->username);
            }
            $this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
            $this->initView();
        }
        ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多