php使用阿里云oss-php-sdk分片上传大文件
目前阿里云官方的php oss sdk不支持分片上传内存中的文件,使得大文件的上传无法进行,本文介绍一个相对简单的解决办法
大文件上传方案简单来说有如下2种:
- Web client端直传oss
- Web client端传到web server,再从web server传到oss
Web端直传oss的介绍参见:Web端直传实践
最安全的做法是“服务端签名直传并设置上传回调”的方式,但是需要的时间最多,适用于在项目还没有实施落地的情况。
由于网络状况和服务器的限制,单纯调整超时时间,并不能有效的解决单个大档案上传的问题。
所以考虑的方向是在client端将档案分片上传到server,再由server来将分片上传到oss。
client端
client端将文件分片上传可以参考:jQuery-File-Upload
下面是client端javascript和html的示例:
<script src="path/to/jquery.ui.widget.js"></script>
<script src="path/to/jquery.fileupload.js"></script>
<script>
$(function () {
'use strict';
var url = 'path/to/upload/';
$('#uploadfile').fileupload({
url: url,
dataType: 'json',
type: 'POST',
maxChunkSize: 20 * 1000 * 1024, // 分片大小,20M
done: function (e, data) {
$('#files').text(data.files[0].name + ' uploaded successfully!');
},
add: function (e, data) {
$('#files').text('uploading ' + data.files[0].name);
if (data.autoUpload || (data.autoUpload !== false &&
$(this).fileupload('option', 'autoUpload'))) {
data.process().done(function () {
data.submit();
});
}
},
progressall: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('#progress .progress-bar').css(
'width',
progress + '%'
);
},
formData: function (form) {
return form.serializeArray();
}
}).prop('disabled', !$.support.fileInput)
.parent().addClass($.support.fileInput ? undefined : 'disabled');
});
</script>
html的部分添加:
<input type="file" id="uploadfile" name="uploadfile" >
<!-- The global progress bar -->
<div id="progress" class="progress">
<div class="progress-bar progress-bar-success"></div>
</div>
<!-- The container for the uploaded files -->
<div id="files" class="files"></div>
<br>
服务端
oss php sdk的分片上传功能仅支持本地文件的分片上传,所以 client->server->oss的路线不适用。
研究sdk的方法之后发现可以将client传过来的分片使用追加上传的方式来组合成一个文件,方法名:appendObject。
结合 jQuery-File-Upload 的服务端示例:example PHP upload handler,和 OssClient 的appendObject方法
可以总结出获取到需要参数的方法,下面是一个示例:
public function upload()
{
$upload = @$_FILES['uploadfile'];
// Parse the Content-Disposition header, if available:
$content_disposition_header = @$_SERVER['HTTP_CONTENT_DISPOSITION'];
$file_name = $content_disposition_header ?
rawurldecode(preg_replace(
'/(^[^"]+")|("$)/',
'',
$content_disposition_header
)) : $upload['name'];
$content_range_header = @$_SERVER['HTTP_CONTENT_RANGE'];
$content_range = $content_range_header ?
preg_split('/[^0-9]+/', $content_range_header) : null;
$size = $content_range ? $content_range[3] : null;
// 如果 client 上传的文件小于 maxChunkSize 设置的大小,将不会使用分片上传的方式,所以这里要做一个判断
if ( null === $size ) {
$ossClient->putObject($bucket, $file_name, file_get_contents($upload['tmp_name']));
}
else {
$ossClient->appendObject($bucket, $file_name, file_get_contents($upload['tmp_name']), $content_range[1]);
}
}
相关文章
- 如何通过xhprof分析性能
使用方法 xhprof_enable(); /** ... 要检查的php代码 ... **/ $xhprof_data = xhprof_disable(); // 引入xhprof_lib i
- LUMEN API Controller 规范
1. 第三方依赖库规范 在使用LUMEN实现API接口时,以下库必须需要包含在composer包依赖中,以实现代码编写的一些规范 dingo/api : 实现API接口库 vlucas/phpdo
- PHP文件锁
共享锁(LOCK_SH) 什么时候加共享锁? 当在读取数据的时候同时进行着其他的写操作,这个时候需要对文件加共享锁,否则无论有没有对写操作加写锁都会写入成功,导致数据不一致 当文件获得共享锁时,其他
- Hello-Risen-程序
首先需要说明的是,您下载到的文件包含两部分,其中src中是开发源码,用于对Risen框架本身的开发,risen 目录中是通过源码生成的包含debug和release版本的框架程序,用于您应用程序的开发
- PHP自定义类示例(Weixin消息解析类)
PHP自定义类示例(Weixin消息解析类) /** * Created by Qingger. * User: jsspf * Date: 2017/3/24 * Time: 10:50
随机推荐
- 如何通过xhprof分析性能
使用方法 xhprof_enable(); /** ... 要检查的php代码 ... **/ $xhprof_data = xhprof_disable(); // 引入xhprof_lib i
- LUMEN API Controller 规范
1. 第三方依赖库规范 在使用LUMEN实现API接口时,以下库必须需要包含在composer包依赖中,以实现代码编写的一些规范 dingo/api : 实现API接口库 vlucas/phpdo
- PHP文件锁
共享锁(LOCK_SH) 什么时候加共享锁? 当在读取数据的时候同时进行着其他的写操作,这个时候需要对文件加共享锁,否则无论有没有对写操作加写锁都会写入成功,导致数据不一致 当文件获得共享锁时,其他
- Hello-Risen-程序
首先需要说明的是,您下载到的文件包含两部分,其中src中是开发源码,用于对Risen框架本身的开发,risen 目录中是通过源码生成的包含debug和release版本的框架程序,用于您应用程序的开发
- PHP自定义类示例(Weixin消息解析类)
PHP自定义类示例(Weixin消息解析类) /** * Created by Qingger. * User: jsspf * Date: 2017/3/24 * Time: 10:50