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代码
Dec 06 PHP
php中用文本文件做数据库的实现方法
Mar 27 PHP
file_get_contents获取不到网页内容的解决方法
Mar 07 PHP
解析php做推送服务端实现ios消息推送
Jul 01 PHP
php中hashtable实现示例分享
Feb 13 PHP
PHP中的switch语句的用法实例详解
Oct 21 PHP
ThinkPHP设置禁止百度等搜索引擎转码(简单实用)
Feb 15 PHP
Thinkphp和onethink实现微信支付插件
Apr 13 PHP
php编程实现简单的网页版计算器功能示例
Apr 26 PHP
laravel实现按时间日期进行分组统计方法示例
Mar 23 PHP
Laravel 自带的Auth验证登录方法
Sep 30 PHP
在Laravel 中实现是否关注的示例
Oct 22 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生成随机密码的几种方法
2011/01/17 PHP
PHP中PDO基础教程 入门级
2011/09/04 PHP
PHP数组式访问接口ArrayAccess用法分析
2017/12/28 PHP
php中对象引用和复制实例分析
2019/08/14 PHP
PHP常用函数之根据生日计算年龄功能示例
2019/10/21 PHP
javascript数组去重3种方法的性能测试与比较
2013/03/26 Javascript
jquery easyui滚动条部分设置介绍
2013/09/12 Javascript
javascript检查浏览器是否支持flash的实现代码
2014/08/14 Javascript
jQuery中ajax和post处理json的不同示例对比
2014/11/02 Javascript
AngularJS身份验证的方法
2016/02/17 Javascript
js获取当前年月日-YYYYmmDD格式的实现代码
2016/06/01 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
2016/07/25 Javascript
简单谈谈require模块化jquery和angular的问题
2017/06/23 jQuery
electron实现静默打印的示例代码
2019/08/12 Javascript
node.js express框架实现文件上传与下载功能实例详解
2019/10/15 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
2019/11/13 Javascript
探究一道价值25k的蚂蚁金服异步串行面试题
2020/08/21 Javascript
[03:02]2020完美世界城市挑战赛(秋季赛)总决赛回顾
2021/03/11 DOTA
Python中的localtime()方法使用详解
2015/05/22 Python
python 对txt中每行内容进行批量替换的方法
2018/07/11 Python
python获取交互式ssh shell的方法
2019/02/14 Python
python Django 创建应用过程图示详解
2019/07/29 Python
numpy中的meshgrid函数的使用
2019/07/31 Python
HTML5 Canvas 实现圆形进度条并显示数字百分比效果示例
2017/08/18 HTML / CSS
Mixbook加拿大:照片书,照片卡,剪贴簿,年历和日历
2017/02/21 全球购物
波兰在线运动商店:YesSport
2020/07/23 全球购物
中兴通讯全球官方网站:ZTE
2020/12/26 全球购物
一道SQL面试题
2012/12/31 面试题
医学生自荐信
2013/12/03 职场文书
学校党员干部承诺书
2015/05/04 职场文书
煤矿安全生产工作总结
2015/08/13 职场文书
导游词之沈阳植物园
2019/11/30 职场文书
52条SQL语句教你性能优化
2021/05/25 MySQL
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis
html粘性页脚的具体使用
2022/01/18 HTML / CSS
零基础学java之带参数以及返回值的方法
2022/04/10 Java/Android