php+resumablejs实现的分块上传 断点续传功能示例
程序员文章站
2024-03-31 19:47:10
本文实例讲述了php+resumablejs实现的分块上传 断点续传功能。分享给大家供大家参考,具体如下:
resumablejs官网
本站。
upload.htm...
本文实例讲述了php+resumablejs实现的分块上传 断点续传功能。分享给大家供大家参考,具体如下:
resumablejs官网
本站。
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网络编程技巧总结》、《php面向对象程序设计入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》
希望本文所述对大家php程序设计有所帮助。
上一篇: Equals和==的区别 公共变量和属性的区别小结
下一篇: Java中的泛型方法详解及简单实例