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,与大家共享. 按照作者的示例程序,编译程序时总 ...
随机推荐
- 解魔方的机器人攻略15 – 安装 Eclipse
由 动力老男孩 发表于 2009/12/27 17:40:49 在远古时代,程序员们通常用写字板来编写Java程序,然后用Javac.exe和Java.exe来编译和执行.对于NXT来说,对应的命令是 ...
- rs485
rs485 编辑 智能仪表是随着80年代初单片机技术的成熟而发展起来的,现在世界仪表市场基本被智能仪表所垄断.究其原因就是企业信息化的需要,企业在仪表选型时其中的一个必要条件就是要具有联网通信接口.最 ...
- JAVA常见算法题(二十二)
package com.xiaowu.demo; //利用递归方法求5!. public class Demo22 { public static void main(String[] args) { ...
- [置顶]
kubernetes资源对象--ResourceQuotas
概念 Resource Quotas(资源配额,简称quota)是对namespace进行资源配额,限制资源使用的一种策略. K8S是一个多用户架构,当多用户或者团队共享一个K8S系统时,SA使用qu ...
- C++完美实现Singleton模式[转]
Singleton模式是常用的设计模式之一,但是要实现一个真正实用的设计模式却也不是件容易的事情.1. 标准的实现class Singleton{public: static Singleton * ...
- 关于计算机中的《补码》,公式:-n=~n+1 引伸:~n=-n-1
在计算机系统中,数值一律用补码来表示(存储).主要原因是使用补码可以将符号位和其他位统一处理:同时,减法也可以按加法来处理.另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃.补 ...
- ElasticSearch文档
1.什么是文档? 程序中大多的实体或对象能够被序列化为包含键值对的JSON对象,键(key)是字段(field)或属性(property)的名字,值(value)可以是字符串.数字.布尔类型.另一个对 ...
- 面试——String的比较总结
public class StringTest { private static String getA() {return "a";} public static void ma ...
- 谷歌安卓UI自动化测试策略
中文翻译版: 为了使大家确信"应做单元测试,就一定能做单元测试",谷歌测试工程师Mona El Mahdy专门写了一篇博客,提出了几种执行安卓应用用户界面单元测试的方法.Mahdy ...
- MySQL架构组成之物理文件组成
一.日志文件 1.错误日志:Error Log 内容:MyQL Server 执行过程中全部较为严重的警告和错误信息,以及MySQL Server 每次启动和关闭的具体信息. 路径:默认存放位置在 ...