首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 5.4+ Session Upload Progress 實現文件上傳進度條(純原生無插件)

     編輯:PHP 綜合知識

背景

PHP 5.4 引入 session.upload_progress,無需 APC、Flash、HTML5 File API,純 PHP + JS 即可實現上傳進度監控。

核心原理

  1. 表單隱藏字段 PHP_SESSION_UPLOAD_PROGRESS 設置唯一標識符(如 test)。
  2. 上傳過程中,PHP 將進度信息寫入 $_SESSION['upload_progress_標識符']。
  3. 前端 Ajax 輪詢進度接口,讀取 Session 計算百分比,更新進度條。
  4. 上傳完成自動清理 Session(可配置)。

php.ini 關鍵配置

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 秒

完整三文件實現

1. 上傳頁面 index.php

<?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>

2. 處理上傳 upload.php

<?php
// 簡單演示:移動文件到當前目錄
if (is_uploaded_file($_FILES['file1']['tmp_name'])) {
    move_uploaded_file($_FILES['file1']['tmp_name'], "./{$_FILES['file1']['name']}");
}
?>

3. 進度接口 progress.php

<?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 數據結構詳解

$_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 平衡性能與實時性。

注意事項

  1. 隱藏字段 **必須** 在文件字段**之前**。
  2. 表單 target="iframe" 防止頁面跳轉,保持進度條頁面存活。
  3. 輪詢用 setTimeout 而非 setInterval,避免請求堆疊導致進度倒退。
  4. PHP 5.4+ 且 Session 正常工作(文件/Redis/Memcached 驅動均可)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved