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 相关文章推荐
PHP数据流应用的一个简单实例
Sep 14 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
Jan 11 PHP
windows环境下php配置memcache的具体操作步骤
Jun 09 PHP
一个好用的PHP验证码类实例分享
Dec 27 PHP
php使用Cookie实现和用户会话的方法
Jan 21 PHP
php抛出异常与捕捉特定类型的异常详解
Oct 26 PHP
php查询及多条件查询
Feb 26 PHP
PHP实现的数独求解问题示例
Apr 18 PHP
PHP实现时间比较和时间差计算的方法示例
Jul 24 PHP
总结PHP代码规范、流程规范、git规范
Jun 18 PHP
PHP的mysqli_stat()函数讲解
Jan 23 PHP
聊聊 PHP 8 新特性 Attributes
Aug 19 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
ThinkPHP做文字水印时提示call an undefined function exif_imagetype()解决方法
2014/10/30 PHP
通过php修改xml文档内容的方法
2015/01/23 PHP
php制作动态随机验证码
2015/02/12 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
IE关闭时判断及AJAX注销案例学习
2013/02/18 Javascript
node.js中的querystring.parse方法使用说明
2014/12/10 Javascript
js与css实现弹出层覆盖整个页面的方法
2014/12/13 Javascript
基于javascript实现句子翻牌网页版小游戏
2016/03/23 Javascript
JavaScript获取当前url根目录(路径)
2016/06/17 Javascript
JavaScript中从setTimeout与setInterval到AJAX异步
2017/02/13 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
JS字符串常用操作方法实例小结
2019/06/24 Javascript
SSM+layUI 根据登录信息显示不同的页面方法
2019/09/20 Javascript
webpack常用构建优化策略小结
2019/11/21 Javascript
使用JS location实现搜索框历史记录功能
2019/12/23 Javascript
vue中实现回车键登录功能
2020/02/19 Javascript
JavaScript实现动态留言板
2020/03/16 Javascript
vue + el-form 实现的多层循环表单验证
2020/11/25 Vue.js
使用IPython下的Net-SNMP来管理类UNIX系统的教程
2015/04/15 Python
浅谈python中的getattr函数 hasattr函数
2016/06/14 Python
用python实现简单EXCEL数据统计的实例
2017/01/24 Python
python实现各进制转换的总结大全
2017/06/18 Python
python实现猜数字小游戏
2020/03/24 Python
Scrapy框架爬取西刺代理网免费高匿代理的实现代码
2019/02/22 Python
Python微信操控itchat的方法
2019/05/31 Python
django中的图片验证码功能
2019/09/18 Python
Python input函数使用实例解析
2019/11/22 Python
关于Keras Dense层整理
2020/05/21 Python
Python 利用OpenCV给照片换底色的示例代码
2020/08/03 Python
Python 解析xml文件的示例
2020/09/29 Python
Tretorn美国官网:瑞典外套和鞋类品牌,抵御风雨
2018/07/19 全球购物
人事行政主管岗位职责
2013/12/22 职场文书
联谊活动策划书
2014/01/26 职场文书
实验室的标语
2014/06/20 职场文书
毕业生入职感言
2015/07/31 职场文书
springboot 自定义配置 解决Boolean属性不生效
2022/03/18 Java/Android