在處理多檔案上傳時,長時間的等待、網路波動導致的超時與失敗是常見痛點。PHP 預設會將上傳檔案暫存在臨時目錄,直到上傳完成才能讀取資訊,這使得即時進度顯示變得困難。本文將介紹兩種主流解決方案:APC 擴展與 uploadprogress 擴展,幫助你實現即時上傳進度條,並突破檔案大小限制。
APC (Alternative PHP Cache) 從 3.0.13 版本起支援 RFC1867 上傳進度追蹤。安裝後需在 php.ini 中啟用:
apc.rfc1867=1
前端表單需包含隱藏欄位 APC_UPLOAD_PROGRESS,值為唯一標識鍵。後端透過 apc_fetch('upload_' . $_POST['APC_UPLOAD_PROGRESS']) 即可獲取進度資料。
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// 上傳請求處理
$status = apc_fetch('upload_' . $_POST['APC_UPLOAD_PROGRESS']);
$status['done'] = 1;
echo json_encode($status); // 供 AJAX 輪詢
exit;
} elseif (isset($_GET['progress_key'])) {
// 讀取上傳進度
$status = apc_fetch('upload_' . $_GET['progress_key']);
echo json_encode($status);
exit;
} else {
// 顯示上傳表單
}
?>
前端配合 JavaScript 定時請求 progress_key,即可動態更新進度條。
uploadprogress 是 PECL 專門為上傳進度設計的擴展。安裝後需設定儲存路徑模板:
uploadprogress.file.filename_template = "/tmp/upd_%s.txt"
表單需包含 UPLOAD_IDENTIFIER 隱藏欄位。上傳完成後,將暫存檔移動至目標目錄;進度查詢時呼叫 uploadprogress_get_info($unique_id) 獲取陣列資料。
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (is_uploaded_file($_FILES['upfile']['tmp_name'])) {
$upload_dir = 'your_path/';
$ext = strrchr($_FILES['video']['name'], '.');
$sessid = $_POST['UPLOAD_IDENTIFIER'];
$tmpfile = $upload_dir . $sessid;
$sessfile = $upload_dir . $sessid . $ext;
if (move_uploaded_file($_FILES['upfile']['tmp_name'], $tmpfile)) {
// 上傳成功邏輯
} else {
// 上傳失敗邏輯
}
}
} elseif (!empty($_GET['sessid'])) {
// 設定快取標頭
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Content-Type: text/html; charset=UTF-8");
$unique_id = $_GET['sessid'];
$uploadvalues = uploadprogress_get_info($unique_id);
if (is_array($uploadvalues)) {
echo json_encode($uploadvalues);
} else {
// 讀取進度失敗處理
}
} else {
// 顯示上傳表單
}
?>
session.upload_progress 內建功能(需啟用 session.upload_progress.enabled)。掌握這兩種方案,即可輕鬆解決大檔案上傳的進度顯示與超時問題,提升使用者體驗。