php使用阿里云oss-php-sdk分片上传大文件

技术文档网 2021-04-19

目前阿里云官方的php oss sdk不支持分片上传内存中的文件,使得大文件的上传无法进行,本文介绍一个相对简单的解决办法

大文件上传方案

大文件上传方案简单来说有如下2种:

  1. Web client端直传oss
  2. Web client端传到web server,再从web server传到oss

Web端直传oss的介绍参见:Web端直传实践

最安全的做法是“服务端签名直传并设置上传回调”的方式,但是需要的时间最多,适用于在项目还没有实施落地的情况。

如果Web已经做好Form表单上传文件,想快速扩大单个文件上传限制呢?

由于网络状况和服务器的限制,单纯调整超时时间,并不能有效的解决单个大档案上传的问题。

所以考虑的方向是在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]);
    }
}

相关文章

  1. 如何通过xhprof分析性能

    使用方法 xhprof_enable(); /** ... 要检查的php代码 ... **/ $xhprof_data = xhprof_disable(); // 引入xhprof_lib i

  2. LUMEN API Controller 规范

    1. 第三方依赖库规范 在使用LUMEN实现API接口时,以下库必须需要包含在composer包依赖中,以实现代码编写的一些规范 dingo/api : 实现API接口库 vlucas/phpdo

  3. PHP文件锁

    共享锁(LOCK_SH) 什么时候加共享锁? 当在读取数据的时候同时进行着其他的写操作,这个时候需要对文件加共享锁,否则无论有没有对写操作加写锁都会写入成功,导致数据不一致 当文件获得共享锁时,其他

  4. Hello-Risen-程序

    首先需要说明的是,您下载到的文件包含两部分,其中src中是开发源码,用于对Risen框架本身的开发,risen 目录中是通过源码生成的包含debug和release版本的框架程序,用于您应用程序的开发

  5. PHP自定义类示例(Weixin消息解析类)

    PHP自定义类示例(Weixin消息解析类) /** * Created by Qingger. * User: jsspf * Date: 2017/3/24 * Time: 10:50

随机推荐

  1. 如何通过xhprof分析性能

    使用方法 xhprof_enable(); /** ... 要检查的php代码 ... **/ $xhprof_data = xhprof_disable(); // 引入xhprof_lib i

  2. LUMEN API Controller 规范

    1. 第三方依赖库规范 在使用LUMEN实现API接口时,以下库必须需要包含在composer包依赖中,以实现代码编写的一些规范 dingo/api : 实现API接口库 vlucas/phpdo

  3. PHP文件锁

    共享锁(LOCK_SH) 什么时候加共享锁? 当在读取数据的时候同时进行着其他的写操作,这个时候需要对文件加共享锁,否则无论有没有对写操作加写锁都会写入成功,导致数据不一致 当文件获得共享锁时,其他

  4. Hello-Risen-程序

    首先需要说明的是,您下载到的文件包含两部分,其中src中是开发源码,用于对Risen框架本身的开发,risen 目录中是通过源码生成的包含debug和release版本的框架程序,用于您应用程序的开发

  5. PHP自定义类示例(Weixin消息解析类)

    PHP自定义类示例(Weixin消息解析类) /** * Created by Qingger. * User: jsspf * Date: 2017/3/24 * Time: 10:50