0

我正在尝试集成Zend_Acl到我的应用程序中:

class AuthController extends Zend_Controller_Action
{
    public function __construct (Zend_Auth $auth, Zend_Acl $acl)
    {
        $this->_auth = $auth;
        $this->_acl  = $acl;
    }
}

但我收到了这个错误:

AuthController::__construct() 的声明必须与 Zend_Controller_Action_Interface::__construct() 的声明兼容......

有任何想法吗?

4

4 回答 4

0

你可以使用一个插件:

//This class effectively extends Zend_Controller_Front
//This plugin will dispatch with every request and provide user access control
//based on credentials provided at login.
class MY_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        parent::preDispatch($request);
        //setup ACL
        $acl = new Zend_Acl();
        //add Roles
        $acl->addRole('guest');
        //add Resources
        $acl->add(new Zend_Acl_Resource('default'));
        //set up access rules, everyone has access to the index page and the error page.
        $acl->allow(NULL, array('index', 'error'));
        $acl->allow(NULL, array('index', 'index'));
        //a guest can only read content and login
        $acl->allow('guest', 'page', array('index'));
        //more ...
        //fetch current user, $auth is set in loginAction()
        $auth = Zend_Auth::getInstance();
        if ($auth->hasIdentity()) {
            $identity = $auth->getIdentity();
            $role = strtolower($identity->role);
        } else {
            $role = 'guest';
        }
        $module = $request->getModuleName();
        $controller = $request->getControllerName();
        $action = $request->getActionName();

        if (!$acl->isAllowed($role, $module, $controller, $action)) {
            if ($role == 'guest') {
                $request->setControllerName('user');
                $request->setActionName('login');
            } else {
                $request->setControllerName('error');
                $request->setActionName('noauth');
            }
        }
    }
}

在 application.ini 中注册插件:

resources.frontController.plugins.acl = "My_Controller_Plugin_Acl"

这只是一个(简单)实现,有很多方法可以给这只猫剥皮。

希望这可以帮助。

于 2012-06-01T10:58:41.257 回答
0

你永远不会启动控制器实例,因为它的工作是 Zend_Controller_Front 为你做这件事,因此你不能使用它的构造函数。但是你可以做的是使用 Zend_Registry

在您的 Bootstrap.php 中

Zend_Registry::set('acl',$acl);
Zend_Registry::set('auth',$auth);

在您的控制器中

public function init()
{
  $this->_acl = Zend_Registry::get('acl');
  $this->_auth = Zend_Registry::get('auth');
}

这个 init 函数充当构造函数。

于 2012-06-01T07:10:25.027 回答
0

Zend_Controller_Action_Interface对于构造函数看起来像这样:

public function __construct(Zend_Controller_Request_Abstract $request,
                            Zend_Controller_Response_Abstract $response,
                            array $invokeArgs = array());

这意味着您的类必须具有相同的构造函数声明

于 2012-06-01T01:04:38.550 回答
0

由于您无法更改构造函数,因此您必须以不同的方式传递 ACL。另请记住,您可以Zend_Auth随时通过调用访问Zend_Auth::getInstance()

要访问您的 ACL,您可以使用Zend_Registry. 如果您在引导程序中定义 ACL,请将其放在注册表中。然后,您可以通过注册表访问它,甚至可以编写一个新类 extends Zend_Controller_Action,它提供了一种检索 ACL 的方法。

于 2012-06-01T01:15:54.423 回答