ThinkPHP3.1URL分发BUG修正
请先留意以下PHP脚本
PHP脚本A(http://127.0.0.1:8110/test.php):
$url = 'http://127.0.0.1:8110/demo.php';
//curl请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'a=dwadwafadwadwadwa&m=dwadwa');
$result = curl_exec($ch);
var_dump($result);
exit();
PHP脚本B(127.0.0.1:8110/demo.php):
var_dump("PHP input:" . file_get_contents('php://input'));
var_dump("POST data:" . $_POST);
执行脚本A的输出结果:
string(81) "string(38) "PHP input:a=dwadwafadwadwadwa&m=dwadwa" string(15) "POST data:Array" "
咦?为何会如此呢?
其实在PHP跟其他编程语言一样,也是有它自己默认的输入流和输出流的。在Web环境下,输入流就是HTTP请求的POST的原始数据,输出流就是HTTP Body,在CLI环境下,就是当前标准的输入输出流(STDIN STDOUT)。而PHP的$_POST全局数组,则是从php://input中解析获得的。
注意1:$HTTP_RAW_POST_DATA也能获取HTTP请求的POST的原始数据,但仅在碰到为识别的MIME类型时产生
注意2:php://input和$HTTP_RAW_POST_DATA均不能在enctype="multipart/form-data"的表单提交下获得数据
接着进入正题,可以看到ThinkPHP3.1的Lib/Core/Dispatcher.class.php有如下代码片段(约在233行):
/**
* 获得实际的操作名称
* @access private
* @return string
*/
static private function getAction($var) {
$action = !empty($_POST[$var]) ?
$_POST[$var] :
(!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION'));
unset($_POST[$var],$_GET[$var]);
在ThinkPHP中Lib/Core/Dispatcher.class.php充当了路由分发的功能(也可以叫前端控制器),这个类负责解析URL并根据约定和配置把后续请求交给指定的Controller和Action执行。
一旦我们在开发中使用了依赖php://input读取请求数据的约定(如一些Flash上传插件,XML-RPC,内部接口服务等等),而刚好提交的数据(可能是二进制数据)又恰好被理解成 /&.+=.+/ 这类字符串,则会导致ThinkPHP出现莫名其妙的URL分发错误(失败)或请求的数据不完整的问题。
而这都是因为ThinkPHP在分发过程中,先检查$_POST再检查$_GET,而且检查获取后又多此一举进行unset造成的。
至此,Lib/Core/Dispatcher.class.php可以修改如下:
/**
* 获得实际的操作名称
* @access private
* @return string
*/
static private function getAction($var) {
// $action = !empty($_POST[$var]) ?
// $_POST[$var] :
// (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION'));
// unset($_POST[$var],$_GET[$var]); $action = (!empty($_GET[$var])?$_GET[$var]:C('DEFAULT_ACTION'));
unset($_GET[$var]);
问题则解决。
总结:该问题很难被发现,也难以定位原因,而且似乎只在ThinkPHP运行在 'URL_MODEL' => 0 模式下才发生。
ThinkPHP3.1URL分发BUG修正的更多相关文章
- Bug修正
名称:nice! 项目名称:约跑app 组长:李权 成员:韩媛媛 刘芳芳 宫丽君 于淼 Bug修正: 1.我看到的现象:退出当前的账号后,按返回键可以再次进入登录界面. 期待的现象:能够安全登陆和退出 ...
- HubbleDotNet 最新绿色版,服务端免安装,基于eaglet 最后V1.2.8.9版本开发,bug修正,支持一键生成同步表
HubbleDotNet 是一个基于.net framework 的开源免费的全文搜索数据库组件.开源协议是 Apache 2.0.HubbleDotNet提供了基于SQL的全文检索接口,使用者只需会 ...
- Lazarus下面的javascript绑定另外一个版本bug修正
Lazarus下面的javascript绑定另外一个版本bug修正 从svn 检出的代码有几个问题 1.fpcjs.pas 单元开始有 {$IFDEF FPC} {$MODE delphi} {$EN ...
- 王者荣耀交流协会互评Beta版本及答复功能改进建议、Bug修正
互评Beta版本 欢迎来怼团队博客园安卓APP Thunder团队爱阅app 探路者团队贪吃蛇 Hello World!团队项目空天猎 答复功能改进建议 答复其他各组给出的“就现有技术和工作量,不改变 ...
- ThinkPHP3.1在多数据库连接下存储过程调用bug修正
最近使用ThinkPHP3.1进行一个项目的开发,由于该项目需要连接多台不同的数据库,所以使用如下配置方法: <?php return array( //'配置项'=>'配置值' //数据 ...
- NVelocity-0.4.2.8580 的修改记录[发个vs2008能用的版本] -- "It appears that no class was specified as the ResourceManager..." bug 修正等
因为另有开发记录工具最新没怎么在 cnblog 写开发备忘.不过我觉得这个是个比较严重的问题,觉得有必要让更多的人知道处理方法,所以在 cnblog 也放上一篇希望广为传播. 因为现在网络上vs200 ...
- [算法 笔记]2014年去哪儿网 开发笔试(续)第一题BUG修正
上一篇的blog地址为:http://www.cnblogs.com/life91/p/3313868.html 这几天又参加了一个家公司的笔试题,在最后的编程题中竟然出现了去哪儿网开发的第一题,也就 ...
- KEIL CRACK及 0xFD Bug修正方法
0xFD Bug是keil编译器中始终存在,而又从未得到官方修复的一个BUG!!! BUG描述:当C源代码中使用了汉字等非ASCII字符,而此字符的编码又恰好包含了大于或等于0xFD的字节时,这个字节 ...
- C++ Primer第18章Vector的再实现及bug修正
C++Primer第18.1.2节在介绍allocator类的时候,给了一个仿照标准库中vector的例子.感觉示例代码非常好,但是本人发现了一个bug,与大家共享. 按照作者的示例程序,编译程序时总 ...
随机推荐
- POJ 2886 Who Gets the Most Candies? (线段树)
[题目链接] http://poj.org/problem?id=2886 [题目大意] 一些人站成一个圈,每个人手上都有一个数字, 指定从一个人开始淘汰,每次一个人淘汰时,将手心里写着的数字x展示 ...
- Intel VTune性能分析器基础
https://wenku.baidu.com/view/b0fe162ebd64783e09122b66.html
- zookeeper 学习笔记3
ZooKeeper 允许客户端向服务端注册一个 Watcher 监听, ZooKeeper 允许客户端向服务端注册一个 Watcher 监听, ZooKeeper 允许客户端向服务端注册一个 Watc ...
- 脑科学对基金经理的八个启示 z
脑科学对基金经理的八个启示 第一,总想要更多.人类大脑是在物资奇缺过程中进化的,所以获得任何“资源”,如食物.性.金钱等,都可以让人感觉良好,大脑也会鼓励我们继续下去. 事实上,可卡因等药物就是“绑架 ...
- spring-data-jpa动态条件查询
//获取动态条件的集合List<Long> list = new ArrayList<Long>(); Long sysUserId = currentUser.getSysU ...
- python项目构建工具zc.buildout
转载:http://blog.csdn.net/u011630575/article/details/52940099 buildout简介 Buildout 是一个基于Python的构建工具, Bu ...
- 18 Tar Command Examples in Linux
FROM: http://www.tecmint.com/18-tar-command-examples-in-linux/ 18 Tar Command Examples in Linux By R ...
- Android学习(十二) ContentProvider
一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据, ...
- Android无数据线调试方法
平时在Android设备上调试程序.通常是将Android设备用数据线和PC机相连. 可是,在没有数据线的情况下也能够: 1.将PC机和Android设备连到同一网段. 2.获取Android设备的I ...
- 算法练习--ABCD*E=DCBA
//1.ABCD * E = DBCA//2.A,B,C,D {0-9} , E {1-9}//3.A,B,C,D,E all different var existSameN = function ...