PHP 5.4 引入 session.upload_progress,無需 APC、Flash、HTML5 File API,純 PHP + JS 即可實現上傳進度監控。
PHP_SESSION_UPLOAD_PROGRESS 設置唯一標識符(如 test)。$_SESSION['upload_progress_標識符']。session.upload_progress.enabled = On
session.upload_progress.cleanup = On
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "PHP_SESSION_UPLOAD_PROGRESS"
session.upload_progress.freq = "1%" ; 每 1% 更新一次
session.upload_progress.min_freq = "1" ; 最小更新間隔 1 秒
<?php session_start(); ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上傳進度演示</title>
<style>
.progress {width:300px;height:20px;border:1px solid #ccc;background:#f0f0f0;margin:10px 0;}
.bar {height:100%;background:#4caf50;width:0%;transition:width 0.3s;}
.label {text-align:center;line-height:20px;color:#333;}
</style>
</head>
<body>
<form id="upload-form" action="upload.php" method="POST" enctype="multipart/form-data" target="hidden_iframe">
<input type="hidden" name="<?php echo ini_get('session.upload_progress.name'); ?>" value="test" />
<p><input type="file" name="file1" /></p>
<p><input type="submit" value="Upload" /></p>
</form>
<iframe id="hidden_iframe" name="hidden_iframe" src="about:blank" style="display:none;"></iframe>
<div id="progress" class="progress" style="display:none;">
<div class="bar"><div class="label">0%</div></div>
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
function fetchProgress() {
$.get('progress.php', { 'PHP_SESSION_UPLOAD_PROGRESS': 'test' }, function(data) {
var pct = parseInt(data);
$('#progress .bar').css('width', pct + '%');
$('#progress .label').text(pct + '%');
if (pct < 100) {
setTimeout(fetchProgress, 100); // 用 setTimeout 避免請求堆疊
} else {
$('#progress .label').text('完成!');
}
});
}
$('#upload-form').submit(function() {
$('#progress').show();
setTimeout(fetchProgress, 100);
});
</script>
</body>
</html>
<?php
// 簡單演示:移動文件到當前目錄
if (is_uploaded_file($_FILES['file1']['tmp_name'])) {
move_uploaded_file($_FILES['file1']['tmp_name'], "./{$_FILES['file1']['name']}");
}
?>
<?php
session_start();
$name = ini_get('session.upload_progress.name');
$key = ini_get('session.upload_progress.prefix') . $_GET[$name];
if (!empty($_SESSION[$key])) {
$current = $_SESSION[$key]['bytes_processed'];
$total = $_SESSION[$key]['content_length'];
echo $current < $total ? ceil($current / $total * 100) : 100;
} else {
echo 100; // 會話不存在視為完成
}
?>
$_SESSION['upload_progress_test'] = [
'start_time' => 1234567890, // 開始時間戳
'content_length' => 57343257, // POST 總長度
'bytes_processed' => 453489, // 已接收字節
'done' => false, // 是否完成
'files' => [ // 每個文件詳情
['field_name'=>'file1','name'=>'test.jpg','tmp_name'=>'/tmp/phpX123',
'size'=>12345,'done'=>false,'start_time'=>...,'bytes_processed'=>...],
// ...
]
];
$_SESSION[$key]['cancel_upload'] = true;(僅影響正在傳輸及後續文件,已完成文件不刪除)。<input type="file" name="files[]" multiple>,Session 中 files 數組包含所有文件進度。freq (如 500KB) 和 min_freq 平衡性能與實時性。target="iframe" 防止頁面跳轉,保持進度條頁面存活。setTimeout 而非 setInterval,避免請求堆疊導致進度倒退。