php - jQuery + PHP 多文件拖放上传无法创建缩略图 - 奇怪

标签 php jquery upload drag-and-drop

我们已经为这个烦人的 SCSS 工作了 3 天。希望有人能够提供一些帮助。基本上我正在使用 http://tutorialzine.com/2011/09/html5-file-upload-jquery-php/允许多个文件上传以及常规文件上传输入。该代码的第一部分是复制上传的原始图像。这对双方来说都很好。第二部分用于缩略图,使用拖放脚本时它不起作用,但使用标准上传时它可以完美工作。我假设我的问题不在于这段代码,但我将其包含在内只是为了向您展示。我还将包含几乎所有其他代码,以防您发现它相关且有助于诊断。

    // copying original image to new location with new name
    $prev = file_get_contents($pic['tmp_name']);
    $new = fopen($file, "w");
    fwrite($new, $prev);
    fclose($new);

    //create image for thumbnail
    switch(strtolower($pic['type']))
    {
        case 'image/jpeg':
            $image = imagecreatefromjpeg($pic['tmp_name']);
            break;
        case 'image/png':
            $image = imagecreatefrompng($pic['tmp_name']);
            imagealphablending($image, true); // setting alpha blending on
            imagesavealpha($image, true);
            break;
        case 'image/gif':
            $image = imagecreatefromgif($pic['tmp_name']);
            break;
        default:
            exit('Unsupported type: '.$pic['type']);
    }

    // Target dimensions
    $max_width = 150;
    $max_height = 150;

    // Get current dimensions
    $old_width  = imagesx($image);
    $old_height = imagesy($image);

    // Calculate the scaling we need to do to fit the image inside our frame
    $scale = min($max_width/$old_width, $max_height/$old_height);

    // Get the new dimensions
    $new_width  = ceil($scale*$old_width);
    $new_height = ceil($scale*$old_height);

    // Create new empty image
    $new = imagecreatetruecolor($new_width, $new_height);

    // Resize old image into new
    imagecopyresampled($new, $image, 0, 0, 0, 0, $new_width, $new_height, $old_width, $old_height);

    // Catch the imagedata
    ob_start();
    //create image for thumbnail
    switch(strtolower($pic['type']))
    {
        case 'image/jpeg':
            imagejpeg($new, $_SERVER['DOCUMENT_ROOT']."/".$thumbnail, 90);
            break;
        case 'image/png';
            imagepng($new, $_SERVER['DOCUMENT_ROOT']."/".$thumbnail, 9);
            break;
        case 'image/gif':
            imagegif($new, $_SERVER['DOCUMENT_ROOT']."/".$thumbnail, 9);
            break;
        default:
            exit('Unsupported type: '.$pic['type']);
    }

    chmod($_SERVER['DOCUMENT_ROOT']."/".$thumbnail,0755);

    $data = ob_get_clean();

    // Destroy resources
    imagedestroy($image);
    imagedestroy($new);

HTML

<h1>Upload Image(s)</h1>
<form action='ajax/post_file.php' method='post' enctype="multipart/form-data">
    <input type='file' name='file'><input type='hidden' name='drag_drop' value='yes'><input type='submit' value='go'>
    </form>
        <!-- Our CSS stylesheet file -->
    <link rel="stylesheet" href="ajax/drag_drop_uploads/css/styles.css" />
        <div id="dropbox" style='height: 400px; overflow: auto;'>
        <span class="message">Drop images here to upload. <br /><i>(they will be automatically uploaded to your account)</i></span>
    </div>

处理拖放上传的 JQuery 插件

         (function(jQuery){

jQuery.event.props.push("dataTransfer");
var opts = {},
    default_opts = {
        url: '',
        refresh: 1000,
        paramname: 'userfile',
        maxfiles: 25,
        maxfilesize: 5, // MBs
        data: {},
        drop: empty,
        dragEnter: empty,
        dragOver: empty,
        dragLeave: empty,
        docEnter: empty,
        docOver: empty,
        docLeave: empty,
        beforeEach: empty,
        afterAll: empty,
        rename: empty,
        error: function(err, file, i){alert(err);},
        uploadStarted: empty,
        uploadFinished: empty,
        progressUpdated: empty,
        speedUpdated: empty
    },
    errors = ["BrowserNotSupported", "TooManyFiles", "FileTooLarge"],
    doc_leave_timer,
    stop_loop = false,
    files_count = 0,
    files;

jQuery.fn.filedrop = function(options) {
    opts = jQuery.extend( {}, default_opts, options );

    this.bind('drop', drop).bind('dragenter', dragEnter).bind('dragover', dragOver).bind('dragleave', dragLeave);
    jQuery(document).bind('drop', docDrop).bind('dragenter', docEnter).bind('dragover', docOver).bind('dragleave', docLeave);
};

function drop(e) {
    opts.drop(e);
    files = e.dataTransfer.files;
    if (files === null || files === undefined) {
        opts.error(errors[0]);
        return false;
    }

    files_count = files.length;
    upload();
    e.preventDefault();
    return false;
}

function getBuilder(filename, filedata, boundary) {
    var dashdash = '--',
        crlf = '\r\n',
        builder = '';

    jQuery.each(opts.data, function(i, val) {
        if (typeof val === 'function') val = val();
        builder += dashdash;
        builder += boundary;
        builder += crlf;
        builder += 'Content-Disposition: form-data; name="'+i+'"';
        builder += crlf;
        builder += crlf;
        builder += val;
        builder += crlf;
    });

    builder += dashdash;
    builder += boundary;
    builder += crlf;
    builder += 'Content-Disposition: form-data; name="'+opts.paramname+'"';
    builder += '; filename="' + filename + '"';
    builder += crlf;

    builder += 'Content-Type: application/octet-stream';
    builder += crlf;
    builder += crlf; 

    builder += filedata;
    builder += crlf;

    builder += dashdash;
    builder += boundary;
    builder += dashdash;
    builder += crlf;
    return builder;
}

function progress(e) {
    if (e.lengthComputable) {
        var percentage = Math.round((e.loaded * 100) / e.total);
        if (this.currentProgress != percentage) {

            this.currentProgress = percentage;
            opts.progressUpdated(this.index, this.file, this.currentProgress);

            var elapsed = new Date().getTime();
            var diffTime = elapsed - this.currentStart;
            if (diffTime >= opts.refresh) {
                var diffData = e.loaded - this.startData;
                var speed = diffData / diffTime; // KB per second
                opts.speedUpdated(this.index, this.file, speed);
                this.startData = e.loaded;
                this.currentStart = elapsed;
            }
        }
    }
}



function upload() {
    stop_loop = false;
    if (!files) {
        opts.error(errors[0]);
        return false;
    }
    var filesDone = 0,
        filesRejected = 0;

    if (files_count > opts.maxfiles) {
        opts.error(errors[1]);
        return false;
    }

    for (var i=0; i<files_count; i++) {
        if (stop_loop) return false;
        try {
            if (beforeEach(files[i]) != false) {
                if (i === files_count) return;
                var reader = new FileReader(),
                    max_file_size = 1048576 * opts.maxfilesize;

                reader.index = i;
                if (files[i].size > max_file_size) {
                    opts.error(errors[2], files[i], i);
                    filesRejected++;
                    continue;
                }

                reader.onloadend = send;
                reader.readAsBinaryString(files[i]);
            } else {
                filesRejected++;
            }
        } catch(err) {
            opts.error(errors[0]);
            return false;
        }
    }

    function send(e) {
        // Sometimes the index is not attached to the
        // event object. Find it by size. Hack for sure.
        if (e.target.index == undefined) {
            e.target.index = getIndexBySize(e.total);
        }

        var xhr = new XMLHttpRequest(),
            upload = xhr.upload,
            file = files[e.target.index],
            index = e.target.index,
            start_time = new Date().getTime(),
            boundary = '------multipartformboundary' + (new Date).getTime(),
            builder;

        newName = rename(file.name);
        if (typeof newName === "string") {
            builder = getBuilder(newName, e.target.result, boundary);
        } else {
            builder = getBuilder(file.name, e.target.result, boundary);
        }

        upload.index = index;
        upload.file = file;
        upload.downloadStartTime = start_time;
        upload.currentStart = start_time;
        upload.currentProgress = 0;
        upload.startData = 0;
        upload.addEventListener("progress", progress, false);

        xhr.open("POST", opts.url, true);
        xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' 
            + boundary);

        xhr.sendAsBinary(builder);  

        opts.uploadStarted(index, file, files_count);  

        xhr.onload = function() { 
            if (xhr.responseText) {
            var now = new Date().getTime(),
                timeDiff = now - start_time,
                result = opts.uploadFinished(index, file, jQuery.parseJSON(xhr.responseText), timeDiff);
                filesDone++;
                if (filesDone == files_count - filesRejected) {
                    afterAll();
                }
            if (result === false) stop_loop = true;
            }
        };
    }
}

function getIndexBySize(size) {
    for (var i=0; i < files_count; i++) {
        if (files[i].size == size) {
            return i;
        }
    }

    return undefined;
}

function rename(name) {
    return opts.rename(name);
}

function beforeEach(file) {
    return opts.beforeEach(file);
}

function afterAll() {
    return opts.afterAll();
}

function dragEnter(e) {
    clearTimeout(doc_leave_timer);
    e.preventDefault();
    opts.dragEnter(e);
}

function dragOver(e) {
    clearTimeout(doc_leave_timer);
    e.preventDefault();
    opts.docOver(e);
    opts.dragOver(e);
}

function dragLeave(e) {
    clearTimeout(doc_leave_timer);
    opts.dragLeave(e);
    e.stopPropagation();
}

function docDrop(e) {
    e.preventDefault();
    opts.docLeave(e);
    return false;
}

function docEnter(e) {
    clearTimeout(doc_leave_timer);
    e.preventDefault();
    opts.docEnter(e);
    return false;
}

function docOver(e) {
    clearTimeout(doc_leave_timer);
    e.preventDefault();
    opts.docOver(e);
    return false;
}

function docLeave(e) {
    doc_leave_timer = setTimeout(function(){
        opts.docLeave(e);
    }, 200);
}

function empty(){}

try {
    if (XMLHttpRequest.prototype.sendAsBinary) return;
    XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
        function byteValue(x) {
            return x.charCodeAt(0) & 0xff;
        }
        var ords = Array.prototype.map.call(datastr, byteValue);
        var ui8a = new Uint8Array(ords);
        this.send(ui8a.buffer);
    }
} catch(e) {}

    })(jQuery);

插件调用的 JQuery

     jQuery(function(){

var dropbox = jQuery('#dropbox'),
    message = jQuery('.message', dropbox);

dropbox.filedrop({
    // The name of the jQuery_FILES entry:
    paramname:'file',

    maxfiles: 25,
    maxfilesize: 5,
    url: 'ajax/post_file.php',

    uploadFinished:function(i,file,response){
        jQuery.data(file).addClass('done');
        // response is the JSON object that post_file.php returns
    },

    error: function(err, file) {
        switch(err) {
            case 'BrowserNotSupported':
                showMessage('Your browser does not support HTML5 file uploads!');
                break;
            case 'TooManyFiles':
                alert('Too many files! Please select 5 at most! (configurable)');
                break;
            case 'FileTooLarge':
                alert(file.name+' is too large! Please upload files up to 2mb (configurable).');
                break;
            default:
                break;
        }
    },

    // Called before each upload is started
    beforeEach: function(file){
        if(!file.type.match(/^image\//)){
            alert('Only images are allowed!');

            // Returning false will cause the
            // file to be rejected
            return false;
        }
    },

    uploadStarted:function(i, file, len){
        createImage(file);
    },

    progressUpdated: function(i, file, progress) {
        jQuery.data(file).find('.progress').width(progress);
    }

});

var template = '<div class="preview">'+
                    '<span class="imageHolder">'+
                        '<img />'+
                        '<span class="uploaded"></span>'+
                    '</span>'+
                    '<div class="progressHolder">'+
                        '<div class="progress"></div>'+
                    '</div>'+
                '</div>'; 


function createImage(file){

    var preview = jQuery(template), 
        image = jQuery('img', preview);

    var reader = new FileReader();

    image.width = 100;
    image.height = 100;

    reader.onload = function(e){

        // e.target.result holds the DataURL which
        // can be used as a source of the image:

        image.attr('src',e.target.result);
    };

    // Reading the file as a DataURL. When finished,
    // this will trigger the onload function above:
    reader.readAsDataURL(file);

    message.hide();
    preview.appendTo(dropbox);

    // Associating a preview container
    // with the file, using jQuery's jQuery.data():

    jQuery.data(file,preview);
}

function showMessage(msg){
    message.html(msg);
}

    });

他们给我的 PHP 示例

       $demo_mode = false;
       $upload_dir = 'ajax/uploads/';
       $allowed_ext = array('jpg','jpeg','png','gif');


      if(strtolower($_SERVER['REQUEST_METHOD']) != 'post'){
  exit_status('Error! Wrong HTTP method!');
      }


    if(array_key_exists('pic',$_FILES) && $_FILES['pic']['error'] == 0 ){

$pic = $_FILES['pic'];

if(!in_array(get_extension($pic['name']),$allowed_ext)){
    exit_status('Only '.implode(',',$allowed_ext).' files are allowed!');
}   

if($demo_mode){

    // File uploads are ignored. We only log them.

    $line = implode('       ', array( date('r'), $_SERVER['REMOTE_ADDR'],          
            $pic['size'], $pic['name']));
    file_put_contents('log.txt', $line.PHP_EOL, FILE_APPEND);

    exit_status('Uploads are ignored in demo mode.');
        }


// Move the uploaded file from the temporary 
// directory to the uploads folder:

if(move_uploaded_file($pic['tmp_name'], $upload_dir.$pic['name'])){
    exit_status('File was uploaded successfuly!');
}

    }

    exit_status('Something went wrong with your upload!');


     // Helper functions

     function exit_status($str){
 echo json_encode(array('status'=>$str));
 exit;
     }

    function get_extension($file_name){
$ext = explode('.', $file_name);
$ext = array_pop($ext);
return strtolower($ext);
     }

最佳答案

正如 OP 评论中所讨论的;

文件上传示例似乎未正确填充文件类型,导致命中交换机的 default block (exit)

顺便说一句,您可能希望将其交换为引发异常,以便将来您会在日志中看到有用的内容

关于php - jQuery + PHP 多文件拖放上传无法创建缩略图 - 奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11456091/

相关文章:

php获取图像名称并添加到数据库?

javascript - 检测特定图像何时完成加载

javascript - 使用 Javascript 上传多个文件

php - 使用 session ID 在 CodeIgniter 中进行 MySQL 查询

php - 我有一个返回旧记录的 MySQL 日期格式

jquery - 制作动画时让一个 div 覆盖另一个

javascript - 使用jquery更改标签的属性

php - 将 CSV 导入 MySQL Workbench,其中文本字段包含数据换行符

websocket - Django channel 文件/图片上传

Php mysqli_fetch_array 不起作用