表单提交时,PHP的$_POST数组为空。

119

我有一个自定义的内容管理系统(CMS),在我的开发环境中(Ubuntu/PHP5+/MySQL5+)运行得非常完美。

我刚把它移到生产环境为我的客户服务,但现在所有的表单提交都显示为空的 $_POST 数组。

我发现了一个技巧来验证数据是否被传递,使用 file_get_contents('php://input'); ,数据在那里正常显示 -- 无论是 $_POST/$_REQUEST 数组总是空的。

我也通过 firebug 验证了正确的 content-type header (application/x-www-form-urlencoded; charset=utf-8)。

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

非常感谢任何帮助!


3
请检查post_max_size的值是否设置为8M而不是8MB。如果设置错误,在最新版本中您可能看不到任何错误,但$_POST的大小将设置为0。 - Sergei Karpov
3
注意:如果缺少斜杠,Apache会进行301重定向。 - Leandro Bardelli
32个回答

241

使用JSON内容类型时,$_POST数组将不会填充(仅适用于多部分表单)。

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

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

2
另一种选择是将 Content-Type 标头更改为 application/x-www-form-urlencoded,然后使用 $.param(dataObject) 序列化数据。这应该会有所帮助。 - ŁukaszBachman
1
@ŁukaszBachman 如果dataobject类似于“title = something&body = anything”,那么该怎么办。我想获取标题和正文的值。$ dataobject [“title”]为空。在我的情况下,$ _POST为空。除了使用file_get_contents(“php:// input”)之外,唯一的获取方法是...除此之外,它没有进行json编码。 - Khurshid Alam
4
https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make#common-mistake-7-assuming-post-will-always-contain-your-post-data - ankitr

104

这里是另一个可能的原因:

我的表单提交到没有www.domain.example,而我设置了自动重定向来添加www.。在此过程中,$_POST数组被清空。

所以要解决这个问题,我只需要提交到www.domain.example


30
该问题的原因是我的 htaccess 中的 URL 重写规则导致 POST 请求无法正常工作。我自动在所有的 URL 后添加斜杠,但是在代码中 ACTION 属性所使用的 URL 却没有斜杠。你的回答有所帮助,因为我之前从未想过要检查 .htaccess 文件。+1 - binar
我以前用Godaddy进行域名转发(带遮罩),这似乎是问题的根源。谢谢! - Chris Prince
2
我也遇到了类似的问题,它来自于我的.htaccess文件。它从URL中剥离了.php扩展名,而我的表单是将POST提交到带有扩展名的URL。 - Emanuel Vintilă
在我花了数小时调试我的WordPress端点之后,我偶然发现了这个答案。非常感谢!! - undefined

30

我遇到了类似的问题。后来发现这是个简单的问题。在我的表单中,我有

<form action="directory" method="post">

其中 "directory" 是目录的名称。我的 $_POST 数组完全为空。当我查看浏览器中的 URL 时,它显示为末尾带有正斜杠。

将正斜杠添加到我的 action 末尾就解决了问题-

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

我的 $_POST 数组再次被填满了!


1
这不应该是一个修复问题,例如在具有良好路由系统的CakePHP上失败了(我并不是说Cake失败了),也许解决这个问题的方法不是框架或.php文件,而是一些Apache配置,我想进一步调查这个问题。这非常有趣。 - James
类似的,我和楼主遇到了同样的问题,但只有在IE浏览器中,当<form>标签没有name属性时才会出现。 - jkt123

15

请确保在php.ini文件中:

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

我认为我的第二个建议将解决您的问题。


1
谢谢MrMage,感谢您的见解,我会查看那些ini设置并告诉您是否有效。谢谢! - Mike D
2
"post_max_size" 设置是我遇到的关键问题。我在表单提交时上传了一个大文件,但这个设置包含的值较小。因此,当我提交表单时,我得到了一个空的 post 数组。 - shasi kanth

11

我发现在从HTTP到HTTPS提交表单时,$_POST为空。这是在测试表单时发生的,但直到我意识到为止,这点花费了我一些时间。


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

这样做可以避免出现路径错误。

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

或者

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

工作正常。

但是这失败了。

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

我实际上有完全相反的情况。我发现/my_uri可以工作,但/my_uri/不行。 - Link14
1
我遇到了同样的问题。看起来是Apache或Nginx将重定向从/api到/api/。 - John Smith
Apache如果缺少斜杠,会自动进行301重定向。感谢您的回答和评论也很有用。 - Leandro Bardelli

6

我曾经遇到一个类似但稍微不同的问题,花了两天时间才理解这个问题。

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

  • 然后检查了一下file_get_contents('php://input');,也是空的。

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

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

我怀疑从 / 重定向到 /index.php 会导致POST数据丢失,并通过在URL中追加index.php 进行了测试。

那样行得通。

在这里发布这篇文章,希望对某些人有所帮助。


2
我曾经遇到过同样的问题,如果URL末尾没有'/',那么在$_REQUEST中就不存在任何内容,但是如果URL末尾有'/'或'/index.php',那么所有发布的数据都会存在于$_REQUEST中。这可能是我的nginx设置或其他什么原因导致的! - MohaMad
在我的fetch URL末尾添加正斜杠也对我有用,例如:fetch("https://myurl.com/api/")而不是只有fetch("https://myurl.com/api") - Rodo P

5
我可以使用enctype="application/x-www-form-urlencoded"来解决这个问题,因为默认值是"text/plain"。当您检查$DATA时,"text/plain"的分隔符是一个空格,而"urlencoded"的分隔符是一个特殊字符。
祝好, Frank

5

如果禁用enable_post_data_reading设置,就会导致这种情况发生。 根据文档:

enable_post_data_reading

禁用此选项会导致$_POST和$_FILES未填充。然后读取postdata的唯一方法是通过php://input流包装器。这可以用于代理请求或以内存高效方式处理POST数据。


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

好的,这很蠢,我将在公共场合出丑,但我用PHP编写了一个小测试脚本,当我的$_POST数组为空时,我在StackOverflow上查找,但没有找到我需要的答案。
我只写了
<form action="test.php">

而忘记将方法指定为POST

我相信有人会嘲笑,但如果这可以帮助做同样事情的其他人,那我不介意!我们都偶尔会犯这种错误!


我简直不敢相信我居然忘了那个!我只是在尝试一个新的服务器,以为那是由于配置问题导致的...无论如何,感谢你提醒我! - Samuel Aiala Ferreira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接