错误消息解释

PHP 返回一个适当的错误代码以及文件数组。错误代码可以在由 PHP 在文件上传期间创建的文件数组的 error 部分找到。换句话说,错误可能在 $_FILES['userfile']['error'] 中找到。

UPLOAD_ERR_OK

值:0;没有错误,文件成功上传。

UPLOAD_ERR_INI_SIZE

值:1;上传的文件超过了 php.ini 中的 upload_max_filesize 指令。

UPLOAD_ERR_FORM_SIZE

值:2;上传的文件超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令。

UPLOAD_ERR_PARTIAL

值:3;上传的文件仅部分上传。

UPLOAD_ERR_NO_FILE

值:4;没有上传文件。

UPLOAD_ERR_NO_TMP_DIR

值:6;缺少临时文件夹。

UPLOAD_ERR_CANT_WRITE

值:7;无法将文件写入磁盘。

UPLOAD_ERR_EXTENSION

值:8;PHP 扩展停止了文件上传。PHP 没有提供确定哪个扩展导致文件上传停止的方法;使用 phpinfo() 检查已加载扩展列表可能会有所帮助。

添加笔记

用户贡献笔记 23 笔记

Viktor
9 年前
更新亚当的旧评论。

这对某些人可能有用。

<?php

$phpFileUploadErrors
= array(
0 => 'There is no error, the file uploaded with success',
1 => 'The uploaded file exceeds the upload_max_filesize directive in php.ini',
2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
3 => 'The uploaded file was only partially uploaded',
4 => 'No file was uploaded',
6 => 'Missing a temporary folder',
7 => 'Failed to write file to disk.',
8 => 'A PHP extension stopped the file upload.',
);
匿名
15 年前
[由 danbrown AT php DOT net 编辑:此代码是最初由 (Thalent, Michiel Thalen) 于 2009 年 3 月 4 日提交的笔记的修正版本。]


这是处理上传错误时有用的异常。

<?php

class UploadException extends Exception
{
public function
__construct($code) {
$message = $this->codeToMessage($code);
parent::__construct($message, $code);
}

private function
codeToMessage($code)
{
switch (
$code) {
case
UPLOAD_ERR_INI_SIZE:
$message = "The uploaded file exceeds the upload_max_filesize directive in php.ini";
break;
case
UPLOAD_ERR_FORM_SIZE:
$message = "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form";
break;
case
UPLOAD_ERR_PARTIAL:
$message = "The uploaded file was only partially uploaded";
break;
case
UPLOAD_ERR_NO_FILE:
$message = "No file was uploaded";
break;
case
UPLOAD_ERR_NO_TMP_DIR:
$message = "Missing a temporary folder";
break;
case
UPLOAD_ERR_CANT_WRITE:
$message = "Failed to write file to disk";
break;
case
UPLOAD_ERR_EXTENSION:
$message = "File upload stopped by extension";
break;

default:
$message = "Unknown upload error";
break;
}
return
$message;
}
}

// 使用
if ($_FILES['file']['error'] === UPLOAD_ERR_OK) {
// 上传成功完成
} else {
throw new
UploadException($_FILES['file']['error']);
}
?>
adam at gotlinux dot us
19 年前
这对某些人可能有用。

<?php
array(
0=>"There is no error, the file uploaded with success",
1=>"The uploaded file exceeds the upload_max_filesize directive in php.ini",
2=>"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form"
3=>"The uploaded file was only partially uploaded",
4=>"No file was uploaded",
6=>"Missing a temporary folder"
);
?>
stephen at poppymedia dot co dot uk
18 年前
如果 post 大于 php.ini 中设置的 post_max_size

$_FILES 和 $_POST 将返回为空
Sohaib Essam
1 年前
switch ($_FILES["image"]["error"]) {
case UPLOAD_ERR_PARTIAL
exit('File only partially uploaded');
break;
case UPLOAD_ERR_NO_FILE
exit('No file was uploaded');
break;
case UPLOAD_ERR_EXTENSION
exit('File upload stopped by a PHP extension');
break;
case UPLOAD_ERR_FORM_SIZE
exit('File exceeds MAX_FILE_SIZE in the HTML form');
break;
case UPLOAD_ERR_INI_SIZE
exit('File exceeds upload_max_filesize in php.ini');
break;
case UPLOAD_ERR_NO_TMP_DIR
exit('Temporary folder not found');
break;
case UPLOAD_ERR_CANT_WRITE
exit('Failed to write file');
break;
default
exit('Unknown upload error');
break;
}
svenr at selfhtml dot org
17 年前
关于 MAX_FILE_SIZE 隐藏表单字段和 UPLOAD_ERR_FORM_SIZE 错误代码的澄清

PHP 具有检查多个“最大文件大小”的奇怪功能。

两个众所周知的限制是 php.ini 设置“post_max_size”和“upload_max_size”,它们组合起来对可以接收的最大数据量施加硬性限制。

除了 PHP 中的这种实现方式外,还存在一种“软限制”功能。它检查是否存在名为“max_file_size”(大小写敏感)的表单字段,该字段应包含一个表示允许的最大字节数的整数。如果上传的文件大小超过了该字段中的整数,PHP 将禁止上传并返回 $_FILES 数组中的错误代码。

PHP 文档中也对“允许浏览器在上传前检查文件大小”做出了(或曾经做过 - 见 bug #40387 - http://bugs.php.net/bug.php?id=40387)含糊不清的描述。然而,这并不属实,而且从未实现过。截止到今天,还没有任何 RFC 建议使用这种命名表单字段,也没有任何浏览器真正检查过它的存在或内容,或者阻止任何操作。PHP 文档暗示浏览器可能会提醒用户其上传的文件过大 - 这是完全错误的。

请注意,使用 PHP 的这种功能不是一个好主意。表单字段很容易被客户端修改。如果您需要检查文件的大小,请在您的脚本中使用传统的方法进行检查,使用脚本定义的整数,而不是从 HTTP 客户端获取的任意数字(从安全角度来看,始终要对客户端数据保持怀疑态度)。
roland at REMOVE_ME dot mxchange dot org
6 年前
我扩展了 @adam at gotlinux dot us 的示例,添加了适当的 UPLOAD_FOO 常量和 gettext 支持。还添加了 UPLOAD_ERR_EXTENSION(在他的版本中丢失)。希望这对某些人有所帮助。

<?php
class Some {
/**
* 上传错误代码
* @var array
*/
private static $upload_errors = [];

public function
__construct() {
// 初始化上传错误
self::$upload_errors = [
UPLOAD_ERR_OK => _('文件上传成功,没有错误。'),
UPLOAD_ERR_INI_SIZE => _('上传的文件大小超过了 php.ini 中的 upload_max_filesize 指令。'),
UPLOAD_ERR_FORM_SIZE => _('上传的文件大小超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令。'),
UPLOAD_ERR_PARTIAL => _('上传的文件只上传了一部分。'),
UPLOAD_ERR_NO_FILE => _('没有上传任何文件。'),
UPLOAD_ERR_NO_TMP_DIR => _('缺少临时文件夹。'),
UPLOAD_ERR_CANT_WRITE => _('无法写入目标目录。请修正 CHMOD。'),
UPLOAD_ERR_EXTENSION => _('PHP 扩展程序阻止了文件上传。'),
];
}
}
?>
jille at quis dot cx
15 年前
当在文件数据之后找不到 MIME 边界时,就会返回 UPLOAD_ERR_PARTIAL 错误。这可能是由于用户取消了上传(按下了 ESC 键等)。
jalcort at att dot net
4 年前
在上传文件时,通常需要访问 php.ini 并设置 upload_tmp_dir = /temp,但在某些主机(如 fatcow)的情况下,您需要不仅指定 /tmp,还需要指定 upload_tmp_dir = /hermes/walnaweb13a/b345/moo.youruser/tmp。

如果没有设置,$_FILES 将显示错误 #6“缺少临时文件夹”。
Jeff Miner mrjminer AT gmail DOT com
14 年前
一件令人烦恼的事情是,处理这些常量值的方式要求使用等式来处理没有错误的情况,这会浪费一些空间。尽管“没有错误”的值为 0,在 if 语句中通常会评估为“false”,但在这种情况下,它总是会评估为 true。

因此,与其使用:
-----
<?php
if($_FILES['userfile']['error']) {
// 处理错误
} else {
// 处理
}
?>
-----
您应该使用:
-----
<?php
if($_FILES['userfile']['error']==0) {
// 处理
} else {
// 处理错误
}
?>
-----
此外,ctype_digit 函数会失败,但 is_int 函数会正常工作。如果您感到困惑... 不,这没有任何意义。

致 Schoschie

您问了一个问题:为什么在可以使事情变得简单的情况下,还要使其复杂化?我也有同样的疑问,因为您/匿名/Thalent(根据 danbrown)发布的代码版本是多余的开销,会导致函数调用,以及可能很长的 switch 语句。在循环中,这将是致命的... 请尝试以下方法:

-----
<?php
$error_types
= array(
1=>'上传的文件大小超过了 php.ini 中的 upload_max_filesize 指令。',
'上传的文件大小超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令。',
'上传的文件只上传了一部分。',
'没有上传任何文件。',
6=>'缺少临时文件夹。',
'无法将文件写入磁盘。',
'PHP 扩展程序阻止了文件上传。'
);

// 在循环之外...
if($_FILES['userfile']['error']==0) {
// 处理
} else {
$error_message = $error_types[$_FILES['userfile']['error']];
// 对错误信息进行任何操作
}

// 在循环中...
for($x=0,$y=count($_FILES['userfile']['error']);$x<$y;++$x) {
if(
$_FILES['userfile']['error'][$x]==0) {
// 处理
} else {
$error_message = $error_types[$_FILES['userfile']['error'][$x]];
// 对错误信息进行任何操作
}
}

// 完成后... 如果您没有在即将结束/完成所有处理过程的函数中进行所有这些操作,并且想要回收内存
unset($error_types);
?>
sysadmin at cs dot fit dot edu
19 年前
我注意到,在 PHP-4.3.2 中,如果上传的文件大小超过了 php.ini 中的 upload-max-filesize 限制,$_FILES 可能会无法设置,而不是设置错误 $_FILES["file"]["error"]。
tyler at fishmas dot org
19 年前
关于发送无效的文件名,一个非常简单的方法是检查文件大小和文件名。例如,要检查文件大小,只需使用文件信息数组中的 size 属性。

<?php
if($_FILES["file_id"]["size"] == 0)
{
// ...处理错误
}
?>
Tom
14 年前
注意:您可能感到意外的是,即使输入元素完全没有值,PHP 也会在 $_FILES 数组中提供一个值,并指示一个错误 UPLOAD_ERR_NO_FILE。

因此,UPLOAD_ERR_NO_FILE 不是一个错误,而是一个说明输入元素没有值的提示。因此,您不能依赖 $_FILES 数组来判断是否提供了文件。相反,您必须遍历数组并检查每个条目 - 这可能非常困难,因为如果您使用类似“foo[bar][bla]”的命名输入元素,这些值可能会嵌套。

看起来 PHP 刚刚向您介绍了另一个常见的陷阱。
admin at compumatter dot com
4 年前
我们使用此函数来处理文件上传。

由于 $_FILES 允许上传多个文件,因此它会遍历每个文件,如果出现错误,它会以人类可读的语言将错误信息显示在错误日志中,然后返回/退出。您可以根据需要调整它以显示为 echo。

function file_upload_test($messageBefore="CM FILE UPLOAD MESSAGE"){
global $_FILES;
# 单文件限制
$upload_max_size = ini_get('upload_max_filesize');
# 批量或多个文件的组合
$post_max_size = ini_get('post_max_size');
# 可能出现错误的数组,如果 $key=error 部分存在错误,则返回该数组
$phpFileUploadErrors = array(
0 => '文件上传成功,没有错误',
1 => '超过了 php.ini 中的 upload_max_filesize 限制,限制为 '.$upload_max_size.'MB',
2 => '上传的文件大小超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令',
3 => '上传的文件只上传了一部分',
4 => '没有上传任何文件',
6 => '缺少临时文件夹',
7 => '无法将文件写入磁盘。',
8 => 'PHP 扩展程序阻止了文件上传。',
);

error_log("========================================");
error_log("$messageBefore");
error_log("========================================");
foreach ($_FILES['cmmediabrowsedfor'] as $key => $value) {
${$key}=$value;
error_log('$_FILES ['.$key.'] = ['.$value.']');
if(is_array($value)){
foreach ($value as $key2 => $value2) {
error_log(' > $_FILES ['.$key.']['.$key2.'] = '.$value2);
if($key=='error'){
error_log(' ******* CM 上传失败: '.$phpFileUploadErrors[$value2]);
error_log(' 退出/返回 plugins/cm-alpha/php/images/img-create-tmp.php');
error_log(' ');
exit;
}
}
}
}
if(!file_exists($_FILES["cmmediabrowsedfor"]["tmp_name"][0]) || !is_uploaded_file($_FILES["cmmediabrowsedfor"]["tmp_name"][0])) {
error_log("没有上传文件 ");
} else {
error_log("成功上传文件 ");
}
}
belowtherim2000 at yahoo dot com
17 年前
我一直尝试调整文件大小限制,并且关于 post_max_size 设置,似乎存在 2047M 的硬限制。任何大于该数字的指定都会导致上传失败,没有任何有用的错误信息描述问题所在。无论要上传的文件有多小,都会发生这种情况。发生错误时,我的页面会尝试输出原始文件的名称。但我发现,这个我保存在本地变量中的原始文件名实际上被破坏了。即使我尝试输出 $_FILES['uploadedfiles']['error'] 中的错误代码,也会返回一个空字符串/值。

希望这条信息能够帮助其他人避免类似的困扰。
rlerne at gmail dot com
9 年前
这更新了上面的 "adam at gotlinux dot us",使其版本感知,并为数组添加了新的常量。

我们想要检查版本的原因是,常量在早期版本中没有定义,它们在数组中出现得较晚。当文件实际上成功上传时,它们实际上会将 "0" 索引(无错误)覆盖为错误消息。

它还删除了错误的常量值(0、1、2 等),以防它们将来发生更改(代码仍然可以正常工作)。

<?php

$upload_errors
= array(
0 => "没有错误,文件上传成功"
,UPLOAD_ERR_INI_SIZE => "上传的文件超过了 php.ini 中的 upload_max_filesize 指令"
,UPLOAD_ERR_FORM_SIZE => "上传的文件超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令"
,UPLOAD_ERR_PARTIAL => "上传的文件仅部分上传"
,UPLOAD_ERR_NO_FILE => "没有上传文件"
);

if (
version_compare(PHP_VERSION, '5.0.3') >= 0)
$upload_errors[UPLOAD_ERR_NO_TMP_DIR] = "缺少临时文件夹";

if (
version_compare(PHP_VERSION, '5.1.0') >= 0)
$upload_errors[UPLOAD_ERR_CANT_WRITE] = "无法写入磁盘";

if (
version_compare(PHP_VERSION, '5.2.0') >= 0)
$upload_errors[UPLOAD_ERR_EXTENSION] = "文件上传被扩展程序停止";
?>
roger dot vermeir at nokia dot com
5 年前
刚刚发现定义以下内容非常重要:
input type="hidden" name="MAX_FILE_SIZE" value=...
在定义 input type="FILE" name=... 之后
在你的 html/php 中。
如果你将它们互换位置,你将继续收到文件大小超过(错误 2)!
希望这能有所帮助。
罗杰
krissv at ifi.uio.no
19 年前
当 $_FILES 等为空,就像 Dub spencer 在顶部注释中说的那样,并且错误没有设置,这可能是因为表单的 enctype 没有正确设置。然后除了可能是 HTTP 服务器错误之外,不会发生任何其他错误。

enctype="multipart/form-data" 工作正常
viseth10 at gmail dot com
6 年前
[好吧,只是一个小的注释。]
匿名在顶部发布的 UploadException 类示例很棒。它运行良好。但存在一个特定问题。你知道生成错误有两面性。
首先 -> 针对客户端。
其次 -> 针对将使用你的脚本的开发者

但我只看到了生成异常的一面。即针对开发者。

为什么?因为当你生成异常时,你的脚本将会停止并执行你在 catch 子句中定义的操作。
现在你不想让任何客户端看到异常,是吗?我也不会。客户端会希望用他们能理解的简单词语了解发生了什么错误,而不是希望他们的 Web 应用程序在上传失败时崩溃。所以,不要生成异常。这些错误应该被收集起来,并以优雅的方式显示给客户端。这是一个小建议。
继续更聪明地开发。
Dub Spencer
19 年前
上传不起作用,并且没有错误?

实际上,发布到脚本中的 $_FILES 和 $_REQUEST 都是空的?

检查一下,"post_max_size" 是否低于你想要加载的数据的大小。

在 Apache 错误日志中,会有一个类似 "Invalid method in request" 的条目。在访问日志中,将有两个请求:一个用于 POST,另一个以全部 "----" 开头,并产生 501。
web att lapas dott id dott lv
17 年前
1. 那么关于多文件上传呢? - 如果有多个文件出现 UPLOAD_ERR_INI_SIZE 错误 - 我们无法正常检测到它吗?...因为我们有一个数组,但这个错误返回 null,无法使用 foreach。因此,对于多文件上传,我们无法正常通知用户... 我们只能检测到 sizeof($_FILES["file"]["error"]) == 0,但实际上无法返回错误代码。max_file_size 也不起作用,因为它分别引用每个文件,但 php.ini 中的 upload_max_filesize 指令引用所有文件。因此,例如,如果 upload_max_filesize=8Mb,max_file_size = 7Mb,并且我的一个文件是 6.5Mb,另一个是 5Mb,它超过了 upload_max_filesize - 无法返回错误,因为我们不知道从哪里获取该错误。
不幸的是,我们无法在客户端获取文件大小,即使 AJAX 通常也无法做到这一点。

2. 如果在文件字段中粘贴一些内容,比如 D:\whatever,那么即使根本不存在这样的文件,也不会返回错误。
info at foto50 dot com
17 年前
对于那些用德语(或者可能是其他语言)阅读本手册的人,如果你没有找到这里列出的错误编号,请查看本页面的英文版本;)
Tom
9 年前
由于在文件上传中通常使用 move_uploaded_file,因此应该在这里记录如何获取它的错误消息(尤其是在手册的其他地方没有记录的情况下)。
常见的代码是做类似以下的事情
if (move_uploaded_file($_FILES["file1"]["tmp_name"], $target_file)) {
echo "<P>FILE UPLOADED TO: $target_file</P>";
} else {
echo "<P>MOVE UPLOADED FILE FAILED!!</P>";
print_r(error_get_last());
}
To Top