为什么将文件上传到 PHP 时 $_FILES 为空?

Why would $_FILES be empty when uploading files to PHP?

提问人:elmonty 提问时间:8/28/2010 最后编辑:Nikola K.elmonty 更新时间:1/20/2022 访问量:246130

问:

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

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";
?>
php apache 文件上传

评论

2赞 Byron Whitlock 8/28/2010
您是否检查了错误日志?
0赞 Luca Matteis 8/28/2010
我敢肯定你忽略了一些愚蠢的东西。例如,你确定有代码吗?vanilla-upload.php
0赞 BrightIntelDusk 3/4/2014
哈,我也有同样的问题。我检查了错误日志,它说正在上传的文件超过了允许的最大大小。
1赞 Fanky 9/2/2021
呵呵,我没有:D<input>name=
0赞 Andr 7/6/2023
我尝试上传的文件不是从root,而是使用位于“子文件夹”中的脚本,如下所示:www.something.com\somthing_\something.php。_FILE 美元是空的!我尝试了 www.something.com 的相同代码 - 它奏效了......不知道如何解决这个问题..我做了解决方法。

答:

82赞 Brian 8/28/2010 #1

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

就您的设置而言,有时在系统上存在多个文件。确保您正在编辑正确的。我知道您说您已将文件配置为文件上传,但您是否也设置了 和 大于您尝试上传的文件?所以你应该有:php.iniphp.iniphp.iniupload_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

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


评论

4赞 shamittomar 8/28/2010
+1:用于重新启动 Apache 服务器提示。许多 Windows 用户忘记了这一点。
580赞 shamittomar 8/28/2010 #2

以下是在 PHP 中上传文件的清单:

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

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

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

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

  5. 确保页面上的所有内容都有关闭标签。<form></form>

  6. 确保您的 FORM 标签具有 .GET 请求不支持 multipart/form-data 上传。method="POST"

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

  8. 确保您没有使用 Javascript 在提交时禁用您的字段<input type="file">

  9. 确保你没有嵌套像这样的表单<form><form></form></form>

  10. 检查您的 HTML 结构是否存在无效/重叠的标签,例如<div><form></div></form>

  11. 此外,请确保您上传的文件中没有任何非字母数字字符。

  12. 有一次,我花了几个小时试图弄清楚为什么这突然发生在我身上。事实证明,我已经修改了 中的一些PHP设置,其中一个(还不确定是哪个)导致上传失败并且为空。.htaccess$_FILES

  13. 您可以尝试避免在代码属性中使用下划线 ()_name=""<input>

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

  15. 检查您的可用磁盘空间。虽然非常罕见,但在这个PHP手册页面的评论中提到了它:

    如果 $_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/

评论

1赞 The Pixel Developer 8/29/2010
这不适用于讨论启动器,但我的托管服务提供商的防火墙策略过于严格,导致一些上传失败。
20赞 quickthyme 1/25/2012
也许“接受”的答案解决了原来的帖子,但这个答案是我发现最有帮助的答案。如有疑问,请查看浏览器看到的来源。检查此列表中的每个项目并向后追溯,我发现我的错误在一个最意想不到的地方。如果你正在为类似的问题而苦苦挣扎,相信我,这可能不是Apache中的错误。;)
4赞 sudee 8/14/2013
此外,请确保包含文件输入的表单元素不是另一个表单元素的子元素。例如:<form><form><input type="file"></form></form>
3赞 Gavin 10/26/2013
哇!谢谢你提供这份清单。我的问题是#2。我正在调用提交处理程序。$('#my-form')[0].reset();
5赞 Thupten 8/21/2014
谢谢。在我的案例中,数字 7 .enctype=“multipart/form-data” 是罪魁祸首。
17赞 elmonty 8/29/2010 #3

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

post_max_size = 2G

post_max_size = 2048M

如果我将其更改为 ,则上传有效。2047M

评论

18赞 Manuel Arwed Schmidt 6/25/2014
请注意,如此高的值容易受到空间外/ddos 攻击。只需添加此内容,以便人们在尝试复制和粘贴您的解决方案时意识到它太多了。无论如何,2 场演出需要的上传时间太长了。
2赞 TheSatinKnight 7/23/2017
不再太大了。我们的客户经常上传 1-3G 范围内的文件。由于他们正在将文件上传到自己的服务器上,并且它们是 IP 白名单服务器,因此交换是很正常的,只是允许客户以他们想要的方式使用他们的设备的一种方式。他们支付账单,不涉及安全风险,没有问题。
0赞 Murolack 5/17/2013 #4

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

2赞 Tahir Yasin 8/15/2013 #5

如果您尝试上传文件数组,则可能需要max_file_uploads增加默认设置为php.ini20

注意:不能在 php.ini 之外更改。参见 PHP “Bug” #50684max_file_uploads

2赞 user2723315 8/28/2013 #6

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

2赞 Gibbie 3/13/2014 #7

如果您的主脚本是,请小心在字段中指定完整的 URL(具有显式且不仅如此)。令人惊讶的是,如果没有,将执行正确的脚本,但 en 空 $_FILES !http://Some_long_URL/index.phpindex.phphttp://Some_long_URLaction

评论

0赞 ucMedia 1/18/2021
你知道怎么解决吗?
0赞 Johnny Vietnam 9/16/2014 #8

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

更改为php_value post_max_size 10MBphp_value post_max_size 10M

6赞 checkmate711 10/15/2014 #9

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

10赞 shashik493 2/11/2015 #10

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

例:

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

任何类型的文件大小都是 ,但我们在上面,但数组是 。答案是我们的应该大于:20mbupload_max_size20mbnullpost_max_sizeupload_max_filesize

post_max_size = 750M  
upload_max_filesize = 750M
0赞 Andris 3/22/2015 #11

我是空的,因为在我放置之后$_FILES<form enctype="multipart/form-data" method="post">

</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>

所以结论是,在必须和不能之后,或者其他一些标签<form enctype="multipart/form-data" method="post"><input name, type, id<div>

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

<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>
6赞 AaronP 4/9/2015 #12

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

确保您的 php.ini 设置了以下密钥:

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

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

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

评论

0赞 Adil Malik 6/2/2021
这解决了我的问题。就我而言,临时目录位于 C 盘中,看起来 XAMPP 没有权限在 C 盘中写入。我将临时目录更改为 D 驱动器中的某个文件夹,并且有效。
5赞 Luis Rosety 6/18/2015 #13

我一直在为同样的问题而苦苦挣扎并测试所有内容,没有得到错误报告,似乎没有任何问题。 我有error_reporting(E_ALL) 但是突然间我意识到我没有检查apache日志,瞧! 脚本上有语法错误......!(缺少“}”)

因此,即使这显然是需要检查的事情,也可以忘记...... 就我而言(linux),它位于:

/var/log/apache2/error.log
0赞 gerteb 8/31/2015 #14

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

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

8赞 Adrian Parr 12/18/2015 #15

确保您的输入元素具有“name”属性。<input type="file" name="uploadedfile" />

如果缺少此值,则 _FILES 美元将为空。

44赞 meda 3/28/2016 #16

添加到您的表单中很重要,例如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>
1赞 Marc M. 1/27/2017 #17

我遇到了同样的问题,发现是我的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 64 位

评论

0赞 EKanadily 2/20/2017
同样的事情,到目前为止,我已经绕圈跑了一个小时!谢谢
0赞 Rajan 5/23/2017 #18

如果您使用的是 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>
3赞 jmng 7/18/2017 #19

检查你的 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

2赞 Crickets 5/29/2019 #20

如果您处于共享托管环境中,请不要信任 提供的临时文件夹位置。sys_get_temp_dir

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

我自然而然地假设我的PHP脚本存储临时文件上传的文件夹是 .这种信念因回归这一事实而得到加强。此外,不返回任何内容。/tmpecho sys_get_temp_dir() . PHP_EOL;/tmpecho ini_get('upload_tmp_dir');

为了验证上传的文件是否确实短暂地出现在我的文件夹中,我在我的脚本中添加了一个语句(如此建议),并在cPanel文件管理器中导航到我的文件夹以找到该文件。但是,无论如何,上传的文件都无处可寻。/tmpsleep(30);/tmp

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

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

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

以下是sys_get_temp_dir PHP.net 网页的解释(即顶部评论):

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

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

0赞 user2195463 7/24/2020 #21

从您正在使用的页面分离表单 到一个简单的 php 页面中,该页面具有 仅PHP代码,并像这样进行测试。

任何引导程序或 java 脚本都可能被清除 _FILES[]。这就是我的情况

0赞 Jacob 8/5/2021 #22

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