Upload 类別

Upload 类別可以安全地处理被上傳到应用程序的档案。 它能让你用不同的方式過濾上傳、定義目标档案名稱應該像怎樣、或過濾档案名稱的大小或長度。

上傳档案陣列

每个上傳档案的資訊被儲存在 Upload 类別中的一个多維陣列。 對於每个档案,每个被定義的陣列有下列欄位:

类型 描述
field 字串 被用來上傳档案的表单欄位名稱。如果該表单欄位是一个(多維)陣列, 該陣列鍵将被以冒號分隔來添加到欄位名稱。 所以一个稱为 "field[a][b][]" 的欄位将被儲存为 "field:a:b:0"。
name 字串 上傳档案的名稱。
type 字串 上傳文件的 MIME 类型,由瀏覽器所定義。
mimetype 字串 上傳档案的 MIME 类型,如同 Upload 类別所確定的。 請注意,这需要安装一个最新的 'mime magic' 档案。 此档案出现在每个 *xin 平台,但在 Windows 平台,你可能必須自己安装这个档案。 如果 MIME 类型不能被確定,此欄位包含的值與 'type' 相同。
file 字串 上傳档案臨時位置的完整档案名稱。
filename 字串 上傳档案的档案名稱(主档名)。
extension 字串 上傳档案的副档名。
size 整数 上傳档案的大小(位元組)。
error 布林 如果为 true,上傳失敗的話,错误陣列包含原因。
errors 陣列 一个陣列群的陣列,每个有兩个值。'error',包含错误代码,以及 'message',包含错误文字。

請注意,MIME 类型将始終包含最具體的类型。所以如果瀏覽器宣稱它是一个 MS-Word 文件, 但 MIME 类型被测定是 "application/octet-stream",瀏覽器的 MIME 类型会被使用,即使这可能是错的或無法預期的! 例如,一个 Microsoft .xlsx 档案可能被偵测是 "application/zip"。

在你呼叫 save() 方法之後,此陣列結構会被擴充兩个額外欄位,給你關於實際儲存的資訊。

类型 描述
saved_to 字串 上傳档案被儲存的完整路徑。
saved_as 字串 該档案被儲存的名稱
errors 陣列 错误陣列(以及错误布林)将在呼叫 save() 來指示任何在试圖儲存档案時遇到的错误之後被更新。

定義的错误常数

Upload 类別定義以下的错误常数:

名稱 描述
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 寫入档案到硬碟失敗。
UPLOAD_ERR_EXTENSION 一个 PHP 擴充停止了档案上傳。PHP 沒提供方法來查明是哪个擴充造成档案上傳停止;審視 phpinfo() 中的已載入擴充列表可能会有幫助。
UPLOAD_ERR_MAX_SIZE 上傳档案超過了定義在配置中的最大档案大小。
UPLOAD_ERR_EXT_BLACKLISTED 上傳档案的副档名被定義在副档名黑名单中。
UPLOAD_ERR_EXT_NOT_WHITELISTED 上傳档案的副档名沒有被定義在副档名白名单中。
UPLOAD_ERR_TYPE_BLACKLISTED 上傳档案的类型被定義在类型黑名单中。
UPLOAD_ERR_TYPE_NOT_WHITELISTED 上傳档案的类型沒有被定義在类型白名单中。
UPLOAD_ERR_MIME_BLACKLISTED 上傳档案的 MIME 类型被定義在 MIME 类型黑名单中。
UPLOAD_ERR_MIME_NOT_WHITELISTED 上傳档案的 MIME 类型沒有被定義在 MIME 类型白名单中。
UPLOAD_ERR_MAX_FILENAME_LENGTH 上傳的档案名稱超過了定義的最大档案名稱長度。
UPLOAD_ERR_MOVE_FAILED 上傳的档案名稱不能從臨時儲存移动到指定路徑。这可能意味著有一个權限問題。
UPLOAD_ERR_DUPLICATE_FILE 上傳的档案名稱不能被儲存因为已存在同名档案。

請注意,为了能夠上傳档案,你的 HTML <form> 标籤必須包含 enctype="multipart/form-data", 而且你的表单必須包含至至少一个 "file" 类型的輸入欄位。沒有它,所有上傳将失敗,而且 Upload::process 将拋出一个例外!

用法範例

// 自訂此上傳的配置
$config = array(
	'path' => DOCROOT.'files',
	'randomize' => true,
	'ext_whitelist' => array('img', 'jpg', 'jpeg', 'gif', 'png'),
);

// 处理 $_FILES 中上傳的档案
Upload::process($config);

// 如果有任何有效档案
if (Upload::is_valid())
{
	// 根據配置儲存他們
	Upload::save();

	// 呼叫一个模型方法來更新資料庫
	Model_Uploads::add(Upload::get_files());
}

// 并处理任何错误
foreach (Upload::get_errors() as $file)
{
	// $file 是一个有所有档案資訊的陣列,
	// $file['errors'] 包含一个所有发生错误的陣列
	// 每个陣列元素是一个包含 'error' 及 'message' 的陣列
}

is_valid()

is_valid 方法可被用來檢查是否有任何已通過上傳驗證的上傳档案存在。

靜態
參数
回傳 布林 - true 如果驗證的档案存在,false 如果沒有。
範例
// 我們有任何已上傳的档案要儲存嗎?
if (Upload::is_valid())
{
	Upload::save();
}

get_files($index = null)

get_files 方法回傳一个所有上傳档案中 error 值为 false 的多維陣列。

靜態
參数
參数 預設 描述
$index 選擇性 档案在已上傳档案陣列中的索引数字,或一个表单欄位的名稱。如果沒指定,会回傳一个有所有已驗證档案的陣列。 如果該索引数字無效,或如果該索引指向一个有错误狀態为 true 的档案,会拋出一个例外。
回傳 陣列
範例
// 取得成功上傳的档案列表
foreach(Upload::get_files() as $file)
{
	// 使用档案資訊做點什么
}

// 透過索引取得第一个上傳的档案
if ( ! Upload::get_files(0))
{
	// 第一个上傳的档案沒有成功上傳
}

get_errors($index = null)

get_errors 方法回傳一个所有上傳档案中 error 狀態为 true 的多維陣列。

靜態
參数
參数 預設 描述
$index 選擇性 档案在已上傳档案陣列中的索引数字,或一个表单欄位的名稱。如果沒指定,会回傳一个有所有已驗證档案的陣列。 如果該索引数字無效,或如果該索引指向一个有错误狀態为 false 的档案,会拋出一个例外。
回傳 陣列
範例
// 取得有错误的上傳档案列表
foreach(Upload::get_errors() as $file)
{
	// 使用档案資訊做點什么
}

// 透過欄位名稱取得第一个上傳的档案
if (Upload::get_errors('new_image'))
{
	// 上傳档案的表单欄位 'new_image' 有一个错误
	// 定義为 <input type="file" name="new_image" />
}

請注意,在你表单中的所有上傳欄位会被发送,即使它們是選擇性的。欄位留空, 上傳的档案陣列将有一个空的档案條目,会有一个 Upload::UPLOAD_ERR_NO_FILE 的错误代码。 处理错误時,首先檢查错误代码,然後再试著使用任何回傳陣列中的其他欄位。

register($event, $callback)

register 方法能让你为特定的上傳事件註冊回呼(callback), 并能让你添加你自己的程式码到 process()save() 方法。

靜態
參数
參数 預設 描述
$event 必要 你想註冊的回呼(callback)事件名稱。有效的名稱是 'validate'、'before' 和 'after'。
$callback 必要 有效的 PHP 回呼(callback)函式。这可以是一个函式、一个动態或靜態方法、或一个閉包(closure)。
回傳 布林 - true 如果回呼(callback)被註冊,false 如果註冊失敗。
範例
// 使用閉包(closure)註冊 before 回呼(callback)
Upload::register('before', function (&$file) {
	if ($file['error'] == Upload::UPLOAD_ERR_OK)
	{
		switch($file['extension'])
		{
			case "jpg":
			case "png":
			case "gif":
				// 在 images 子目录儲存这些
				$file['file'] .= 'images/';
			break;

			case "css":
				// 在 css 子目录儲存这些
				$file['file'] .= 'css/';
			break;

			case "js":
				// 在 javascript 子目录儲存这些
				$file['file'] .= 'js/';
			break;

			default:
				// 給所有其他的不修改路徑
		}
	}
});

如果你想要使用一个 'validate' 回呼(callback),確保在你呼叫 Upload::process() 之前註冊它。 如果你已经使用 'auto_process' 配置設定,只要你使用 Upload 类別,Upload::process() 将会被呼叫, 这意味著你不能使用此設定,如果你想在执行階段定義回呼(callback)。

該回呼(callback)将接受一个 FuelPHP\Upload\File 物件做为參数。該條目透過引用傳遞, 它允許回呼(callback)函式修改陣列中的條目。你可以因为向下相容的原因存取它做为一个陣列, 但如果迁移你的应用程序從版本 < 1.6 到 1.6+,檢查傳遞到你回呼(callback)的值, 因为不是所有屬性在 1.6 前都是相同命名。
如果該回呼(callback)函式回傳一个整数,它会被假設为一个上傳档案错误代码的更新。 所有其他回傳值会被忽略。

注意:如果你改變在你的回呼(callback)中的 $file 陣列內容,你必須確保該資訊仍然有效, 因为 Upload 不会再一次执行它的檢查。此規則的唯一例外是 'file' 路徑, 如果需要它会在回呼(callback)被执行之後被檢查并建立。

process($config = array())

process 方法处理關於所有上傳档案的資訊, 正規化可被使用表单欄位名稱的不同排列組合, 取回額外關於档案及其 MIME 类型的資訊, 并驗證档案。

靜態
參数
參数 預設 描述
$config 選擇性 配置項目的陣列,如此你可以覆寫定義在配置档案中的設定。
回傳
拋出 FuelException,當沒有档案试圖上傳可被偵测到(即沒有 "Enctype" 或 type="file" 輸入欄位的表单)
範例
// 处理上傳的档案
// 設定最大大小为 10kb,并允許重複档案的覆寫
Upload::process(array(
	'max_size'    => 10240,
	'auto_rename' => false,
	'overwrite'   => true
));

如果你打算使用此方法,在配置中停用 auto_process,以避免处理上傳的档案兩次!

save( ... )

save 方法儲存所有已驗證的上傳档案到指定的路徑。

靜態
參数
參数 預設 描述
$integer 選擇性 透過 get_files() 回傳的档案陣列的鍵。这能让你從一組上傳档案中儲存一个獨立的档案。
$array 選擇性 透過 get_files() 回傳的档案陣列的鍵陣列。这能让你從一組上傳档案中儲存選擇的档案。
$string 選擇性 档案應該被儲存的路徑。它覆寫指定在配置中的路徑,或在 process() 方法被呼叫時傳遞在 $config 陣列中的路徑。

請注意,这些參数所給的順序是不相關的,而他們全都是選擇性的。但使用 $integer 或 $array,不要兩个都使用。如果你这樣做,最後一个指定的会被使用。
回傳
範例
// 儲存所有驗證的档案
Upload::save();

// 只儲存第一个上傳的档案
Upload::save(0);

// 儲存第一个、第二个和第四个上傳的档案
Upload::save(0, 1, 3);

// 儲存所有驗證的档案,并存到替代的位置
$arr = Upload::get_files();
Upload::save(DOCROOT.'assets', array_keys($arr));

// 处理这些档案的任何错误
foreach (Upload::get_errors() as $key => $file)
{
	// 在这裡处理错误
}