表单提交时,php $ _POST数组为空

时间:2009-08-15 21:35:06

标签: php arrays forms post

我有一个自定义CMS我已经构建完全可以在我的开发盒上运行(Ubuntu / PHP5 + / MySQL5 +)。

我刚将它移动到我的客户端的生产框中,现在所有表单提交都显示为空的$ _POST数组。

我找到了一个技巧来验证数据实际上是使用file_get_contents('php://input');传递的,并且数据显示正常 - $_POST / $_REQUEST数组始终为空。

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

无论表单是通过AJAX提交还是通过常规表单提交,都会发生此问题。

非常感谢任何帮助!

29 个答案:

答案 0 :(得分:161)

我知道这个问题是关于通过表单进行POST的,但是在使用JSON内容类型进行POST时寻找类似问题的答案。找到答案并希望分享它,因为它花了我很多时间。

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

以下是解决问题的方法:

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

希望这有助于某人!

答案 1 :(得分:82)

这是另一个可能的原因 - 我的表单是在没有WWW的情况下提交到domain.com。我已经设置了一个自动重定向来添加“WWW”。 $ _POST数组在此过程中被清空。所以我要做的就是提交到www.domain.com

答案 2 :(得分:19)

我有类似的问题。原来是一个简单的修复。以我的形式

  

< form action =“directory”method =“post”>

其中directory是...目录的名称。我的POST阵列完全是空的。当我在浏览器中查看网址时,结果显示为正斜杠。

在我的操作结束时添加正斜杠就可以了 -

  

< form action =“directory /”method =“post”>

我的$ _POST数组又满了!

答案 3 :(得分:11)

确保,在php.ini中:

  • track_vars(仅适用于非常旧的PHP版本)设置为On
  • variables_order包含字母P
  • post_max_size设置为合理值(例如8 MB)
  • (如果使用suhosin补丁)suhosin.post.max_varssuhosin.request.max_vars足够大。

我想我的第二个建议可以解决你的问题。

答案 4 :(得分:5)

我遇到了类似但略有不同的问题,需要2天才能理解这个问题。

  • 在我的情况下,POST数组也是空的。

  • 然后用file_get_contents('php:// input')检查;那也是 空。

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

然后我检查了实际网址的错误。 URL没有错,但它指向URL中没有index.php的文件夹,我在index.php检查POST。

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

那工作。

在此发布,所以有人会发现它有用。

答案 5 :(得分:5)

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

答案 6 :(得分:4)

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

php_value post_max_size xxMB
php_value upload_max_filesize xxMB

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

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

希望这可以帮助将来的某个人,因为我杀了几个小时来解决这个问题。感谢所有花时间帮助我的人(MrMage,Andrew)

答案 7 :(得分:4)

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

这个

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

OR

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

作品点。

但这失败了

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

答案 8 :(得分:4)

禁用enable_post_data_reading设置会导致此问题。根据文件:

  

enable_post_data_reading

     

禁用此选项会导致不填充$ _POST和$ _FILES。读取postdata的唯一方法是通过php://输入流包装器。这对于代理请求或以内存有效的方式处理POST数据非常有用。

答案 9 :(得分:4)

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

亲切的问候 弗兰克

答案 10 :(得分:3)

--zoom           : Zooms the page   
--margin-bottom  : Set the page bottom margin  
--margin-left    : Set the page left margin  
--margin-right   : Set the page right margin  
--margin-top     : Set the page top margin  
--page-height    : Page Height 

好吧,这是愚蠢的,我会在公共场合骚扰自己,但是我在PHP中敲了一些测试脚本,当我的<form action="test.php" method="post"> ^^^^^^^^^^^^^ 数组为空时,StackOverflow是我看到的第一个地方,我没找到我需要的答案。

我只写了

$_POST

并忘记将方法指定为<form action="test.php">

我相信有人会窃笑,但如果这有助于其他人做同样的事情,那么我不介意!我们都时不时地做到这一点!

答案 11 :(得分:2)

这里有同样的问题!

我试图通过邮递员中的邮寄请求连接到我的本地服务器代码,而这个问题浪费了我很多时间!

对于使用本地项目的任何人(例如邮递员): 使用您的IPv4地址(在cmd中键入ipconfig)而不是“ localhost”关键字。 就我而言:

之前:

localhost/app/login

之后:

192.168.1.101/app/login

答案 12 :(得分:1)

在我的情况下,这是因为我在使用jQuery提交表单之前使用jQuery来禁用页面上的所有输入。 所以我改变了我的“禁用每个输入,甚至'隐藏'类型”:

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

“仅禁用'按钮'类型输入”:

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

这样一来,用户就不会意外地按下“go”按钮两次并且软管我们的数据库! 似乎如果您将'禁用'属性放在'隐藏'类型表单输入上,如果表单已提交,则不会发送其值!

答案 13 :(得分:1)

我花了几个小时来解决一个类似的问题。就我而言,问题是

max_input_vars = "1000"

默认情况下,在php.ini中。我的表单非常庞大,没有上传。 php.ini设置为upload_max_filesize =“ 100M”和post_max_size =“ 108M”,对于我而言,这肯定不是问题。当表单中的变量超过1000个时,PHP行为与max_input_vars相同。它返回空的_POST数组。我希望我能在一个小时之前和几个小时前找到它。

答案 14 :(得分:1)

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

POST方法

我们将进行一些修改,因此在发送请求时将使用POST方法......

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);

必须与任何POST请求一起设置某些http标头。所以我们将它们设置在这些行中......

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);
  }
}

我们为'ready state'更改事件设置了一个处理程序。这与我们用于GET方法的处理程序相同。你可以在这里使用http.responseText - 使用innerHTML(AHAH)插入div,eval it(JSON)或其他任何东西。

http.send(params);

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

答案 15 :(得分:1)

对我来说,.htaccess在未安装mod_rewrite时重定向。安装mod_rewite,一切都很好。

具体做法是:

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

正在执行。

答案 16 :(得分:0)

我的问题是我使用HTML <base>标记来更改测试网站的基本网址。从标头中删除该标记后,$_POST数据又回来了。

答案 17 :(得分:0)

在我的情况下(OVHsotisisé服务器上的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>

`

更多信息:method="post" enctype="text/plain" are not compatible?

答案 18 :(得分:0)

除了MRMage的帖子:

我必须设置此变量来解决某些$_POST变量(大数组&gt; 1000项)消失的问题:

suhosin.request.max_vars = 2500

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

答案 19 :(得分:0)

这类似于@icesar said

但是我试图将内容发布到位于site/api/index.php的api,只发布到site/api,因为它会自动传递给index.php。然而,这显然会导致某些事情变得混乱,因为我的$_POST在飞行中被清空了。只需直接发布到site/api/index.php而不是解决它。

答案 20 :(得分:0)

也许不是最方便的解决方案,但我发现如果我将形式action属性设置为根域,则可以访问index.php并获取已发布的变量。但是,如果我将重写的URL设置为操作,则它不起作用。

答案 21 :(得分:0)

确保在输入标记中使用name =“ 您的变量名”。

我错误地使用id =“ your_variable_name ”。

我花了很多时间来发现错误。

答案 22 :(得分:0)

我从Mod Security收到以下错误:

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"]

一旦我删除了我的mod安全配置进行测试,它就会按预期工作。现在我只需要修改我的规则以保持安全但足够灵活以满足我的需求:)

答案 23 :(得分:0)

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

在我的情况下,问题出在我的.htaccess文件中,因为我添加了一些变量来提高PHP的最大上传限制。我的代码是这样的:

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以前像往常一样返回了数据。 希望这对以后的人有所帮助。

答案 24 :(得分:0)

就我而言,当从HTTP发布到HTTPS时,$ _ POST为空。问题是,表单具有类似//example.com的操作,当我将网址固定为https://example.com时,问题消失了。

答案 25 :(得分:0)

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

这会在PHP上为您创建一个空POST

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

但是,这会起作用

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

答案 26 :(得分:0)

我有同样的问题。 问题是.htaccess

我有一个HTTPS重写规则,并且正在将发帖请求发送到http://而不是https://。 帖子请求由于重定向而被清除。

答案 27 :(得分:0)

空 POST 数组的另一个简单原因可能是没有关闭表单然后添加第二个 .... 当第二个表单提交时,POST 数组将为空。

答案 28 :(得分:-2)

好吧,我认为我应该把我的案子放在这里....我在特定情况下得到的帖子数组是空的。表单效果很好,但有时用户抱怨他们点击提交按钮,没有任何反应。 ....   挖掘一段时间后,我发现我的托管公司有一个安全模块,可以检查用户输入并清除整个帖子阵列(不仅是恶意数据),如果它发现的话。在我的例子中,一位数学老师试图输入等式:dy + dx + 0 = 0;并且数据被彻底抹去。

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