php+resumablejs实现的分块上传 断点续传功能示例


Posted in PHP onApril 18, 2017

本文实例讲述了php+resumablejs实现的分块上传 断点续传功能。分享给大家供大家参考,具体如下:

resumablejs官网 http://www.resumablejs.com/

本站下载地址。

upload.html

<!DOCTYPE html>
<html lang="en">
<div>
 <a href="#" rel="external nofollow" id="browseButton" >Select files</a>
<div>
<div>
<input id="btnCancel" type="button" onClick='r.pause()'value="Cancel All Uploads" 
 style="margin-left: 2px; height: 22px; font-size: 8pt;" />
   <br />
</div>
<script src="resumable.js"></script>
<script>
var r = new Resumable({
 target:'upload.php',
 chunkSize:2*1024*1024,
 simultaneousUploads:4,
 testChunks:true,
 throttleProgressCallbacks:1,
});
r.assignBrowse(document.getElementById('browseButton'));
r.on('fileSuccess', function(file){
 // console.debug(file);
 });
r.on('fileProgress', function(file){
 // console.debug(file);
 });
r.on('fileAdded', function(file, event){
 r.upload();
 //console.debug(file, event);
 });
r.on('fileRetry', function(file){
 //console.debug(file);
 });
r.on('fileError', function(file, message){
 //console.debug(file, message);
 });
r.on('uploadStart', function(){
 //console.debug();
 });
r.on('complete', function(){
 //console.debug();
 });
r.on('progress', function(){
 //console.debug();
 });
r.on('error', function(message, file){
 //console.debug(message, file);
 });
r.on('pause', function(file,message){
 //console.debug();
 });
r.on('cancel', function(){
 //console.debug();
 });
</script>
</html>

upload.php

<?php
/**
 * This is the implementation of the server side part of
 * Resumable.js client script, which sends/uploads files
 * to a server in several chunks.
 *
 * The script receives the files in a standard way as if
 * the files were uploaded using standard HTML form (multipart).
 *
 * This PHP script stores all the chunks of a file in a temporary
 * directory (`temp`) with the extension `_part<#ChunkN>`. Once all 
 * the parts have been uploaded, a final destination file is
 * being created from all the stored parts (appending one by one).
 *
 * @author Gregory Chris (http://online-php.com)
 * @email www.online.php@gmail.com
 */
////////////////////////////////////////////////////////////////////
// THE FUNCTIONS
////////////////////////////////////////////////////////////////////
/**
 *
 * Logging operation - to a file (upload_log.txt) and to the stdout
 * @param string $str - the logging string
 */
function _log($str) {
 // log to the output
 $log_str = date('d.m.Y').": {$str}\r\n";
 echo $log_str;
 // log to file
 if (($fp = fopen('upload_log.txt', 'a+')) !== false) {
  fputs($fp, $log_str);
  fclose($fp);
 }
}
/**
 * 
 * Delete a directory RECURSIVELY
 * @param string $dir - directory path
 * @link http://php.net/manual/en/function.rmdir.php
 */
function rrmdir($dir) {
 if (is_dir($dir)) {
  $objects = scandir($dir);
  foreach ($objects as $object) {
   if ($object != "." && $object != "..") {
    if (filetype($dir . "/" . $object) == "dir") {
     rrmdir($dir . "/" . $object); 
    } else {
     unlink($dir . "/" . $object);
    }
   }
  }
  reset($objects);
  rmdir($dir);
 }
}
/**
 *
 * Check if all the parts exist, and 
 * gather all the parts of the file together
 * @param string $dir - the temporary directory holding all the parts of the file
 * @param string $fileName - the original file name
 * @param string $chunkSize - each chunk size (in bytes)
 * @param string $totalSize - original file size (in bytes)
 */
function createFileFromChunks($temp_dir, $fileName, $chunkSize, $totalSize) {
 // count all the parts of this file
 $total_files = 0;
 foreach(scandir($temp_dir) as $file) {
  if (stripos($file, $fileName) !== false) {
   $total_files++;
  }
 }
 // check that all the parts are present
 // the size of the last part is between chunkSize and 2*$chunkSize
 if ($total_files * $chunkSize >= ($totalSize - $chunkSize + 1)) {
  // create the final destination file 
  if (($fp = fopen('temp/'.$fileName, 'w')) !== false) {
   for ($i=1; $i<=$total_files; $i++) {
    fwrite($fp, file_get_contents($temp_dir.'/'.$fileName.'.part'.$i));
    _log('writing chunk '.$i);
   }
   fclose($fp);
  } else {
   _log('cannot create the destination file');
   return false;
  }
  // rename the temporary directory (to avoid access from other 
  // concurrent chunks uploads) and than delete it
  if (rename($temp_dir, $temp_dir.'_UNUSED')) {
   rrmdir($temp_dir.'_UNUSED');
  } else {
   rrmdir($temp_dir);
  }
 }
}
////////////////////////////////////////////////////////////////////
// THE SCRIPT
////////////////////////////////////////////////////////////////////
//check if request is GET and the requested chunk exists or not. this makes testChunks work
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
 $temp_dir = 'temp/'.$_GET['resumableIdentifier'];
 $chunk_file = $temp_dir.'/'.$_GET['resumableFilename'].'.part'.$_GET['resumableChunkNumber'];
 if (file_exists($chunk_file)) {
   header("HTTP/1.0 200 Ok");
  } else
  {
   header("HTTP/1.0 404 Not Found");
  }
 }
// loop through files and move the chunks to a temporarily created directory
if (!empty($_FILES)) foreach ($_FILES as $file) {
 // check the error status
 if ($file['error'] != 0) {
  _log('error '.$file['error'].' in file '.$_POST['resumableFilename']);
  continue;
 }
 // init the destination file (format <filename.ext>.part<#chunk>
 // the file is stored in a temporary directory
 $temp_dir = 'temp/'.$_POST['resumableIdentifier'];
 $dest_file = $temp_dir.'/'.$_POST['resumableFilename'].'.part'.$_POST['resumableChunkNumber'];
 // create the temporary directory
 if (!is_dir($temp_dir)) {
  mkdir($temp_dir, 0777, true);
 }
 // move the temporary file
 if (!move_uploaded_file($file['tmp_name'], $dest_file)) {
  _log('Error saving (move_uploaded_file) chunk '.$_POST['resumableChunkNumber'].' for file '.$_POST['resumableFilename']);
 } else {
  // check if all the parts present, and create the final destination file
  createFileFromChunks($temp_dir, $_POST['resumableFilename'], 
    $_POST['resumableChunkSize'], $_POST['resumableTotalSize']);
 }
}

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
phpfans留言版用到的install.php
Jan 04 PHP
Ajax+PHP 边学边练 之二 实例
Nov 24 PHP
七款最流行的PHP本地服务器分享
Feb 19 PHP
php实现登录tplink WR882N获取IP和重启的方法
Jul 20 PHP
php 获取文件行数的方法总结
Oct 11 PHP
php使用PDO事务配合表格读取大量数据插入操作实现方法
Feb 16 PHP
php检查函数必传参数是否存在的实例详解
Aug 28 PHP
PHP 获取 ping 时间的实现方法
Sep 29 PHP
PHP的mysqli_set_charset()函数讲解
Jan 23 PHP
PHP设计模式之策略模式原理与用法实例分析
Apr 04 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
Oct 30 PHP
PHP超全局变量实现原理及代码解析
Sep 01 PHP
ZendFramework2连接数据库操作实例
Apr 18 #PHP
PHP实现的数独求解问题示例
Apr 18 #PHP
PHP使用finfo_file()函数检测上传图片类型的实现方法
Apr 18 #PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
Apr 18 #PHP
基于thinkPHP3.2实现微信接入及查询token值的方法
Apr 18 #PHP
PHP递归删除多维数组中的某个值
Apr 17 #PHP
Thinkphp5.0自动生成模块及目录的方法详解
Apr 17 #PHP
You might like
PHP 开发工具
2006/12/06 PHP
落伍首发 php+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
2006/12/16 PHP
在PHP中使用curl_init函数的说明
2010/11/02 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
destoon实现VIP排名一直在前面排序的方法
2014/08/21 PHP
PHP实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
php操作(删除,提取,增加)zip文件方法详解
2015/03/12 PHP
php实现支持中文的文件下载功能示例
2017/08/30 PHP
Aster vs Newbee BO5 第一场2.19
2021/03/10 DOTA
JS页面延迟执行一些方法(整理)
2013/11/11 Javascript
Node.js文件操作详解
2014/08/16 Javascript
JavaScript检查弹出窗口是否被阻拦的方法技巧
2015/03/13 Javascript
javascript检测移动设备横竖屏
2016/05/21 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
详解几十行代码实现一个vue的状态管理
2019/01/28 Javascript
微信小程序实现图片选择并预览功能
2019/07/25 Javascript
javascript中的闭包概念与用法实践分析
2019/07/26 Javascript
js cavans实现静态滚动弹幕
2020/05/21 Javascript
python批量制作雷达图的实现方法
2016/07/26 Python
利用Python爬取可用的代理IP
2016/08/18 Python
wx.CheckBox创建复选框控件并响应鼠标点击事件
2018/04/25 Python
python爬虫实例详解
2018/06/19 Python
python递归法解决棋盘分割问题
2019/07/17 Python
Pytorch 多维数组运算过程的索引处理方式
2019/12/27 Python
html5通过postMessage进行跨域通信的方法
2017/12/04 HTML / CSS
New Balance德国官方网站:购买鞋子和服装
2019/08/31 全球购物
override和overload的区别
2016/03/09 面试题
社区工作者思想汇报
2014/01/13 职场文书
计算机科学系职业生涯规划书
2014/03/08 职场文书
2014年教师党员自我评价范文
2014/09/22 职场文书
公安交警中队队长个人对照检查材料思想汇报
2014/10/05 职场文书
导师工作推荐信
2015/03/27 职场文书
Nginx 过滤静态资源文件的访问日志的实现
2021/03/31 Servers
MYSQL如何查看操作日志详解
2022/05/30 MySQL
Android开发手册TextInputLayout样式使用示例
2022/06/10 Java/Android
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL