提交表单时 php $_ POST 数组为空

我有一个自定义的内容管理系统(CMS) ,它可以在我的开发框(Ubuntu/PHP5 +/MySQL5 +)上完美工作。

I just moved it up to the production box for my client and now all form submissions are showing up as empty $_POST arrays.

I found a trick to verify the data is actually being passed using file_get_contents('php://input'); and the data is showing up fine there -- the $_POST/$_REQUEST arrays are always empty.

我还通过 firebug (application/x-www-form-urlencoded; charset=utf-8)验证了内容类型标题的正确性。

无论表单是通过 AJAX 提交,还是通过普通表单提交,这个问题都会发生。

非常感谢您的帮助!

187468 次浏览

确保在 php.ini 中:

  • track_vars (it's only available on very old PHP versions) is set to On
  • variables_order包含字母 P
  • post_max_size被设置为一个合理的值(例如8MB)
  • suhosin.post.max_varssuhosin.request.max_vars足够大。

I suppose the second suggestion of mine will solve your problem.

在这一点上没有一个优雅的解决方案,但是想要分享我的发现,以供将来遇到这个问题的其他人参考。问题的根源是在。Htaccess 文件。我只是简单地添加了这两个值,以便将文件上传的文件大小限制从默认的8MB 增加到更大的值——我观察到,在 htaccess 文件中简单地使用这两个值,无论是大于还是小于默认值,都会导致问题。

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

我增加了额外的变量,希望能提高所有 suhosin.post.xxx/suhosin.upload.xxx 变量的极限,但不幸的是,这些变量对这个问题没有任何影响。

总之,我不能真正解释“为什么”在这里,但已经确定了根本原因。我的感觉是,这最终是一个 suhosin/htaccess 问题,但不幸的是,除了删除上面的2php 覆盖值之外,我无法解决这个问题。

希望这能帮到以后的人,因为我花了好几个小时才搞清楚这件事。感谢所有花时间帮助我的人(Mage 先生,Andrew)

还有一个可能的原因:

我的形式是提交到 domain.example没有 www.,我已经建立了一个自动重定向,以添加 www.$_POST数组正在清空的过程中。

所以要修复它,我所要做的就是提交给 www.domain.example

参考文献: http://www.openjs.com/articles/ajax_xmlhttp_using_post.php

POST 方法

We are going to make some modifications so POST method will be used when sending the request...

var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);


//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");


http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);

Some http headers must be set along with any POST request. So we set them in these lines...

http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");

通过以上几行,我们基本上可以说,数据发送是以表单提交的格式进行的。我们还给出了要发送的参数的长度。

http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}

我们为“就绪状态”更改事件设置了一个处理程序。这是我们用于 GET 方法的相同处理程序。您可以在这里使用 http.response seText ——使用 innerHTML (AHAH)、 eval it (JSON)或任何其他方法将其插入到 div 中。

http.send(params);

最后,我们将参数与请求一起发送。只有在调用这一行之后才加载给定的 url。在 GET 方法中,参数将为空值。但是在 POST 方法中,要发送的数据将作为 send 函数的参数发送。Params 变量在第二行声明为 lorem=ipsum&name=binny-因此我们发送两个参数-‘ lorem’和‘ name’,分别带有值‘ ipsum’和‘ binny’。

我可以使用 enctype = “ application/x-www-form-urlencode”来解决这个问题,因为默认值是“ text/plain”。当您签入 $DATA 时,这个分隔符是一个“ text/platen”的空格,以及一个特殊字符“ urlencode”。

问候你 弗兰克

除了 MRMage 的帖子:

我必须设置这个变量来解决一些 $_POST变量(大于1000个项目的大数组)消失的问题:

suhosin.request.max_vars = 2500

request”,而不是“ post”是解决方案..。

对我来说,. htaccess 在 mod _ rewrite 没有安装的时候正在重定向。

具体来说:

<IfModule !mod_rewrite.c>
ErrorDocument 404 /index.php
</Ifmodule>

正在执行。

在我的例子中,这是因为我在使用 jQuery 提交表单之前使用 jQuery 禁用页面上的所有输入。 所以我改变了我的“禁用所有输入,甚至是‘隐藏’类型”:

$(":input").attr("disabled","disabled");

to "disable only the 'button' type inputs":

$('input[type=button]').attr('disabled',true);

这是因为用户不能意外地按下’去’按钮两次,并冲洗我们的数据库! It seems that if you put the 'disabled' attribute on a 'hidden' type form input their values won't be sent over if the form is submitted!

我从国防安全部得到了以下错误:

Access denied with code 500 (phase 2). Pattern match "((select|grant|delete|insert|drop|alter|replace|truncate|update|create|rename|describe)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]+[[:space:]]+(from|into|table|database|index|view)[[:space:]]+[A-Z|a-z|0-9|\*| |\,]|UNION SELECT.*\'.*\'.*,[0-9].*INTO.*FROM)" at REQUEST_BODY. [file "/usr/local/apache/conf/modsec2.user.conf"] [line "345"] [id "300013"] [rev "1"] [msg "Generic SQL injection protection"] [severity "CRITICAL"]

Once I removed my mod security configuration to test, it all worked as expected. Now I just need to modify my rules to stay secure but flexible enough for my needs :)

我发现当从 HTTP 发送到 HTTPS 时,$_POST是空的。 这是在测试表单时发生的,但我花了一段时间才意识到这一点。

我也有过类似的问题。结果是一个简单的解决办法

< form action = “ Directory”method = “ post”> < 表单动作 = “目录”方法 = “发布”>

其中目录是... 目录的名称。我的 POST 数组完全是空的。当我在浏览器中查看网址时,它在结尾处显示一个正斜杠。

将正斜杠添加到我的动作的结尾,这样做的技巧-

< form action = “ directory/”method = “ post”> < 表单动作 = “目录/”方法 = “发布”>

我的 $_ POST 数组又满了!

当使用 JSON 内容类型时,$_POST数组将不会填充(我相信只会填充多部分表单)

以下是我纠正这个问题的方法:

$_POST = json_decode(file_get_contents("php://input"), true);

这可能不是最方便的解决方案,但是我发现,如果将表单 action属性设置为根域,就可以访问 index.php 并获取发布的变量。但是,如果我设置一个重写的 URL 作为操作,它不工作。

这有点类似于@icesar

但是我试图发布东西到我的 api,位于 site/api/index.php,只发布到 site/api,因为它会自己传递到 index.php。然而,这显然导致了一些混乱,因为我的 $_POST在飞行中被清空。直接发布到 site/api/index.php就可以解决这个问题。

我遇到了一个类似但略有不同的问题,花了2天时间才理解这个问题。

  • In my case also POST array was empty.

  • 然后使用 file _ get _ content (‘ php://input’)检查; 空

后来,我发现浏览器没有要求确认重新提交表单数据后,如果我刷新后提交加载的页面。直接刷新页面。但是,当我将表单 URL 更改为另一个 URL 时,它正确地传递 POST,并要求在尝试刷新页面时重新提交数据。

然后我检查了实际的 URL 有什么问题。URL 没有问题,但是它指向一个 URL 中没有 index.php 的文件夹,我在 index.php 检查 POST。

在这里,我怀疑/to/index.php 的重定向会导致 POST 数据丢失,并通过将 index.php 附加到 URL 来测试 URL。

成功了。

把它贴在这里,这样别人就会觉得有用。

我的问题是,我正在使用 HTML <base>标记来更改测试站点的基 URL。一旦我从标题中删除了这个标记,$_POST数据就返回了。

在我的例子中(OVH mutualization 服务器上的 php 页面) enctype="text/plain"不工作($_POST和相应的 $_REQUEST是空的) ,下面的其他示例工作。 `

<form action="?" method="post">
<!-- in this case, my google chrome 45.0.2454.101 uses -->
<!--     Content-Type:application/x-www-form-urlencoded -->
<input name="say" value="Hi">
<button>Send my greetings</button>
</form>


<form action="?" method="post" enctype="application/x-www-form-urlencoded">
<input name="say" value="Hi">
<button>Send my application/x-www-form-urlencoded greetings</button>
</form>


<form action="?" method="post"  enctype="multipart/form-data">
<input name="say" value="Hi">
<button>Send my multipart/form-data greetings</button>
</form>


<form action="?" method="post" enctype="text/plain"><!-- not working -->
<input name="say" value="Hi">
<button>Send my text/plain greetings</button>
</form>

`

More here: Method = “ post”enctype = “ text/plain”是否不兼容?

禁用 enable_post_data_reading设置将导致这种情况。根据文档:

激活 _ post _ data _ reading

禁用此选项将导致不填充 $_ POST 和 $_ FILES。然后,读取 postdata 的唯一方法是通过 php://input 流包装器。这对于代理请求或以高效的内存方式处理 POST 数据非常有用。

如果要发送到/api/index.php 等目录中的 index.php 文件,请确保在表单中指定该文件的完整目录

这个

<form method="post" action="/api/index.php">
</form>

或者

<form method="post" action="/api/">
</form>

工程。

But this fails

<form method="post" action="/api">
</form>
<form action="test.php" method="post">
^^^^^^^^^^^^^

好吧,这是愚蠢的,我会尴尬自己在公共场合,但我搞了一个小测试脚本的东西在 PHP 和当我的 $_POST数组是空的,StackOverflow 是第一个地方,我看,我没有找到我需要的答案。

我只写了

<form action="test.php">

忘了指定方法为 POST

我确信有人会窃笑,但是如果这对其他做同样事情的人有帮助,那么我不介意!我们时不时都会这样!

好吧,我觉得我应该把我的案子放在这里。在特定情况下,我会让文章数组变空。.表单运行良好,但有时用户抱怨他们点击提交按钮,什么也没有发生... ..。 After digging for a while, I discovered that my hosting company has a security module that checks users inputs and clears the whole post array (not only the malicious data) if it discovers so. In my example, a math teacher was trying to enter the equation: dy + dx + 0 = 0; and data was wiped completely.

为了解决这个问题,我建议他现在在文本区域输入数据为 dy + dx + 0 = 0,现在它可以工作了... ..。这可以节省一些时间。.

我刚刚花了几个小时来解决一个类似的问题

max_input_vars = "1000"

默认情况下,在 php.ini 中。我有一个很大的表单,没有上传。将 php.ini 设置为 load _ max _ filesize = “100M”和 post _ max _ size = “108M”,这肯定不是我的问题。当 max _ input _ vars 超过表单中的1000个变量时,PHP 的行为是相同的。它返回空 _ POST 数组。我真希望一小时前就能找到。

确保在输入标记中使用 name = “ Your _ variable _ name”。

我错误地使用 id = “ Your _ variable _ name”。

我花了很多时间才抓住这个漏洞。

same issue here!

i was trying to connect to my local server code via post request in postman, and this problem wasted my time alot!

for anyone who uses local project (e.g. postman): 使用 IPv4地址(在 cmd 中键入 ipconfig)而不是“ localhost”关键字。 就我而言:

以前:

localhost/app/login

之后:

192.168.1.101/app/login

我知道这是旧的,但想分享我的解决方案。

In my case the issue was in my .htaccess as I added variables to raise my PHP's max upload limit. My code was like this:

php_value post_max_size 50MB
php_value upload_max_filesize 50MB

后来我注意到这些值应该是 xxM 而不是 xxMB,当我将它们更改为:

php_value post_max_size 50M
php_value upload_max_filesize 50M

现在我的 $_ POST 正常返回数据。 希望这能帮到将来的某个人。

在我的例子中,当从 HTTP 发送到 HTTPS 时,$_POST是空的。问题是,表单有一个类似于 //example.com的操作,当我将 URL 修复为 https://example.com时,问题就消失了。

确保定义了每个字段的 name属性。

这会在 PHP 上创建一个空的 POST

<input type="text" id="Phone">

但是,这会有用的

<input type="text" name="Phone" id="Phone">

我也有同样的问题。 问题在于 .htaccess

我有一个 HTTPS 重写规则,并将发送请求发送到 http://而不是 https://。 The post request cleared due to redirect.

POST数组的另一个简单原因是没有用 </form>关闭窗体,然后添加第二个 <form>...</form>。当提交第二个表单时,POST 数组将为空。

我在迁移到新服务器时也遇到了同样的问题。在 php.ini文件中设置 post_max_size的值修复了我的问题。

在我的例子中,我的 <form>标签中有 target="_blank",移除它解决了这个问题。

但是,如果您仍然需要在提交之后打开一个新页面,只需将 _blank替换为一个随机值,比如 newtab(它可以是任何值)。

以前:

<form target="_blank" action="api/" enctype="application/x-www-form-urlencoded" method="post">

之后:

<form target="newtab" action="api/" enctype="application/x-www-form-urlencoded" method="post">