2024 日本 PHP 研討會

錯誤訊息說明

PHP 會連同檔案陣列一起傳回適當的錯誤碼。錯誤碼可以在 PHP 檔案上傳期間建立的檔案陣列的 error 部分找到。換句話說,錯誤可能會在 $_FILES['userfile']['error'] 中找到。

此錯誤碼的值是 UPLOAD_ERR_* 常數之一。

新增筆記

使用者貢獻的筆記 12 則筆記

Viktor
10 年前
更新 Adam 先前的評論。

這可能對某些人有用。

<?php

$phpFileUploadErrors
= array(
0 => '檔案上傳成功,沒有錯誤',
1 => '上傳的檔案超過了 php.ini 中 upload_max_filesize 的設定值',
2 => '上傳的檔案超過了 HTML 表單中指定的 MAX_FILE_SIZE 設定值',
3 => '檔案只有部分被上傳',
4 => '沒有檔案被上傳',
6 => '缺少暫存資料夾',
7 => '檔案寫入磁碟失敗',
8 => '一個 PHP 擴充功能停止了檔案上傳',
);
匿名
15 年前
【danbrown AT php DOT net 編輯:此程式碼是 2009 年 3 月 4 日由 (Thalent, Michiel Thalen) 提交的筆記的修正版本。】


這是在處理上傳錯誤時,一個方便使用的例外處理方法。

<?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_filesize",它們共同對可接收的資料量設下了硬性限制。

除此之外,PHP 也以某種方式實作了軟性限制的功能。它會檢查是否存在名為 "max_file_size" 的表單欄位(大小寫皆可),該欄位應包含一個整數,表示允許的最大位元組數。如果上傳的檔案大於此欄位中的整數,PHP 將會拒絕此次上傳,並在 $_FILES 陣列中顯示錯誤碼。

PHP 文件也(曾經 - 參考錯誤 #40387 - http://bugs.php.net/bug.php?id=40387)模糊地提到「允許瀏覽器在上傳前檢查檔案大小」。然而,這並非事實,也從未如此。到目前為止,從未有任何 RFC 提議使用此類命名的表單欄位,也沒有任何瀏覽器實際檢查其存在或內容,或阻止任何事情。PHP 文件暗示瀏覽器可能會提醒使用者其上傳檔案過大 — 這根本是錯誤的。

請注意,使用這個 PHP 功能並不是一個好主意。表單欄位很容易被客戶端更改。如果您必須檢查檔案大小,請在您的腳本中使用腳本定義的整數,以傳統方式進行檢查,而不是使用從 HTTP 客戶端取得的任意數字(從安全性的角度來看,必須始終保持不信任)。
roland at REMOVE_ME dot mxchange dot org
6 年前
我擴展了 gotlinux.us 網站 @adam 的例子,加入了適當的 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);
?>
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