Zend_Auth、Zend_Acl的使用实例(在Action中使用Acl)
引导文件(该程序防于 /webroot/zf/下面
(本人比较衰,总是给别人做,而且无法掌握服务器,不能部署Url-Rewrite,所以都不使用url重写,所以需要setBaseUrl)
数据库表:
CREATE TABLE `user` (
`uid` SMALLINT( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 20 ) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL ,
`password` CHAR( 32 ) NOT NULL ,
`role` ENUM( 'user', 'staff', 'admin' ) NOT NULL ,
`truename` VARCHAR( 20 ) CHARACTER SET gbk COLLATE gbk_chinese_ci NOT NULL ,
INDEX ( `role` , `truename` ) ,
UNIQUE (
`username`
)
) ENGINE = MYISAM CHARACTER SET gbk COLLATE gbk_chinese_ci COMMENT = '用户表';
在数据库中存储了一个role字段(枚举类型),以保存用户角色信息!
<?php
error_reporting(E_ALL);
require './Zend/Loader.php';
function __autoload($class)
{
Zend_Loader::loadClass($class);
}
//初始化访问控制连
$acl = new Zend_Acl;
$acl->add(new Zend_Acl_Resource('Default'));
$acl->add(new Zend_Acl_Resource('News'));
//上面对应我的两个module,一个Default,一个News
$acl->addRole(new Zend_Acl_Role('guest'));
$acl->addRole(new Zend_Acl_Role('user'), 'guest');
$acl->addRole(new Zend_Acl_Role('staff'), 'user');
$acl->addRole(new Zend_Acl_Role('admin'));
$acl->allow('guest', array('Default', 'News'), 'view');
$acl->allow('user', array('Default', 'News'), array('reply', 'download'));
$acl->allow('staff', array('Default', 'News'), array('delete', 'update'));
$acl->allow('admin');
//验证权限,如果没有登录则以游客身份登录
$auth = Zend_Auth::getInstance();
if(!$auth->hasIdentity())
{
$auth->getStorage()->write((object)array('username' => 'Guest',
'role' => 'guest',
'truename' => '游客'));
}
$router = new Zend_Controller_Router_Rewrite();
//$router->addRoute('root',new Zend_Controller_Router_Route('/',array('module' =>'News', 'controller' => 'Index', 'Action' => 'index'))); 也是给出默认控制器的
$front = Zend_Controller_Front::getInstance()->setControllerDirectory(array(
'default' => './Default/Controllers',
'News' => './News/Controllers'
))
->setRouter($router)
->setParam('Zend_Acl', $acl)
->setParam('Zend_Auth', $auth)
->setBaseUrl('/zf/index.php')
->setParam('noViewRenderer', true)
->setParam('useDefaultControllerAlways',true)
->throwExceptions(true)->returnResponse(false)
->dispatch();
?>
在Action中使用Zend_Acl(Default模块中的IndexController,访问他的downloadAction):
<?php
class IndexController extends Zend_Controller_Action
{
public function indexAction()
{
$view = new Zend_View;
$view->name = '张心灵';
$view->title = '测试';
$view->setScriptPath('./Default/Views/Index');
$view->addScriptPath('./Default/Views');
$this->getResponse()->appendBody($view->render('Index.phtml'));
}
public function downloadAction()
{
$acl = $this->getInvokeArg('Zend_Acl');
if(!$acl->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, 'Default', 'download')) $this->getResponse()->appendBody('访问不合法');
else $this->getResponse()->appendBody('合法访问');
}
}
测试地址:http://localhost/zf/index.php/index/download
当然,据称更好的办法是在 preDispatch 方法中控制权限
测试代码如下:
<?php
class IndexController extends Zend_Controller_Action
{
public function preDispatch()
{
if(!$this->getInvokeArg('Zend_Acl')->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, ucfirst($this->getRequest()->getModuleName()), $this->getRequest()->getActionName()))
$this->_forward('index', 'user', 'Default');
}
public function indexAction()
{
$view = new Zend_View;
$view->name = '张心灵';
$view->title = '测试';
$view->setScriptPath('./Default/Views/Index');
$view->addScriptPath('./Default/Views');
$this->getResponse()->appendBody($view->render('Index.phtml'));
}
public function downloadAction()
{
$acl = $this->getInvokeArg('Zend_Acl');
if(!$acl->isAllowed($this->getInvokeArg('Zend_Auth')->getStorage()->read()->role, 'Default', 'download')) $this->getResponse()->appendBody('访问不合法');
else $this->getResponse()->appendBody('合法访问');
}
}
执行结果还是OK的!不过就是感觉在 preDispatch 中控制权限比较呆板啦!
运行的Perfect!(感谢CCTV、感谢Channal V................)
很简单的是,您可以将 访问不合法那句 改为 _froward 等等,让用户登录就行了,看起来Zend Framework使用还是蛮方便的(除了Zend_XmlRpc,那么大个Bug,居然这么就了都没修复)