ThinkPHP 跨控制器页面跳转 官方文档 未讲清楚
来源:互联网 发布:七微南风知我意2微盘 编辑:程序博客网 时间:2024/06/08 08:17
摘要:在ThinkPHP学习过程中使用系统Controller类库提供的success()/error()跳转方法,官方《ThinkPHP3.2.3快速入门 》文档、《ThinkPHP3.2.3完全开发手册 》文档,都没有讲清楚跳转其它控制器/操作的原理,这里将从TP的源码讲解跳转过程,明确问题所在,以及怎样修正。
一 . 需要提前了解的东西
<a>标签的href属性
href 属性的值可以是任何有效文档的相对或绝对 URL,包括片段标识符和 JavaScript 代码段。如果用户选择了 <a> 标签中的内容,那么浏览器会尝试检索并显示 href 属性指定的 URL 所表示的文档,或者执行 JavaScript 表达式、方法和函数的列表。
举例解释:
下面要讲到的TP的Controller类库的success/error方法其实是在模板中使用了第二种方法来跳转的。
二 . success/error方法问题所在、及修正
先说问题出在哪里,当我在Index控制器里面希望跳转至Login控制器里面,按照官方文档的说法是这样做:
$this->error(‘马上跳转!’,’Login/index’,1);
可事实并不是这样
URL会从
http://localhost/ThinkPHP_Test/index.php/Home/Index/index
跳转至
http://localhost/ThinkPHP_Test/index.php/Home/Index/Login/index
这显然不是我想要的,现将问题追踪的思路列举如下,并提出修正方法。
上我自己的测试代码。
//IndexController.class.php<?phpnamespace Home\Controller;use Think\Controller;class IndexController extends Controller { public function index(){ $this->display(); } public function click(){ $this->error('马上跳转!','../Login/index',1); //$this->redirect('Login/index'); }}?>
//这是模板文件Index/index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Index index</title></head><body> <h1>Index index</h1> <a href="{:U('Index/click')}">跳转</a> <br/> <a href="../Login/index">不用U的跳转</a></body></html>
//LoginController.class.php<?phpnamespace Home\Controller;use Think\Controller;class LoginController extends Controller{ public function index(){ $this->display(); }}?>
//这是模板文件Login/index.html<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Login index</title></head><body> <h1>Login index</h1></body></html>
下面来做说明:
1).TP的配置声明:
- URL_MODEL是1,为PATHINFO模式;
- 没有为Home模块做绑定;
- PHP配置文件没有开启重写模块;
- PHP的配置文件sites-enabled/000-default里面AllOverride None
2).运行TP
http://localhost/ThinkPHP_Test/index.php/Home/Index/index
3).点击“跳转”链接
当前页面源码里面可以查看到,这个“跳转”链接的href已经被ThinkPHP模板引擎替换为:
/ThinkPHP_Test/index.php/Home/Index/click.html
说明U()方法是将’Index/click’这样的字符串处理成了URL绝对地址,这样的访问是最安全的
4).Index控制器的click方法被调用
执行跳转命令。
官方文档是这样写的:
$this->error(‘马上跳转!’,’Login/index’,1);
下面我们用这种错误的用法来trace一下TP的源码,看看会出现什么问题
5).调用Think\Controller类库里面的error方法
把error方法源码贴上:
这里说明:success/error方法都调用这个dispatchJump,方法,不同的是success方法传入的$status参数为1,error方法传入的$status参数为0.
private function dispatchJump($message,$status=1,$jumpUrl='',$ajax=false) { if(true === $ajax || IS_AJAX) {// AJAX提交 $data = is_array($ajax)?$ajax:array(); $data['info'] = $message; $data['status'] = $status; $data['url'] = $jumpUrl; $this->ajaxReturn($data); } if(is_int($ajax)) $this->assign('waitSecond',$ajax); if(!empty($jumpUrl)) $this->assign('jumpUrl',$jumpUrl); // 提示标题 $this->assign('msgTitle',$status? L('_OPERATION_SUCCESS_') : L('_OPERATION_FAIL_')); //如果设置了关闭窗口,则提示完毕后自动关闭窗口 if($this->get('closeWin')) $this->assign('jumpUrl','javascript:window.close();'); $this->assign('status',$status); // 状态 //保证输出不受静态缓存影响 C('HTML_CACHE_ON',false); if($status) { //发送成功信息 $this->assign('message',$message);// 提示信息 // 成功操作后默认停留1秒 if(!isset($this->waitSecond)) $this->assign('waitSecond','1'); // 默认操作成功自动返回操作前页面 if(!isset($this->jumpUrl)) $this->assign("jumpUrl",$_SERVER["HTTP_REFERER"]); $this->display(C('TMPL_ACTION_SUCCESS')); }else{ $this->assign('error',$message);// 提示信息 //发生错误时候默认停留3秒 if(!isset($this->waitSecond)) $this->assign('waitSecond','3'); // 默认发生错误的话自动返回上页 if(!isset($this->jumpUrl)) $this->assign('jumpUrl',"javascript:history.back(-1);"); $this->display(C('TMPL_ACTION_ERROR')); // 中止执行 避免出错后继续执行 exit ; } }
AJAX提交的方式我们不看。
可以看到’Login/index’这个字符串是直接赋值给了$jumpUrl,可以看到在第10行赋值给模板了,名字也是jumpUrl。
6).再去看看TP的默认模板文件是怎么处理的
这里只摘出关键代码:
页面自动 <a id="href" href="<?php echo($jumpUrl); ?>">跳转</a>等待时间: <b id="wait"><?php echo($waitSecond); ?></b><script type="text/javascript">(function(){var wait = document.getElementById('wait'),href = document.getElementById('href').href;var interval = setInterval(function(){ var time = --wait.innerHTML; if(time <= 0) { location.href = href; clearInterval(interval); };}, 1000);})();</script>
’Login/index’字符串直接赋值给href属性,在等待$waitSecond后,将页面定位到href属性值,这里出了问题,当把’Login/index’直接赋值给href属性的时候,浏览器会将现在的URL:
http://localhost/ThinkPHP_Test/index.php/Home/Index/index
跳转成:
http://localhost/ThinkPHP_Test/index.php/Home/Index/Login/index
这样就达不到我们的要求了
所以正确的做法是:
在需要跳转的时候这么做:
$this->error(‘马上跳转!’,’../Login/index’,1);
相当于向上去一个目录,替换掉Index控制器,这样才能跳转成功。
<完>
- ThinkPHP 跨控制器页面跳转 官方文档 未讲清楚
- thinkphp 同一控制器内方法跳转
- thinkphp 控制器间跳转,并传参
- Thinkphp 控制器->跳转和重定向
- Thinkphp中页面的跳转
- thinkphp 页面跳转传递参数
- thinkphp 跨控制器调用
- ThinkPHP--跨控制器调用
- Thinkphp页面跳转设置跳转等待时间
- Laravel 5.4 官方文档摘记:控制器
- 控制器跨级跳转
- ThinkPHP之跨控制器调用
- ThinkPHP跨控制器调用方法
- ThinkPHP跨控制器调用方法
- SpringMVC—ParameterizableViewController控制器实现跳转页面
- SpringMVC—UrlFilenameViewController控制器实现跳转页面
- 导航控制器Navigation实现页面跳转
- tabBar控制器,跳转到指定的页面
- jstl-functions的用法
- JSP入门之自定义标签
- 360加固宝
- sleep和wait有什么区别
- sss
- ThinkPHP 跨控制器页面跳转 官方文档 未讲清楚
- netty5笔记-线程模型3-EventLoop
- vm和主机互相ping不通
- 快速识别汇编中等价的C语言语句(if, while, for, switch)
- 前缀转中缀(利用栈)
- Python模块
- maven2中snapshot快照库和release发布库的应用
- Dropout原理介绍
- 标题和图片的兼容性