也是Zend_Controller_Action的几个使用技巧
时间:2007-08-21
来源:互联网
也贴一些实在的代码,大家讨论一下。也许有更技巧的方法,希望有经验的多多提意见。
1、验证问题。
2、编码转换
3、相同的Controller指向不同的View
4、_redirect函数重构
5、baseUrl的问题
我们都知道,在Zend_Controller_Action里,任何一个请求,都是controller/action构成;而任何一个请求的执行顺序都是init() preDispatch() xxAction() postDispatch()
利用这个,我们可以做很多事情。
1、验证问题。
其实,这个实例大家可以在Getting Started with Zend_Auth by Rob Allen (English) 里找到。当然,英文资料里只是简单实现,很多功能我们可以再扩展。
一个复杂的验证问题是不同页面可能要求验证对象不同。
比如A页面不需要验证。B页面必须登陆用户才能显示;而C必须登陆管理员才能显示。
通过Zend_Controller_Action 继承重构,就可以解决这个问题。
很明显,不需要验证的A页面,我们可以直接直接继承Zend_Controller_Action ,或者写一个MyControllerAction 继承于Zend_Controller_Action,但不增加验证代码。
PHP代码:
abstract class MyControllerAction extends Zend_Controller_Action {}
PHP代码:
abstract class MyControllerAction_User extends MyControllerAction {//截取部分代码
public function init(){
parent::init();
//通过一个模块取得登陆数据
$authMoudle = Moudle_Auth::getInstance();
$this->_loginUser = $authMoudle->isLogin(Object_User::User );
$this->view->loginUser = $this->_loginUser;
}
public function preDispatch(){
//这里判断是否存在该用户,如果不存在跳出
if (empty($this->_loginUser)) {
if(Mobile::isMobile()){
$this->_redirect('/auth/ageover');
}else{
$this->_redirect('/auth/login');
}
}
}
}
还可以写一个MyControllerAction_Admin用来验证其他类用户,控制C页面的显示。
PHP代码:
//截取部分代码abstract class MyControllerAction_Admin extends MyControllerAction {
public function init(){
parent::init();
$authMoudle = Moudle_Auth::getInstance();
//这里就变成验证管理员身份
$this->_loginAdmin = $authMoudle->isLogin(Object_User::Admin );
$this->view->loginAdmin = $this->_loginAdmin;
}
public function preDispatch(){
if (empty($this->_loginAdmin)) {
$this->_redirect('/admin/auth/login');
}
}
}
PHP代码:
class AController extends MyControllerAction{//不需要验证
}
class BController extends MyControllerAction_User{
//验证用户
}
class CdviceController extends MyControllerAction_Admin{
//验证管理员
}
PHP代码:
$frontController->setControllerDirectory(array('default' => './application/controllers',
'admin' => './application/admin/controllers',
));
很多项目数据库保存数据使用UTF-8,而页面显示使用另外一个编码。
我的项目就存在这个问题,页面是SJIS码。数据库等交换保存的全部是UTF-8码。
一个很简单的实现办法就是重构Zend_Controller_Action中的render()方法。注意不是Zend_View里的render()。
大家应该在Controller中几乎每个Action最后一句都是$this->render()。我们就是通过控制这个视图显示,达到编码转换。
PHP代码:
//第四个参数是为ajax设置的。我利用的prototype.js,取得数据自动转为当前页面码,所以不需要提前转换public function render($action = null, $name = null, $noController = false,$ajax = false)
{
$view = $this->initView();
$script = $this->getViewScript($action, $noController);
if($ajax){
$this->getResponse()->appendBody($view->render($script),$name);
}else{
$this->getResponse()->appendBody(mb_convert_encoding($view->render($script), "SJIS",'UTF-8'),$name);
}
}
因此需要再增加以下两个函数用来获取用户提交的$_GET或者$_POST
PHP代码:
public function getUtfParam($key){try{
$_paras = $this->getRequest()->getParam($key);
if(!empty($_paras) and is_string($_paras)){
$_paras = mb_convert_encoding($_paras,'UTF-8', "SJIS,JIS,sjis-win");
}
return $_paras;
}catch (Exception $e){
throw $e;
}
}
public function getUtfPost($key){
try{
if($this->getRequest()->isPost()){
$filter = new Zend_Filter_StripTags();
$value= $filter->filter($this->getRequest()->getPost($key));
$value = trim($value);
if(!empty($value) and is_string($value)){
$value = mb_convert_encoding($value,'UTF-8', "SJIS,JIS,sjis-win");
}
return $value;
}else{
return null;
}
}catch (Exception $e){
throw $e;
}
}
同时开发手机Web和Pc Web的时候,我们都知道手机界面和Pc界面差异很大。
一般情况下几乎完全分离。
但是,实际上我们的服务器端数据确实几乎一样的。
比如,用户请求一个Url http://localhost/user/show/id/111 显示id=111的用户信息
服务器端,也就是我们的controller取得数据一样,但是客户端显示的html确分Pc版和mobile版
重构重构Zend_Controller_Action中的initView()方法可以提供一个很好的解决方案。
PHP代码:
public function initView(){
if (!$this->getInvokeArg('noViewRenderer') && $this->_helper->hasHelper('viewRenderer')) {
return $this->view;
}
require_once 'Zend/View/Interface.php';
if (isset($this->view) && ($this->view instanceof Zend_View_Interface)) {
return $this->view;
}
$request = $this->getRequest();
$module = $request->getModuleName();
$dirs = $this->getFrontController()->getControllerDirectory();
if (empty($module) || !isset($dirs[$module])) {
$module = 'default';
}
$baseDir = dirname($dirs[$module]) . DIRECTORY_SEPARATOR . 'views';
if (!file_exists($baseDir) || !is_dir($baseDir)) {
throw new Zend_Controller_Exception('Missing base view directory ("' . $baseDir . '")');
}
//在这里,我们重新写了[b]$baseDir[/b] ,指向不同目录
if(Mobile::isMobile()){
$baseDir .= DIRECTORY_SEPARATOR .'mobile';
}else{
$baseDir .= DIRECTORY_SEPARATOR .'pc';
}
require_once 'Zend/View.php';
$this->view = new Zend_View(array('basePath' => $baseDir));
return $this->view;
}
PHP代码:
/application/controllers
/models
/views
/mobile
/filters
/helpers
/scripts
/pc
/filters
/helpers
/scripts
其实,这个应用不一定手机版Pc版。我们可以在这里控制不同的View版本,比如:
PHP代码:
if(Version::isVersion('1.0')){$baseDir .= DIRECTORY_SEPARATOR .'version1';
}elseif(Version::isVersion('2.0')){
$baseDir .= DIRECTORY_SEPARATOR .'version2';
}else{
$baseDir .= DIRECTORY_SEPARATOR .'version-test';
}
重构是因为$this->_redirect('user/show');竟然出现错误。(1.0Rc3版本测试结果)
正确的写法是$this->_redirect('/user/show');
因此重写_redirect函数。同时增加session id,支持不支持cookie的浏览器。
PHP代码:
protected function _redirect($url, array $options = array()){if(substr($url,0,strlen('/')) === '/'){
$url = trim($url);
}else{
$url = '/'.trim($url);
}
$url = $url.'?'.SID;
parent::_redirect($url,$options);
}
这个问题也许有更好的解决办法。
在Rob Allen 的教材里,其实有一个bug。如果url写成http://localhost/zf-tutorials/index.php 的话,css不能正确取得。
其实这个baseUrl 可以重写的。
PHP代码:
protected function _init(){$url = $this->_request->getBaseUrl();
$this->_baseUrl = (basename($url)=='index.php')?dirname($url):$url;
$this->view->baseUrl = $this->_baseUrl;
}
最近看了一些Zend_Controller_Action的Plugins 和Action Helpers 好像很强大的样子(因为不懂,所以强大)。
谁有一些经验多多分享。
[ 本帖最后由 qqinxl 于 2007-8-21 00:13 编辑 ]
作者: qqinxl 发布时间: 2007-08-20
作者: lyw0301 发布时间: 2007-08-21
作者: lichao 发布时间: 2007-08-21
作者: bc1998 发布时间: 2008-01-13
而且,现在对Zend Framework热情也过了,不爱写东西了。
论框架,还是看J2EE领域阿。
总觉得Zend Framework缺些什么。
比如国际化问题,觉得http://bbs.phpchina.com/viewthread.php?tid=44407的方法还是不够优雅。
作者: qqinxl 发布时间: 2008-01-16
关于多语言应用,试试Zend_Translate。
作者: Haohappy 发布时间: 2008-01-16
作者: bc1998 发布时间: 2008-01-16
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28