PHP获取上传进度能吗

wen PHP项目 1

本文目录导读:

PHP获取上传进度能吗

  1. 使用 PHP 原生 Session 上传进度(PHP 5.4+)
  2. 使用 APC/Apcu 扩展(已废弃/较旧)
  3. 使用 JavaScript + XMLHttpRequest Level 2(推荐)
  4. 第三方库/方案(生产环境推荐)
  5. WebSocket + 专门的上传服务器(高级)
  6. 注意事项
  7. 总结建议

在PHP中获取上传进度是可以的,但实现方式取决于你的PHP版本和服务器配置。

主要有以下几种方法:

使用 PHP 原生 Session 上传进度(PHP 5.4+)

这是PHP内置的功能,不需要额外的扩展。

前置条件:

  • PHP 5.4 或以上
  • session.upload_progress.enabled = On(默认开启)

实现步骤:

HTML 表单:

<form action="upload.php" method="post" enctype="multipart/form-data">
    <!-- 关键:session.upload_progress.name 对应的隐藏字段 -->
    <input type="hidden" name="<?php echo ini_get('session.upload_progress.name'); ?>" value="my_upload" />
    <input type="file" name="file1" />
    <input type="submit" value="上传" />
</form>

获取进度(progress.php):

<?php
session_start();
// 获取上传进度
$key = ini_get('session.upload_progress.prefix') . 'my_upload';
if (!empty($_SESSION[$key])) {
    $progress = $_SESSION[$key];
    echo json_encode([
        'uploaded' => $progress['bytes_processed'],
        'total' => $progress['content_length'],
        'percentage' => round($progress['bytes_processed'] / $progress['content_length'] * 100)
    ]);
} else {
    echo json_encode(['progress' => 0]);
}

前端轮询:

// 使用 AJAX 定时请求 progress.php
setInterval(function() {
    fetch('progress.php')
        .then(response => response.json())
        .then(data => {
            // 更新进度条
            console.log('上传进度:' + data.percentage + '%');
        });
}, 1000);

使用 APC/Apcu 扩展(已废弃/较旧)

APC 方法(PHP 5.x,已废弃):

<?php
// 在表单中需要设置:
// <input type="hidden" name="APC_UPLOAD_PROGRESS" value="unique_id" />
// 获取进度
$status = apc_fetch('upload_' . $_POST['APC_UPLOAD_PROGRESS']);

使用 JavaScript + XMLHttpRequest Level 2(推荐)

这是最通用、最可靠的方法,不需要服务器端额外配置。

const input = document.querySelector('input[type="file"]');
const formData = new FormData();
formData.append('file', input.files[0]);
const xhr = new XMLHttpRequest();
xhr.upload.addEventListener('progress', (e) => {
    if (e.lengthComputable) {
        const percent = (e.loaded / e.total) * 100;
        document.querySelector('progress').value = percent;
        console.log(`已上传 ${percent}%`);
    }
});
xhr.addEventListener('load', () => {
    console.log('上传完成');
});
xhr.open('POST', 'upload.php');
xhr.send(formData);

第三方库/方案(生产环境推荐)

Dropzone.js

<div id="myDropzone" class="dropzone"></div>
<script>
Dropzone.options.myDropzone = {
    url: '/upload.php',
    paramName: 'file',
    maxFilesize: 2, // MB
    dictDefaultMessage: "拖拽文件到这里上传",
    init: function() {
        this.on('uploadprogress', function(file, progress, bytesSent) {
            console.log(file.name + ': ' + progress + '%');
        });
    }
};
</script>

Plupload

支持HTML5、Flash、Silverlight等多种上传方式,自带进度条。


WebSocket + 专门的上传服务器(高级)

对于大文件上传,可以使用:

  • Resumable.js - 分块上传
  • Tus - 可断点续传的开放协议

注意事项

问题 解决方案
Nginx 缓冲问题 配置 proxy_buffering off 或使用 X-Accel-Buffering: no
Apache 模块问题 修改 mod_php 配置
Session 并发锁 使用 session_write_close() 允许并行请求
内存限制 调整 memory_limitupload_max_filesize

总结建议

  • 小项目/简单需求:使用 XMLHttpRequest Level 2(方法3),最简单且跨浏览器兼容
  • 大文件/企业级应用:使用 Dropzone.jsPlupload 等成熟库
  • 需要后端进度信息:使用 PHP Session 方法(方法1)
  • 非常规需求(断点续传):使用 Tus 协议

最推荐的方案是 XMLHttpRequest Level 2,因为它:

  1. 实现简单
  2. 不需要服务器端配置
  3. 浏览器原生支持
  4. 不会消耗服务器额外资源

抱歉,评论功能暂时关闭!