我的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";
?>
答案 0 :(得分:429)
以下是PHP中文件上传的检查表:
检查php.ini:
file_uploads = On
post_max_size = 100M
upload_max_filesize = 100M
.htaccess
,则可能需要使用.user.ini
或php.ini
。phpinfo()
功能验证您的身份
实际上正在应用设置。 100M
而不是 100MB
。确保您的<form>
代码具有enctype="multipart/form-data"
属性。没有其他标签可以使用,它必须是您的FORM标签。仔细检查拼写正确。仔细检查多部分/表单数据是否被STRAIGHT QUOTES包围,而不是从Word或网站博客中粘贴的智能引号(WordPress将直引号转换为角度报价!)。如果页面上有多个表单,请确保它们都具有此属性。手动输入,或尝试手动输入直接单引号。
确保没有两个具有相同name
属性的输入文件字段。如果您需要支持多个,请在名称的末尾加上方括号:
<input type="file" name="files[]">
<input type="file" name="files[]">
确保您的tmp和upload目录具有正确的读取和写入权限集。临时上载文件夹在PHP设置中指定为upload_tmp_dir
。
确保您的文件目标和tmp / upload目录没有 其中有空格。
确保您网页上的所有<form>
都有</form>
个关闭代码。
确保您的FORM标记为method="POST"
。 GET请求不支持多部分/表单数据上传。
确保您的文件输入标记具有NAME属性。 ID属性是不够的! ID属性用于DOM,而不用于POST有效负载。
确保您在提交时未使用Javascript停用<input type="file">
字段
确保您没有嵌套<form><form></form></form>
检查HTML结构中是否存在<div><form></div></form>
还要确保您上传的文件中没有任何非字母数字字符。
有一次,我花了好几个小时试图弄清楚为什么会突然发生这种情况。事实证明我修改了.htaccess
中的一些PHP设置,其中一个(不确定哪个)导致上传失败并且$_FILES
为空。
您可以尝试在_
代码
name=""
属性中避免使用下划线(<input>
)
尝试上传非常小的文件,以缩小是否存在文件大小问题。
检查可用磁盘空间。虽然非常罕见,但在PHP Manual page comment中提到了
如果$ _FILES数组突然出现空洞,即使表单看起来正确,也应该检查临时文件夹分区的可用磁盘空间。在我的安装中,所有文件上传都失败而没有警告。在咬牙切齿之后,我尝试释放额外的空间,之后文件上传突然再次起作用。
请确保您没有通过AJAX POST请求而不是正常的POST请求提交表单,导致页面重新加载。我浏览了上面列表中的每一点,最后发现我的$ _FILES变量为空的原因是我使用AJAX POST请求提交表单。我知道有一些方法可以使用ajax上传文件,但这可能是你的$ _FILES数组为空的正当理由。
其中一些要点的来源:
http://getluky.net/2004/10/04/apachephp-_files-array-mysteriously-empty/
答案 1 :(得分:72)
对于您似乎已正确设置该部分的HTML。您已经拥有enctype="multipart/form-data"
,这对于表单非常重要。
就php.ini
设置而言,有时在系统上存在多个php.ini
文件。确保您正在编辑正确的。我知道您说您已将php.ini
文件配置为上传文件,但您是否还将upload_max_filesize
和post_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?
答案 2 :(得分:30)
将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>
答案 3 :(得分:14)
感谢大家提供各种全面的回复。这些都非常有帮助。答案结果证明是非常奇怪的。事实证明PHP 5.2.11不喜欢以下内容:
post_max_size = 2G
或
post_max_size = 2048M
如果我将其更改为2047M
,则上传有效。
答案 4 :(得分:6)
我找到了另一个原因: 使用JQuery Mobile并将表单属性data-ajax设置为true时,FILES数组将为空。所以将data-ajax设置为false。
答案 5 :(得分: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 :(得分:3)
确保您的输入元素具有&#39;名称&#39;属性。
<input type="file" name="uploadedfile" />
如果缺少,$ _FILES将为空。
答案 7 :(得分:3)
我正在努力解决同样的问题并测试所有内容,没有得到错误报告,似乎没有任何错误。 我有error_reporting(E_ALL) 但突然间我意识到我没有检查过apache日志并且vo! 脚本上有语法错误......! (缺少“}”)
所以,即使这是值得检查的事情,也可能会被遗忘...... 在我的情况下(linux)它位于:
/var/log/apache2/error.log
答案 8 :(得分:2)
没有人提到这一点,但它帮助了我,网上没有多少地方提到它。
确保您的php.ini设置以下密钥:
upload_tmp_dir="/path/to/some/tmp/folder"
如果您希望使用绝对服务器文件路径,则需要检查您的webhost。您应该能够在php.ini文件中看到其他目录示例来确定这一点。一旦我设置它,我在_FILES对象中得到了值。
最后确保您的tmp文件夹以及移动文件的位置具有正确的权限,以便可以读取和写入。
答案 9 :(得分:2)
检查你的php.ini上的 enable_post_data_reading = On ,因为:
禁用此选项会导致$ _POST和$ _FILES无法填充。读取postdata的唯一方法是通过php://输入流包装器。 (...)
在http://php.net/manual/en/ini.core.php#ini.enable-post-data-reading
中答案 10 :(得分:2)
另一个可能的罪魁祸首是apache重定向。在我的情况下,我设置了apache的httpd.conf,将我们网站上的某些页面重定向到http版本,将其他页面重定向到页面的https版本,如果它们还没有。我有一个带有文件输入的表单的页面是配置为强制ssl的页面之一,但指定为表单操作的页面配置为http。因此页面会将上传内容提交到操作页面的ssl版本,但是apache会将其重定向到页面的http版本,而后期数据也会丢失。
答案 11 :(得分:2)
如果您尝试上传文件数组,则可能需要在php.ini
中增加max_file_uploads
,默认设置为20
注意:max_file_uploads
无法在php.ini之外进行更改。见PHP "Bug" #50684
答案 12 :(得分: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 64位
答案 13 :(得分: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>
答案 14 :(得分:0)
我有类似的问题,而且这个问题在shattomar中提到的htaccess中的错误值。
将php_value post_max_size 10MB
更改为php_value post_max_size 10M
答案 15 :(得分:0)
如果您的主要脚本为http://Some_long_URL/index.php
,请务必在{{1}中指定完整网址(明确index.php
且不 <{1}}) }字段。令人惊讶的是,如果没有,则执行正确的脚本,但使用空的$ _FILES!
答案 16 :(得分:0)
我也遇到了$ _FILES空的问题。上面的检查表没有提到.htaccess,httpd.conf或httpd-vhost.conf中的MultiViews。
如果您在包含该网站的目录的options指令中设置了MultiViews,则$ _FILES将为空,即使Content-Length标头显示我上传的文件。
答案 17 :(得分: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>
答案 18 :(得分:0)
我遇到了同样的问题,没有一个主题是我的错误。检查.htaccess文件,如果有的话,如果启用了“MultiViews”。我不得不禁用它们。
答案 19 :(得分:0)
sys_get_temp_dir
提供的临时文件夹位置。还有一件事需要检查,但尚未提及...
我自然地以为,我的PHP脚本存储临时文件上载的文件夹为/tmp
。 echo sys_get_temp_dir() . PHP_EOL;
返回/tmp
的事实进一步强化了这一信念。另外,echo ini_get('upload_tmp_dir');
不返回任何内容。
为验证上传的文件确实确实短暂出现在我的/tmp
文件夹中,我在脚本中添加了sleep(30);
语句(如建议的here)并导航到我的{{ 1}}文件夹中的cPanel文件管理器中找到该文件。但是,无论如何,都无法在此找到上传的文件。
我花费了数小时试图确定原因,并实施了此处提供的所有建议。
最后,在我的网站文件中搜索查询/tmp
之后,我发现我的网站在不同目录中还包含名为tmp
的其他文件夹。我意识到我的PHP脚本实际上是在将上传的文件写入tmp
。(必须在cPanel中启用“显示隐藏的文件” 设置才能查看此文件夹。)
那么,为什么.cagefs/tmp
函数返回的信息不正确?
这是PHP.net网页上sys_get_temp_dir
的说明(即最上面的注释):
如果在Linux系统上运行,其中systemd具有PrivateTmp = true( 是CentOS 7和其他较新发行版的默认设置), 函数将只返回“ / tmp”,而不是true,时间更长, 有点动态的路径。
此SO帖子也探讨了这个问题:
答案 20 :(得分:0)
从您正在使用的页面上分离表格 进入一个具有以下形式的简单php页面: 仅php代码,并像这样进行测试。
任何引导程序或Java脚本都可能清除 文件[]。那是我的情况
答案 21 :(得分:0)
如果您使用 AJAX 而不是表单提交,请确保将请求标头 Content-Type
设置为 multipart/form-data; boundary=myAwesomeBoundary'
,其中 myAwesomeBoundary
是分隔请求正文部分的唯一字符串。我错误地将 Content-Type
标头设置为仅 multipart/form-data
而未设置 boundary
。解决方法是不覆盖标头,而是让浏览器为我生成它。