PHP Conference Japan 2024

错误消息解释

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

此错误代码的值是 **UPLOAD_ERR_*** 常量之一。

添加注释

用户贡献的注释 12 个注释

Viktor
10 年前
更新 Adams 的旧注释。

这可能对某些人有用。

<?php

$phpFileUploadErrors
= array(
0 => '没有错误,文件上传成功',
1 => '上传的文件超过了 php.ini 中 upload_max_filesize 指令的值',
2 => '上传的文件超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令的值',
3 => '上传的文件仅部分上传',
4 => '没有上传任何文件',
6 => '缺少临时文件夹',
7 => '无法将文件写入磁盘。',
8 => 'PHP 扩展停止了文件上传。',
);
匿名
15 年前
[由 php DOT net 上的 danbrown 编辑:此代码是最初由 (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 = "上传的文件超过了 php.ini 中 upload_max_filesize 指令的值";
break;
case
UPLOAD_ERR_FORM_SIZE:
$message = "上传的文件超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令的值";
break;
case
UPLOAD_ERR_PARTIAL:
$message = "上传的文件仅部分上传";
break;
case
UPLOAD_ERR_NO_FILE:
$message = "没有上传任何文件";
break;
case
UPLOAD_ERR_NO_TMP_DIR:
$message = "缺少临时文件夹";
break;
case
UPLOAD_ERR_CANT_WRITE:
$message = "无法将文件写入磁盘";
break;
case
UPLOAD_ERR_EXTENSION:
$message = "文件上传被扩展停止";
break;

default:
$message = "未知的上传错误";
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=>"没有错误,文件上传成功",
1=>"上传的文件超过了 php.ini 中 upload_max_filesize 指令的值",
2=>"上传的文件超过了 HTML 表单中指定的 MAX_FILE_SIZE 指令的值"
3=>"上传的文件仅部分上传",
4=>"没有上传任何文件",
6=>"缺少临时文件夹"
);
?>
stephen at poppymedia dot co dot uk
19 年前
如果 post 大于 php.ini 中设置的 post_max_size

$_FILES 和 $_POST 将返回空
Sohaib Essam
1 年前
switch ($_FILES["image"]["error"]) {
case UPLOAD_ERR_PARTIAL
exit('文件仅部分上传');
break;
case UPLOAD_ERR_NO_FILE
exit('没有上传任何文件');
break;
case UPLOAD_ERR_EXTENSION
exit('文件上传被 PHP 扩展停止');
break;
case UPLOAD_ERR_FORM_SIZE
exit('文件超过了 HTML 表单中的 MAX_FILE_SIZE');
break;
case UPLOAD_ERR_INI_SIZE
exit('文件超过了 php.ini 中的 upload_max_filesize');
break;
case UPLOAD_ERR_NO_TMP_DIR
exit('未找到临时文件夹');
break;
case UPLOAD_ERR_CANT_WRITE
exit('无法写入文件');
break;
default
exit('未知的上传错误');
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 客户端获取的任意数字(从安全角度来看,始终必须不信任 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=>'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
'The uploaded file was only partially uploaded.',
'No file was uploaded.',
6=>'Missing a temporary folder.',
'Failed to write file to disk.',
'A PHP extension stopped the file upload.'
);

// 在循环之外...
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);
?>
tyler at fishmas dot org
20 年前
关于发送无效文件名的问题,一个非常简单的检查方法是检查文件大小以及文件名。例如,要检查文件大小,只需使用文件信息数组中的 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 只是让您遇到了另一个常见的陷阱。
To Top