【问题标题】:Why would $_FILES be empty when uploading files to PHP?为什么将文件上传到 PHP 时 $_FILES 为空?
【发布时间】:2011-04-04 22:54:55
【问题描述】:

我在我的 Windows 7 计算机上安装了 WampServer 2。我正在使用 Apache 2.2.11 和 PHP 5.2.11。当我尝试从表单上传任何文件时,它似乎在上传,但在 PHP 中,$_FILES 数组为空。 c:\wamp\tmp 文件夹中没有文件。我已配置 php.ini 以允许文件上传等。 tmp 文件夹对当前用户具有读/写权限。我被难住了。

HTML:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
    <form enctype="multipart/form-data" action="vanilla-upload.php" method="POST">
        Choose a file to upload: <input name="uploadedfile" type="file" /><br />
        <input type="submit" value="Upload File" />
    </form>
</body>
</html>

PHP:

<?php
echo 'file count=', count($_FILES),"\n";
var_dump($_FILES);
echo "\n";
?>

【问题讨论】:

  • 你检查过错误日志吗?
  • 我确定你忽略了一些愚蠢的东西。例如,你确定有vanilla-upload.php中的代码吗?
  • 哈,我也遇到了同样的问题。我检查了错误日志,它说正在上传的文件超出了允许的最大大小。
  • 哈,我的&lt;input&gt; 没有name=:D

标签: php apache file-upload


【解决方案1】:

以下是 PHP 文件上传检查清单:

  1. 检查 php.ini 是否有:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M
  • 如果您使用共享主机并且无权访问php.ini,则可能需要使用.htaccess.user.ini
  • 确保 您正在编辑正确的 ini 文件 – 使用phpinfo() 函数来验证您的 实际正在应用设置。
  • 还要确保您没有 拼错大小 - 它应该是 100M 不是 100MB
  1. 确保您的 &lt;form&gt; 标记具有 enctype="multipart/form-data" 属性。没有其他标签可以工作,它必须是您的 FORM 标签。仔细检查它是否拼写正确。仔细检查 multipart/form-data 是否被直引号包围,而不是从 Word 或网站博客中粘贴的智能引号(WordPress 将直引号转换为角引号!)。如果页面上有多个表单,请确保它们都具有此属性。手动输入它们,或者尝试手动输入单引号。

  2. 确保您没有两个具有相同name 属性的输入文件字段。如果需要支持多个,请在名称末尾加上方括号:

    <input type="file" name="files[]">
    <input type="file" name="files[]">
    
  3. 确保您的 tmp 和上传目录设置了正确的读写权限。临时上传文件夹在 PHP 设置中指定为upload_tmp_dir

  4. 确保您的文件目标和 tmp/upload 目录不 里面有空格。

  5. 确保您页面上的所有&lt;form&gt; 都有&lt;/form&gt; 关闭标签。

  6. 确保您的 FORM 标记具有 method="POST"。 GET 请求不支持多部分/表单数据上传。

  7. 确保您的文件输入标签具有 NAME 属性。 ID 属性是不够的! ID 属性用于 DOM,不适用于 POST 负载。

  8. 确保您在提交时未使用 Javascript 禁用 &lt;input type="file"&gt; 字段

  9. 确保您没有嵌套像 &lt;form&gt;&lt;form&gt;&lt;/form&gt;&lt;/form&gt; 这样的表单

  10. 检查您的 HTML 结构中是否存在无效/重叠标签,例如 &lt;div&gt;&lt;form&gt;&lt;/div&gt;&lt;/form&gt;

  11. 还要确保您上传的文件中没有任何非字母数字字符。

  12. 有一次,我花了几个小时试图弄清楚为什么会突然发生这种情况。原来我修改了.htaccess中的一些PHP设置,其中一个(还不确定是哪个)导致上传失败,$_FILES为空。

  13. 您可以尝试在 &lt;input&gt; 标记的 name="" 属性中避免使用下划线 (_)

  14. 尝试上传非常小的文件以缩小是否是文件大小问题。

  15. 检查您的可用磁盘空间。虽然非常少见,但在这个PHP Manual page comment中提到:

    如果 $_FILES 数组突然变空,即使您的表单看起来正确,您也应该检查临时文件夹分区的可用磁盘空间。在我的安装中,所有文件上传都失败了,没有警告。咬牙切齿后,我尝试释放额外的空间,之后文件上传突然又开始工作了。

  16. 请确保您不是通过 AJAX POST 请求而不是导致页面重新加载的正常 POST 请求提交表单。我浏览了上面列表中的每一点,最后发现我的 $_FILES 变量为空的原因是我使用 AJAX POST 请求提交表单。我知道也有使用 ajax 上传文件的方法,但这可能是您的 $_FILES 数组为空的正当理由。

其中一些观点的来源:
https://web.archive.org/web/20050426084124/http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/

【讨论】:

  • 也许“接受”的答案解决了原始帖子,但这个答案是我发现最有帮助的一个。如有疑问,请查看浏览器看到的来源。检查此列表中的每个项目并向后追溯,我在一个最意想不到的地方发现了我的错误。如果您遇到类似的问题,请相信我,这可能不是 Apache 中的错误。 ;)
  • 还要确保包含文件输入的表单元素不是另一个表单元素的子元素。例如&lt;form&gt;&lt;form&gt;&lt;input type="file"&gt;&lt;/form&gt;&lt;/form&gt;
  • 哇!谢谢你的名单。我的问题是#2。我在提交处理程序中调用$('#my-form')[0].reset();
  • 谢谢。在我的情况下 7 。 enctype="multipart/form-data" 是罪魁祸首。
  • 伙计,你是救生员。我花了几个小时试图弄清楚(2)是我的问题......谢谢!
【解决方案2】:

就 HTML 而言,您似乎已正确设置了该部分。您已经拥有enctype="multipart/form-data",这对表单非常重要。

就您的php.ini 设置而言,有时系统上存在多个php.ini 文件。确保您编辑的是正确的。我知道您说您已将php.ini 文件配置为上传文件,但您是否也将upload_max_filesizepost_max_size 设置为大于您要上传的文件?所以你应该有:

file_uploads = On; sounds like you already did this
post_max_size = 8M; change this higher if needed
upload_max_filesize = 8M; change this higher if needed

您的目录:"c:\wamp\tmp" 是否具有读写权限?您是否记得在进行 php.ini 更改后重新启动 Apache?


【讨论】:

  • +1:用于重新启动 Apache 服务器提示。许多 Windows 用户忘记了这一点。
【解决方案3】:

在表单中添加enctype="multipart/form-data" 很重要,例如

<form action="upload.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

【讨论】:

    【解决方案4】:

    感谢大家的各种全面回复。这些都非常有帮助。答案竟然是非常奇怪的。事实证明,PHP 5.2.11 不喜欢以下内容:

    post_max_size = 2G
    

    post_max_size = 2048M
    

    如果我把它改成2047M,上传就可以了。

    【讨论】:

    • 请注意,如此高的值是空间不足/ddos 攻击的漏洞。只需添加此内容,以便人们在尝试复制和粘贴您的解决方案时意识到它太多了。无论如何,2 场演出需要的上传时间太长了。
    • 不再太大了。我们有客户经常上传 1-3G 范围内的文件。由于他们正在将文件上传到自己的服务器上,并且它们是 IP 白名单服务器,因此交换是非常正常的,并且只是一种允许客户端以他们想要的方式使用其设备的方式。他们支付账单,不涉及安全风险,没有问题。
    【解决方案5】:

    我看了 2 个小时也有同样的问题,很简单,我们先检查我们的服务器配置。

    示例:

    echo $upload_max_size = ini_get('upload_max_filesize');  
    echo $post_max_size=ini_get('post_max_size');   
    

    任何类型的文件大小都是:20mb,但我们的upload_max_size 高于20mb,但数组为null。答案是我们的post_max_size 应该大于upload_max_filesize

    post_max_size = 750M  
    upload_max_filesize = 750M
    

    【讨论】:

      【解决方案6】:

      确保您的输入元素具有“名称”属性。 &lt;input type="file" name="uploadedfile" /&gt;

      如果缺少,$_FILES 将为空。

      【讨论】:

        【解决方案7】:

        这是我发现的另一个原因: 当使用 JQuery Mobile 并且表单属性 data-ajax 设置为 true 时,FILES 数组将为空。所以将 data-ajax 设置为 false。

        【讨论】:

          【解决方案8】:

          没有人提到这一点,但它帮助了我,网上没有多少地方提到它。

          确保您的 php.ini 设置以下键:

              upload_tmp_dir="/path/to/some/tmp/folder"
          

          如果他们希望您使用绝对服务器文件路径,您需要与您的虚拟主机核实。您应该能够在 php.ini 文件中查看其他目录示例以确定这一点。我一设置它就在我的 _FILES 对象中获得了值。

          最后确保您的 tmp 文件夹和您要移动文件的位置具有正确的权限,以便可以读取和写入它们。

          【讨论】:

          • 这解决了我的问题。在我的情况下,临时目录位于 C 驱动器中,看起来 XAMPP 没有在 C 驱动器中写入的权限。我将临时目录更改为 D 驱动器中的某个文件夹并且有效。
          【解决方案9】:

          我一直在努力解决同样的问题并测试所有内容,但没有收到错误报告,而且似乎没有任何问题。 我有 error_reporting(E_ALL) 但突然间我意识到我没有检查 apache 日志,瞧! 脚本出现语法错误...! (缺少“}”)

          所以,即使这是明显需要检查的东西,也可能会被遗忘...... 就我而言(linux),它位于:

          /var/log/apache2/error.log
          

          【讨论】:

            【解决方案10】:

            如果您尝试上传文件数组,那么您可能需要在php.ini 中增加max_file_uploads,默认设置为20

            注意max_file_uploads 不能在 php.ini 之外更改。见PHP "Bug" #50684

            【讨论】:

              【解决方案11】:

              另一个可能的罪魁祸首是 apache 重定向。在我的情况下,我设置了 apache 的 httpd.conf 以将我们网站上的某些页面重定向到 http 版本,并将其他页面重定向到页面的 https 版本(如果它们还没有的话)。我有一个带有文件输入的表单的页面是配置为强制使用 ssl 的页面之一,但指定为表单操作的页面配置为 http。因此页面会将上传提交到操作页面的 ssl 版本,但 apache 将其重定向到页面的 http 版本,并且发布的数据,包括上传的文件都丢失了。

              【讨论】:

                【解决方案12】:

                如果您的主脚本是http://Some_long_URL/index.php,请注意在action 字段中指定完整的URL(带有明确的index.php不是 只有http://Some_long_URL)。令人惊讶的是,如果不是,则执行正确的脚本,但 $_FILES 为空!

                【讨论】:

                • 你知道怎么解决吗?
                【解决方案13】:

                检查您的 php.ini 是否有 enable_post_data_reading=On,因为:

                禁用此选项会导致不填充 $_POST 和 $_FILES。读取 postdata 的唯一方法是通过 php://input 流包装器。 (...)

                http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading

                【讨论】:

                  【解决方案14】:

                  如果您在共享主机环境中,请不要相信 sys_get_temp_dir 提供的临时文件夹位置。

                  这里还有一件事需要检查,但尚未提及......

                  我自然假设我的 PHP 脚本存储临时文件上传的文件夹是/tmpecho sys_get_temp_dir() . PHP_EOL; 返回/tmp 的事实强化了这种信念。此外,echo ini_get('upload_tmp_dir'); 什么也不返回。

                  为了验证上传的文件确实短暂地出现在我的/tmp 文件夹中,我在脚本中添加了一个sleep(30); 语句(如建议的here)并导航到我在cPanel 文件管理器中的/tmp 文件夹找到文件。但是无论如何,上传的文件在那里找不到。

                  我花了几个小时试图确定原因,并实施了这里提供的每一个建议。

                  最后,在我的网站文件中搜索tmp 查询后,我发现我的网站在不同目录中包含其他名为tmp 的文件夹。我意识到我的 PHP 脚本实际上正在将上传的文件写入.cagefs/tmp(必须在 cPanel 中启用 “显示隐藏文件” 设置才能查看此文件夹.)

                  那么,为什么sys_get_temp_dir 函数返回的信息不准确?

                  这是来自 PHP.net 网页的sys_get_temp_dir 的解释(即顶部评论):

                  如果在 systemd 具有 PrivateTmp=true 的 Linux 系统上运行(其中 是 CentOS 7 和其他较新发行版的默认设置),这个 函数将简单地返回“/tmp”,而不是真正的,更长的时间, 有点动态的路径。

                  这篇 SO 帖子也深入探讨了这个问题:

                  【讨论】:

                    【解决方案15】:

                    我遇到了同样的问题,发现问题的一部分是我的 IDE。我直接从 IDE (PHPStorm) 启动调试器,而不是直接使用浏览器。 IDE 生成的 URL 是这样的:

                    "...localhost:63342/CB_Upload/index.php?_ijt=j2hcbacqepj87bvg66ncuohvne"
                    

                    只是使用:

                    "...localhost/CB_Upload/index.php"
                    

                    工作得很好。我的设置是 PC / Windows 10 / WAMPSERVER 3.0.6 64bit

                    【讨论】:

                    • 同样的事情,到目前为止我已经在圈子里跑了一个小时!谢谢
                    【解决方案16】:

                    我遇到了同样的问题,主题都不是我的错误。签入您的 .htaccess 文件,如果有的话,如果启用了“MultiViews”。我不得不禁用它们。

                    【讨论】:

                      【解决方案17】:

                      我遇到了类似的问题,正如 shamittomar 所提到的,问题在 htaccess 中的值错误。

                      php_value post_max_size 10MB 更改为php_value post_max_size 10M

                      【讨论】:

                        【解决方案18】:

                        我是空的$_FILES 因为在&lt;form enctype="multipart/form-data" method="post"&gt; 之后我放置了

                        </div>
                        <div style="clear:both"></div>
                        

                        最初的代码是这样的

                        <span class="span_left">Photos (gif/jpg/jpeg/png) </span>
                        <form enctype="multipart/form-data" method="post">
                        <input name="files[]" type="file" id="upload_file" />
                        <input type="button" id="upload" value="Upload photo" />
                        </form>
                        

                        我决定修改和

                        <div>
                        <span class="span_left">Photos (gif/jpg/jpeg/png) </span>
                        <form enctype="multipart/form-data" method="post">
                        </div>
                        <div style="clear:both"></div>
                        <input name="files[]" type="file" id="upload_file" />
                        <input type="button" id="upload" value="Upload photo" />
                        </form>
                        <div style="clear:both"></div>
                        

                        所以结论是&lt;form enctype="multipart/form-data" method="post"&gt;后面一定是&lt;input name, type, id,不能是&lt;div&gt;或者其他一些标签

                        在我的情况下,正确的代码是

                        <div>
                        <span class="span_left">Photos (gif/jpg/jpeg/png) </span>
                        </div>
                        <div style="clear:both"></div>
                        <form enctype="multipart/form-data" method="post">
                        <input name="files[]" type="file" id="upload_file" />
                        <input type="button" id="upload" value="Upload photo" />
                        </form>
                        <div style="clear:both"></div>
                        

                        【讨论】:

                          【解决方案19】:

                          我也遇到了 $_FILES 为空的问题。上面的清单没有提到 .htaccess、httpd.conf 或 httpd-vhost.conf 中的 MultiViews。

                          如果您在包含网站的目录的选项指令中设置了 MultiViews,则 $_FILES 将为空,即使 Content-Length 标头显示我上传的文件也是如此。

                          【讨论】:

                            【解决方案20】:

                            如果您使用的是 JQuery Mobile

                            Ajax 不支持将多部分表单与文件输入一起使用。在这种情况下,您应该使用 data-ajax="false" 装饰父表单,以确保表单正确提交到服务器。

                            <form action="upload.php" method="post" enctype="multipart/form-data"  data-ajax="false">
                                Select image to upload:
                                <input type="file" name="fileToUpload" id="fileToUpload">
                                <input type="submit" value="Upload Image" name="submit">
                            </form>
                            

                            【讨论】:

                              【解决方案21】:

                              将表单从您正在使用的页面中分离出来 进入一个简单的 php 页面,该页面具有以下形式和 只有php代码,然后像这样测试它。

                              任何引导程序或 java 脚本都可能清除 文件[]。那是我的情况

                              【讨论】:

                                【解决方案22】:

                                如果您使用 AJAX 而不是表单提交,请确保将请求标头 Content-Type 设置为 multipart/form-data; boundary=myAwesomeBoundary',其中 myAwesomeBoundary 是分隔请求正文部分的唯一字符串。我错误地将Content-Type 标头设置为仅multipart/form-data 而不设置boundary。解决方法是不覆盖标题,而是让浏览器为我生成它。

                                【讨论】:

                                  猜你喜欢
                                  • 2016-10-15
                                  • 2015-08-22
                                  • 2013-03-21
                                  • 1970-01-01
                                  • 2021-04-30
                                  • 2015-02-04
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多