PHP 实现文件流上传及接收教程
编辑:本站更新:2024-12-04 12:47:11人气:5992
在PHP开发中,实现文件的流式上传与接收是一项常见的且实用的功能。本文将深入探讨如何利用PHP来处理大体积或者大量数据时进行高效的、分块式的文件传输。
首先,在前端部分,为了支持文件流上传功能,我们需要使用HTML5提供的FormData对象和XMLHttpRequest Level 2 API(也称为xhr2)。以下是一个基本示例:
<form id="uploadForm">
<input type="file" name="streamFile"/>
</form>
<script>
var form = document.getElementById('uploadForm');
var formData = new FormData(form);
// 创建一个新的 XMLHttpRequest 对象,并设置请求方式为 POST
var xhr = new XMLHttpRequest();
xhr.open("POST", "/your/upload/script.php");
// 设置 onprogress 回调函数以实时获取进度反馈
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
console.log(percentDone);
}
};
xhr.onreadystatechange = function() {
// 请求完成并且成功响应后执行操作
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
alert(this.responseText);
}
};
// 发送formData到服务器端脚本
xhr.send(formData);
</script>
而在服务端(PHP),我们通过`$_FILES['streamFile']`超全局变量可以访问接收到的数据并将其保存至磁盘或进一步处理。但是由于是“流”模式上传,所以我们需要逐段读取并通过php://temp临时内存流或者是直接写入硬盘的方式存储:
<?php
$targetDir = "uploads/";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$fileName = $_FILES["streamFile"]["name"];
// 打开一个临时内存流用于存放缓冲区内的数据
$tmp_file = fopen("php://temp/maxmemory:10485760", 'w+b');
// 获取HTTP头中的Content-Type以便判断是否multipart/form-data类型(即是否有文件正在被上传)
if(str_contains($_SERVER['CONTENT_TYPE'], 'multipart')) {
$boundary = substr($httpHeader, strpos($httpHeader, "\r\n\r\n")+4);
while(!feof(STDIN)) {
$chunk = fread(STDIN, 8192);
// 查找每个边界位置并将内容写入临时流内
if(false !== ($pos = strpos($chunk, '--'.$boundary))) {
fwrite($tmp_file, trim(substr($chunk, 0 , $pos)));
parse_str(trim("--".$boundary."--".substr($chunk, $pos+strlen('--'.$boundary)), "--"), $data);
file_put_contents("$targetDir/$fileName", $data['filename']);
}
}
fclose($tmp_file);
echo "Upload complete.";
}
}
?>
上述代码只是一个简单的概念演示,实际应用可能要更复杂一些,例如错误检查、安全验证以及断点续传等功能的支持都需要额外编写逻辑去完善。同时需要注意的是,对于大型文件的流式处理应确保有足够的系统资源可用,包括但不限于足够的内存空间、适当的I/O速度等条件满足。
总的来说,借助于现代Web技术和服务端语言的强大能力,我们可以轻松地实现在浏览器上高效稳定的大规模文件流式上传,极大地提升了用户体验的同时也为高并发场景下的大规模数据迁移提供了可靠的解决方案。
首先,在前端部分,为了支持文件流上传功能,我们需要使用HTML5提供的FormData对象和XMLHttpRequest Level 2 API(也称为xhr2)。以下是一个基本示例:
html
<form id="uploadForm">
<input type="file" name="streamFile"/>
</form>
<script>
var form = document.getElementById('uploadForm');
var formData = new FormData(form);
// 创建一个新的 XMLHttpRequest 对象,并设置请求方式为 POST
var xhr = new XMLHttpRequest();
xhr.open("POST", "/your/upload/script.php");
// 设置 onprogress 回调函数以实时获取进度反馈
xhr.upload.onprogress = function(event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
console.log(percentDone);
}
};
xhr.onreadystatechange = function() {
// 请求完成并且成功响应后执行操作
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
alert(this.responseText);
}
};
// 发送formData到服务器端脚本
xhr.send(formData);
</script>
而在服务端(PHP),我们通过`$_FILES['streamFile']`超全局变量可以访问接收到的数据并将其保存至磁盘或进一步处理。但是由于是“流”模式上传,所以我们需要逐段读取并通过php://temp临时内存流或者是直接写入硬盘的方式存储:
php
<?php
$targetDir = "uploads/";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$fileName = $_FILES["streamFile"]["name"];
// 打开一个临时内存流用于存放缓冲区内的数据
$tmp_file = fopen("php://temp/maxmemory:10485760", 'w+b');
// 获取HTTP头中的Content-Type以便判断是否multipart/form-data类型(即是否有文件正在被上传)
if(str_contains($_SERVER['CONTENT_TYPE'], 'multipart')) {
$boundary = substr($httpHeader, strpos($httpHeader, "\r\n\r\n")+4);
while(!feof(STDIN)) {
$chunk = fread(STDIN, 8192);
// 查找每个边界位置并将内容写入临时流内
if(false !== ($pos = strpos($chunk, '--'.$boundary))) {
fwrite($tmp_file, trim(substr($chunk, 0 , $pos)));
parse_str(trim("--".$boundary."--".substr($chunk, $pos+strlen('--'.$boundary)), "--"), $data);
file_put_contents("$targetDir/$fileName", $data['filename']);
}
}
fclose($tmp_file);
echo "Upload complete.";
}
}
?>
上述代码只是一个简单的概念演示,实际应用可能要更复杂一些,例如错误检查、安全验证以及断点续传等功能的支持都需要额外编写逻辑去完善。同时需要注意的是,对于大型文件的流式处理应确保有足够的系统资源可用,包括但不限于足够的内存空间、适当的I/O速度等条件满足。
总的来说,借助于现代Web技术和服务端语言的强大能力,我们可以轻松地实现在浏览器上高效稳定的大规模文件流式上传,极大地提升了用户体验的同时也为高并发场景下的大规模数据迁移提供了可靠的解决方案。
www.php580.com PHP工作室 - 全面的PHP教程、实例、框架与实战资源
PHP学习网是专注于PHP技术学习的一站式在线平台,提供丰富全面的PHP教程、深入浅出的实例解析、主流PHP框架详解及实战应用,并涵盖PHP面试指南、最新资讯和活跃的PHP开发者社区。无论您是初学者还是进阶者,这里都有助于提升您的PHP编程技能。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。