php中post键值过多引起的一个bug

本文探讨了一个在处理大量表单提交时遇到的怪异问题,以及如何通过调整PHP配置解决内存溢出风险,同时强调了合理编码的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


今天在前任开发员遗留的项目中遇到这么一个奇怪的问题。纠结了很长时间,突然间恍然大悟,想起自己以前看过的一篇文章,瞬间所有的怪异现象全有了解释。

这个怪异问题是这样的。

我有一个很长很长的表单。如下:

<form actionmethod=”post”>

<inputtype=”checkbox” name=”user_id[]” value=”001”/>

<inputtype=”text” name=”001_name”/>

<inputtype=”text” name=”001_address”/>

<inputtype=”text” name=”001_email”/>

<inputtype=”checkbox” name=”user_id[]” value=”002”/>

<inputtype=”text” name=”002_name”/>

<inputtype=”text” name=”002_address”/>

<inputtype=”text” name=”002_email”/>

<inputtype=”checkbox” name=”user_id[]” value=”003”/>

<inputtype=”text” name=”003_name”/>

<inputtype=”text” name=”003_address”/>

<inputtype=”text” name=”003_email”/>

.

.

.

<inputtype=”checkbox” name=”user_id[]” value=”500”/>

<inputtype=”text” name=”500_name”/>

<inputtype=”text” name=”500_address”/>

<inputtype=”text” name=”500_email”/>

<inputtype=”submit”/>

</form>

当我提交表单,发现这么个奇怪的问题。我选择前面的用户传过来的$_POST['user_id']是正常的,但是到我选择后面的几个用户(例如第500个用户)时,发现$_POST['user_id']是不存在的。百思不得其解,前面的checkbox和后面的checkbox没有什么区别啊,但是为什么就是传不过去呢?

然后我在php中用file_get_content('php://input')打印出原始的post字符串发现是……user_id%5B%5D=480&……。所名原始post是的的确确把user_id[]原本传输过来的。那么问题肯定是发生在phppost流转化成$_POST数组中出现了问题的。然后发现当我选择前面的用户时…user_id%5B%5D=020&……post字符流位置很靠前,而当…user_id%5B%5D=500在流中的位置很靠后。然后突然想到看过风雪之隅的一片关于通过构造Hash冲突实现各种语言的拒绝服务攻击文章发现php5.3.8之后的版本在配置文件里增加了max_input_vars选项,默认是1000.而我的表单提交的post已经达到2000个,超过1000的限制。所以php就把超过的键值给截掉了。所以导致我选前面的用户$_POST['user_id']有值,选择后面的有没有了的怪异现象。

其次,由于我的键值都很短,所以整个post流并不大,所以不会产生php内存报警。

再次意识到这样大面积构造荣冗余的表达是一个非常糟糕的编码习惯。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值