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


145

我在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";
?>

2
您检查错误日志了吗?
拜伦·惠特洛克

我敢肯定您忽略了一些愚蠢的事情。例如,您确定要包含代码vanilla-upload.php吗?
卡·马蒂斯

哈,我有同样的问题。我检查了错误日志,并说正在上传的文件超过了允许的最大大小。
BrightIntelDusk 2014年

Answers:


493

以下是使用PHP上传文件的清单:

  1. 检查php.ini:
    file_uploads = On
    post_max_size = 100M
    upload_max_filesize = 100M

    • 您可能需要使用,.htaccess或者.user.ini如果您在共享主机上并且没有访问权限php.ini
    • 确保您正在编辑正确的ini文件-使用该phpinfo()功能来验证您的设置是否已被实际应用。
    • 另外,请确保您不会拼写错误的大小-应该100M 不会 100MB
  2. 确保您的<form>标签具有enctype="multipart/form-data"属性。没有其他标签可以使用,它必须是您的FORM标签。仔细检查拼写是否正确。仔细检查multipart / form-data是否被STRAIGHT QUOTES包围,而不是从Word或网站博客中粘贴的智能引号(WordPress将直引号转换为尖引号!)。如果页面上有多个表单,请确保它们都具有此属性。手动输入,或尝试手动输入单引号。

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

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

  5. 确保文件目标目录和tmp / upload目录中没有空格。

  6. 确保<form>页面上的所有具有</form>关闭标签。

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

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

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

  10. 确保您没有嵌套表格 <form><form></form></form>

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

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

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

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

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

  16. 检查您的可用磁盘空间。尽管非常罕见,但在此PHP手册页注释中提到了它:

    如果$ _FILES数组突然神秘地变空,即使您的表格看起来正确,也应检查可用于临时文件夹分区的磁盘空间。在我的安装中,所有文件上传均失败,没有警告。咬牙切齿之后,我尝试释放更多空间,之后文件上传突然又恢复了。

  17. 确保您不是通过AJAX POST请求提交表单,而不是通过导致页面重新加载的普通POST请求提交表单。我遍历了上面列表中的每个点,最终发现我的$ _FILES变量为空的原因是我使用AJAX POST请求提交了表单。我知道也有使用ajax上传文件的方法,但这可能是$ _FILES数组为空的有效原因。

这些观点的来源:http :
//getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/


12
也许“已接受”的答案解决了原始帖子,但这是我发现最有帮助的答案。如有疑问,请查看浏览器看到的源。检查此列表中的每个项目并向后追溯,我在最意外的地方发现了我的错误。如果您正在努力解决类似的问题,请相信我,这可能不是Apache中的错误。;)
quickthyme 2012年

3
还要确保包含文件输入的表单元素不是另一个表单元素的子元素。例如<form><form><input type="file"></form></form>
sudee

3
哇!谢谢你的这份清单。我的问题是#2。我正在调用$('#my-form')[0].reset();提交处理程序。
加文

2
谢谢。在我的情况下是7。罪魁祸首是enctype =“ multipart / form-data”。
2014年

3
杜德,你是救命稻草。我花了几个小时试图弄清楚这个问题(2)是我的问题...谢谢!
Mike Q

74

至于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 吗?



4
+1:用于重新启动Apache服务器提示。许多Windows用户忘记了这一点。
shamittomar

36

重要的是要添加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>

14

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

post_max_size = 2G

要么

post_max_size = 2048M

如果我将其更改为2047M,则上传成功。


17
请注意,如此高的价值是对空间/ ddos​​攻击的脆弱性。只需添加此内容,以便人们在尝试复制并粘贴您的解决方案时就太多了。无论如何,2个演出将需要太长的上传时间。
Manuel Arwed Schmidt 2014年

不再太大。我们的客户定期上传1-3G范围内的文件。由于他们将文件上传到自己的服务器上,并且它们是IP列入白名单的服务器,因此交换是非常正常的,并且仅仅是允许客户端以他们想要的方式使用其设备的一种方式。他们支付账单,不涉及安全风险,没有问题。
TheSatinKnight

8

我在看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

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



4

我在同一个问题上苦苦挣扎,并测试了所有内容,没有收到错误报告,而且似乎没有什么错。我有error_reporting(E_ALL)但突然间我意识到我没有检查apache日志和voilà!脚本上存在语法错误...!(缺少“}”)

因此,即使这是显而易见的要检查的东西,也可以将其忘记...就我而言(Linux),它位于:

/var/log/apache2/error.log

3

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

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

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

如果他们希望您使用绝对服务器文件路径,则需要与您的虚拟主机联系。您应该能够在php.ini文件中查看其他目录示例来确定这一点。设置好后,我的_FILES对象中便有了值。

最后,请确保您的tmp文件夹以及将文件移动到的位置都具有正确的权限,以便可以对其进行读写。



2

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



1

如果你的主要脚本是http://Some_long_URL/index.php要小心指定完整的URL(具有明确index.php不是http://Some_long_URL)的action领域。令人惊讶的是,如果没有执行,将执行正确的脚本,但是带有空的$ _FILES!


1

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


同样的事情,到目前为止,我在圈子里跑了一个小时!谢谢
EKanadily '17

1

不信任由以下人员提供的临时文件夹位置 sys_get_temp_dir如果您在共享主机环境中,请。

这是尚未提及的另一件事要检查...

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

要验证上传的文件事实上确实短暂地出现在我的/tmp文件夹中,我添加了一个sleep(30);声明,我的脚本(如建议在这里),并导航到我的/tmp在的cPanel文件管理器文件夹中找到该文件。但是,无论如何,都无法在该处找到上载的文件。

我花了几个小时来尝试确定原因,并实施了此处提供的所有建议。

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

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

这是来自PHP.net网页的解释sys_get_temp_dir(即,最上面的注释):

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

该SO帖子也探讨了这个问题:


0

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


0

我有类似的问题,正如shamittomar所述,该问题在htaccess中的价值不正确。

更改php_value post_max_size 10MBphp_value post_max_size 10M


0

我是空的,$_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>

0

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

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


0

如果您使用的是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>

0

将您正在使用的页面从表单中分离出来,放到一个仅包含表单和php代码的简单php页面中,然后进行测试。

任何引导程序或Java脚本都可以清除_FILES []。那是我的情况

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.