一, 前言
在网站开发中, 经常会有上传文件的需求, 有的文件 size 太大直接上传, 经常会导致上传过程中耗时太久, 大量占用带宽资源, 因此有了分片上传.
分片上传主要是前端将一个较大的文件分成等分的几片, 标识当前分片是第几片和总共几片, 待所有的分片均上传成功的时候, 在后台进行合成文件即可.
二, 开发过程中遇到的问题
分片的时候每片该分多大 size? 太大会出现 "413 request entity too large"
分片上传的时候并不是严格按照分片的序号顺序上传, 如何判断所有的分片均上传成功?
合成文件的时候如何判断保证合成一个完整的文件而不出错? 多个分片同时上传的时候, 读写文件没有独占锁的时候会导致合成错误.
三, 问题解决
当出现 413 的时候, 修改了 nginx.conf 和 PHP.INI
(1)nginx 中添加 client_max_body_size 和 client_body_buffer_size
(2)PHP.INI 添加 post_max_size 和 upload_max_filesize
重启 nginx 和 PHP-fpm
代码逻辑梳理和分享
(1) 先获取当前分片是第几片以及总共几片
(2) 创建一个文件夹用来存储所有的分片以及合成的文件
(3) 变量 $done 初始为 true, 用来判断是否所有的分片都上传完成, 每个分片保存的时候使用分片序号作为文件名, 然后判断所有的分片文件是否存在
(4) 当 $done===true 的时候, 代表所有分片上传完成, 合成文件.
$target 变量代表合成后的文件名, file_exists 判断是否已经合成成功, 然后追加方式创建打开文件, 循环将每个分片内容写入一个文件中.
在读取每个分片之前先判断当前分片是否存在, 是为了防止多个进程执行合成文件代码块的时候导致某个分片已经写入删除, 最后导致合成的文件是不完整的, 此时需要删除合成的不完整的文件并退出 exit 当前进程.
其中每个分片最好设置独占锁, flock($in, LOCK_EX), 用来保证读写分片的时候其他进程不会操作该分片. 最后删除分片 unlink 以及释放独占锁.
总结
来源: https://www.jb51.net/article/149646.htm