SWFUpload 是一款結合 Flash 與 JavaScript 的檔案上傳元件,支援多檔案佇列、進度條、檔案類型/大小限制等功能。雖然現代瀏覽器已普及 HTML5 上傳 API,但在需相容舊版 IE 的專案中仍具參考價值。本文提供完整的前端整合與後端 PHP 處理範例。
<!DOCTYPE html>
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>SWFUpload Demo</title>
<link href="css/default.css" rel="stylesheet" type="text/css" />
<!-- SWFUpload 核心與擴充腳本 -->
<script type="text/javascript" src="swfupload/swfupload.js"></script>
<script type="text/javascript" src="js/swfupload.queue.js"></script>
<script type="text/javascript" src="js/fileprogress.js"></script>
<script type="text/javascript" src="js/handlers.js"></script>
<script type="text/javascript">
var swfu;
window.onload = function() {
var settings = {
flash_url: "swfupload/swfupload.swf",
upload_url: "upload.php",
post_params: { "PHPSESSID": "<?php echo session_id(); ?>" },
file_size_limit: "100 MB",
file_types: "*.*",
file_types_description: "All Files",
file_upload_limit: 100,
file_queue_limit: 0,
custom_settings: {
progressTarget: "fsUploadProgress",
cancelButtonId: "btnCancel"
},
debug: false,
// 按鈕外觀
button_image_url: "images/TestImageNoText_65x29.png",
button_width: "65",
button_height: "29",
button_placeholder_id: "spanButtonPlaceHolder",
button_text: '<span class="theFont">瀏覽</span>',
button_text_style: ".theFont { font-size: 16; }",
button_text_left_padding: 12,
button_text_top_padding: 3,
// 事件處理器(需於 handlers.js 定義)
file_queued_handler: fileQueued,
file_queue_error_handler: fileQueueError,
file_dialog_complete_handler: fileDialogComplete,
upload_start_handler: uploadStart,
upload_progress_handler: uploadProgress,
upload_error_handler: uploadError,
upload_success_handler: uploadSuccess,
upload_complete_handler: uploadComplete,
queue_complete_handler: queueComplete
};
swfu = new SWFUpload(settings);
};
</script>
</head>
<body>
<div id="header"><h1 id="logo"><a href="/">SWFUpload</a></h1></div>
<div id="content">
<form id="form1" action="index.php" method="post" enctype="multipart/form-data">
<p>點選「瀏覽」選擇檔案,系統將自動上傳。</p>
<p><strong>請勿上傳含中文檔名的檔案!</strong></p>
<div class="fieldset flash" id="fsUploadProgress"><span class="legend">快速上傳</span></div>
<div id="divStatus">0 個檔案已上傳</div>
<div>
<span id="spanButtonPlaceHolder"></span>
<input id="btnCancel" type="button" value="取消所有上傳" onclick="swfu.cancelQueue();" disabled="disabled" />
</div>
</form>
</div>
</body>
</html>
<?php
// 因 Flash 不自動攜帶 Session,需手動恢復
if (isset($_POST["PHPSESSID"])) session_id($_POST["PHPSESSID"]);
elseif (isset($_GET["PHPSESSID"])) session_id($_GET["PHPSESSID"]);
session_start();
// POST 大小限制檢查
$postMax = ini_get('post_max_size');
$unit = strtoupper(substr($postMax, -1));
$mult = ($unit=='M'?1048576:($unit=='K'?1024:($unit=='G'?1073741824:1)));
if ((int)$_SERVER['CONTENT_LENGTH'] > $mult*(int)$postMax && $postMax) {
header("HTTP/1.1 500 Internal Server Error");
exit("POST exceeded maximum allowed size.");
}
// 基本設定
$savePath = getcwd() . "/files/";
$uploadName = "Filedata";
$maxSize = 2147483647; // 2GB
$extWhitelist = ["doc","txt","jpg","gif","png"];
$validChars = '.A-Z0-9_ !@#$%^&()+={}\[\],~`-';
$maxNameLen = 260;
$errors = [
0=>"上傳成功", 1=>"超過 php.ini upload_max_filesize",
2=>"超過表單 MAX_FILE_SIZE", 3=>"僅部分上傳",
4=>"無檔案上傳", 6=>"缺少暫存資料夾"
];
// 檢查上傳狀態
if (!isset($_FILES[$uploadName])) exitError("No upload found for $uploadName");
if ($_FILES[$uploadName]["error"] != 0) exitError($errors[$_FILES[$uploadName]["error"]]);
if (!is_uploaded_file($_FILES[$uploadName]["tmp_name"])) exitError("is_uploaded_file test failed");
if (!isset($_FILES[$uploadName]['name'])) exitError("File has no name");
// 檔案大小
$fsize = filesize($_FILES[$uploadName]["tmp_name"]);
if (!$fsize || $fsize > $maxSize) exitError("File size exceeds limit");
if ($fsize <= 0) exitError("File size invalid");
// 檔名過濾
$fname = preg_replace('/[^'.$validChars.']|\.+$/i', "", basename($_FILES[$uploadName]['name']));
if (strlen($fname)==0 || strlen($fname) > $maxNameLen) exitError("Invalid file name");
// 重複檔名
if (file_exists($savePath . $fname)) exitError("File already exists");
// 副檔名驗證
$ext = strtolower(pathinfo($_FILES[$uploadName]['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $extWhitelist)) exitError("Invalid file extension");
// 移動檔案
if (!move_uploaded_file($_FILES[$uploadName]["tmp_name"], $savePath.$fname)) {
exitError("Cannot save file");
}
echo "File Received";
exit(0);
function exitError($msg) {
header("HTTP/1.1 500 Internal Server Error");
echo $msg;
exit(0);
}
?>