【问题标题】:php $_POST array empty upon form submissionphp $_POST 数组在表单提交时为空
【发布时间】:2010-11-19 22:54:04
【问题描述】:

我有一个自定义的内容管理系统 (CMS),我已经构建了它在我的开发盒 (Ubuntu/PHP5+/MySQL5+) 上完美运行。

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

我发现了一个技巧来验证数据实际上是使用file_get_contents('php://input'); 传递的,并且数据在那里显示得很好——$_POST/$_REQUEST 数组总是空的。

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

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

非常感谢任何帮助!

【问题讨论】:

  • 检查 post_max_size:该值必须设置为 8M,而不是 8MB。在最新情况下,您不会看到任何错误,但 $_POST 大小将设置为 0
  • 注意:如果斜线丢失,Apache 会执行 301 重定向。

标签: php arrays forms post


【解决方案1】:

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

这是我纠正问题的方法:

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

【讨论】:

  • 这个解决方法很有意义 - 它修复了我的批量更新控制器 :)
  • 另一种选择是将Content-Type 标头更改为application/x-www-form-urlencoded,然后使用$.param(dataObject) 序列化您的数据。这应该会有所帮助。
  • @ŁukaszBachman 如果数据对象类似于........title=something&body=anything。我想获得标题和正文的价值。 $dataobject["title"] 返回空。在我的情况下 $_POST 是空的。并且使用 file_get_contents("php://input") 获取它的唯一方法...除了它不是 json 编码的。
  • 这非常有用。奇怪的是,在我的开发机器上发送 Json 没有问题,但在生产机器上发送。
【解决方案2】:

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

【讨论】:

  • 该死,我的htaccess 中的 url 重写是 POST 无法正常工作的原因。我自动将斜杠附加到所有 url,但在作为 ACTION 的代码中,我使用了没有斜杠的 url。您的回答有所帮助,因为我从未想过要检查 .htaccess。 +1
  • 我使用 Godaddy 进行了域转发(带屏蔽),这似乎是问题的根源。谢谢!
  • 我也遇到了类似的问题,它来自我的.htaccess 文件。它正在从 URL 中删除 .php 扩展名,而我的表单是 POSTing 到带有扩展名的 URL。
【解决方案3】:

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

directory 是...目录的名称。我的 POST 数组完全是空的。当我在浏览器中查看 url 时,它的末尾带有正斜杠。

在我的操作末尾添加正斜杠就可以了 -

我的 $_POST 数组又满了!

【讨论】:

  • 这不应该是一个修复,例如在具有良好路由系统的 CakePHP 上,失败了,(我不是说 Cake 失败了),也许解决这个问题的方法不是框架或 .php 文件,但是 apache 上的一些配置,我想对这个问题做进一步的调查。挺有意思的。
  • 在类似的说明中,我遇到了与 OP 相同的问题,但前提是 <form> 标记没有 name 属性,并且仅在 IE 中。
【解决方案4】:

确保在 php.ini 中:

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

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

【讨论】:

  • 感谢 MrMage,感谢您的洞察力,并将检查这些 ini 设置,并让您知道是否成功。谢谢!
  • "post_max_size" 设置是我的亮点。我在表单提交期间上传了一个大文件,而这个设置包含的值较小。因此,当我提交表单时,我得到了一个空的 post 数组。
【解决方案5】:

我发现从 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/ 不行。
    • 遇到了同样的问题。似乎 apache 或 nginx 添加了从 /api 到 /api/ 的重定向
    • 如果斜线丢失,Apache 会自动重定向 301。感谢您的回答,cmets 也很有用。
    【解决方案7】:

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

    亲切的问候 弗兰克

    【讨论】:

      【解决方案8】:

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

      • 在我的例子中,POST 数组也是空的。

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

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

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

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

      成功了。

      把它贴在这里,这样有人会觉得它有帮助。

      【讨论】:

      • 我遇到了同样的问题,在 url 末尾没有 '/', $_REQUEST 中不存在任何内容,但是使用 '/' 或 '/index.php' ,所有发布的数据都存在于 $_REQUEST .可能是我的 nginx 设置或其他什么!
      【解决方案9】:

      禁用enable_post_data_reading 设置将导致此问题。根据文档:

      enable_post_data_reading

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

      【讨论】:

        【解决方案10】:

        目前没有优雅的解决方案,但想分享我的发现,以供以后遇到此问题的其他人参考。问题的根源是 .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)

        【讨论】:

        • 在 Serverfault 上问这个问题可能是值得的,特别是如果问题在于服务器设置/htaccess。
        • 如果我没记错的话,大小应该指定为'xxM',而不是'xxMB',所以我想知道这是否与它有关......
        【解决方案11】:
        <form action="test.php" method="post">
                                ^^^^^^^^^^^^^
        

        好吧,这很愚蠢,我会在公共场合让自己难堪,但我为 PHP 中的某些内容编写了一个小测试脚本,当我的 $_POST 数组为空时,StackOverflow 是我查看的第一个地方,但我没有找不到我需要的答案。

        我只写了

        <form action="test.php">
        

        忘记将方法指定为POST

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

        【讨论】:

        • 不敢相信我也忘记了!我只是在尝试一个新的服务器,并且认为这是由于配置引起的......无论如何,谢谢你的提醒!
        【解决方案12】:

        就我而言,当从 HTTP 发布到 HTTPS 时,$_POST 为空。问题是,表单有这样的操作 //example.com 当我将 url 固定为 https://example.com 时,问题就消失了。

        【讨论】:

        • 我认为与服务器的设置方式有关。我在使用 GoDaddy 作为主机时遇到了同样的问题。此解决方案没有解决问题。
        • 这个解决方案解决了我的问题。我有一个很好的headeach。
        【解决方案13】:

        同样的问题!

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

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

        之前:

        localhost/app/login
        

        之后:

        192.168.1.101/app/login
        

        【讨论】:

        • Postman 给了我一些关于抓取带有引号或空格的 json 值的问题。它需要一种特定的格式。
        【解决方案14】:

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

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

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

        但是,这会起作用

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

        【讨论】:

        • 我认为这与服务器的设置方式有关。我在使用 GoDaddy 作为主机时遇到了同样的问题。此解决方案没有解决问题。
        • 对于那些关心的人,您可能不得不陷入设置自己的.htaccess的噩梦。
        【解决方案15】:

        参考: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);
        

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

        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.responseText - 使用 innerHTML(AHAH)、eval it(JSON) 或其他任何内容插入 div。

        http.send(params);
        

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

        【讨论】:

          【解决方案16】:

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

          在我的情况下,问题出在我的 .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 像以前一样正常返回数据。 希望这对将来的人有所帮助。

          【讨论】:

            【解决方案17】:

            我遇到了同样的问题。 问题是.htaccess

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

            【讨论】:

              【解决方案18】:

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

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

              到“只禁用'按钮'类型的输入”:

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

              这样用户就不会不小心按了两次“开始”按钮并用软管冲洗我们的数据库! 似乎如果您将“禁用”属性放在“隐藏”类型的表单输入上,则如果提交表单,它们的值将不会被发送!

              【讨论】:

                【解决方案19】:

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

                具体来说:

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

                正在执行。

                【讨论】:

                  【解决方案20】:

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

                  max_input_vars = "1000"
                  

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

                  【讨论】:

                    【解决方案21】:

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

                    【讨论】:

                      【解决方案22】:

                      除了MRMage的帖子:

                      我不得不设置这个变量来解决一些$_POST变量(大数组> 1000项)消失的问题:

                      suhosin.request.max_vars = 2500
                      

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

                      【讨论】:

                        【解决方案23】:

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

                        【讨论】:

                          【解决方案24】:

                          这有点类似于@icesar said

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

                          【讨论】:

                            【解决方案25】:

                            我的问题是我使用 HTML &lt;base&gt; 标记来更改我的测试站点的基本 URL。一旦我从标题中删除该标签,$_POST 数据就会返回。

                            【讨论】:

                              【解决方案26】:

                              在我的情况下(OVH 互惠服务器上的 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?

                              【讨论】:

                                【解决方案27】:

                                我从 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 安全配置进行测试,一切都按预期工作。现在我只需要修改我的规则以保持安全但足够灵活以满足我的需求:)

                                【讨论】:

                                  【解决方案28】:

                                  确保在输入标签中使用 name="your_variable_name"。

                                  我错误地使用了 id="your_variable_name"。

                                  我花了很多时间来捕捉错误。

                                  【讨论】:

                                    【解决方案29】:

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

                                    【讨论】:

                                      【解决方案30】:

                                      好的,我想我应该把我的案例放在这里....在特定情况下我将帖子数组设为空..表单运行良好,但有时用户抱怨他们点击了提交按钮,但没有任何反应。 …… 经过一段时间的挖掘,我发现我的托管公司有一个安全模块,可以检查用户输入并在发现时清除整个帖子数组(不仅是恶意数据)。在我的例子中,一位数学老师试图输入方程:dy + dx + 0 = 0;并且数据被完全擦除。

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

                                      【讨论】:

                                      • 要求用户考虑错误代码是不可能的。
                                      • 这并不是真正的错误代码,但您可能会考虑使用新的托管服务提供商。或者以不同的形式发布输入,例如HTML URL 编码。
                                      猜你喜欢
                                      • 1970-01-01
                                      • 2021-06-18
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2013-06-04
                                      • 1970-01-01
                                      • 1970-01-01
                                      • 2016-12-26
                                      • 2010-10-25
                                      相关资源
                                      最近更新 更多