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 和 MySQL 基础教程(三)
Oct 09 PHP
PHP重定向的3种方式
Mar 07 PHP
腾讯QQ微博API接口获取微博内容
Oct 30 PHP
php三维数组去重(示例代码)
Nov 26 PHP
老生常谈PHP位运算的用途
Mar 12 PHP
Yii2汉字转拼音类的实例代码
Apr 18 PHP
PHP7扩展开发教程之Hello World实现方法示例
Aug 03 PHP
php微信开发之图片回复功能
Jun 14 PHP
PHP defined()函数的使用图文详解
Jul 20 PHP
PHP实现数组根据某个字段进行水平合并,横向合并案例分析
Oct 08 PHP
laravel解决迁移文件一次删除创建字段报错的问题
Oct 24 PHP
thinkphp框架表单数组实现图片批量上传功能示例
Apr 04 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 rsa加密解密使用方法
2015/04/27 PHP
ThinkPHP表单数据智能写入create方法实例分析
2015/09/27 PHP
php根据数据id自动生成编号的实现方法
2016/10/16 PHP
Thinkphp5.0自动生成模块及目录的方法详解
2017/04/17 PHP
ThinkPHP3.2.3框架Memcache缓存使用方法实例总结
2019/04/15 PHP
通过Unicode转义序列来加密,按你说的可以算是混淆吧
2007/05/06 Javascript
jQuery timers计时器简单应用说明
2010/10/28 Javascript
jquery分割字符串的方法
2015/06/24 Javascript
jQuery返回定位插件详解
2017/05/15 jQuery
基于AngularJS的简单使用详解
2017/09/10 Javascript
使用svg实现动态时钟效果
2018/07/17 Javascript
JavaScript中call和apply方法的区别实例分析
2018/08/03 Javascript
vue axios请求频繁时取消上一次请求的方法
2018/11/10 Javascript
JS/jQuery实现超简单的Table表格添加,删除行功能示例
2019/07/31 jQuery
JavaScript适配器模式原理与用法实例详解
2020/03/09 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
教你如何在Django 1.6中正确使用 Signal
2014/06/22 Python
python基础练习之几个简单的游戏
2017/11/10 Python
Python使用百度翻译开发平台实现英文翻译为中文功能示例
2019/08/08 Python
python3利用Axes3D库画3D模型图
2020/03/25 Python
如何将Pycharm中调整字体大小的方式设置为&quot;ctrl+鼠标滚轮上下滑&quot;
2020/11/17 Python
AmazeUI中各种的导航式菜单与解决方法
2020/08/19 HTML / CSS
新西兰领先的鞋类和靴子网上商城:Merchant 1948
2017/09/08 全球购物
linux面试题参考答案(2)
2015/12/06 面试题
告诉你怎样写创业计划书
2014/01/27 职场文书
教师学习培训邀请函
2014/02/04 职场文书
政府采购方案
2014/06/12 职场文书
学党史心得体会
2014/09/05 职场文书
基层工作经历证明
2015/06/19 职场文书
2015年团委副书记工作总结
2015/07/23 职场文书
会计继续教育培训心得体会
2016/01/19 职场文书
2016年禁毒宣传活动总结
2016/04/05 职场文书
python-for x in range的用法(注意要点、细节)
2021/05/10 Python
解决Pytorch半精度浮点型网络训练的问题
2021/05/24 Python
python如何利用cv2模块读取显示保存图片
2021/06/04 Python
css实现两栏布局,左侧固定宽,右侧自适应的多种方法
2021/08/07 HTML / CSS