我正在尝试使用dropzone js和php正确实现块上传。我主要关心的是:我应该在哪里进行ajax调用?通常(没有任何块),您只需指定URL参数。但是,对于块来说,这还不够,我想,因为将只有1个ajax调用,但是理想情况下,块将是几个,我们必须等待全部,然后再用php重新组装整个文件。因此,以您的经验,执行ajax调用或在哪里调用的正确位置是什么? (也许这是只打一个电话的方法吗?)。这是我当前代码的简单摘录:
window['dropzone' + panel_index] = new Dropzone(
selector,
{
url: ajax_url + '?action=uploadfile'
,addRemoveLinks: true
,maxFiles: 5
,maxFilesize: maxfilesize
,uploadMultiple:false
,parallelUploads: 1
,chunking:true
,forceChunking:true
,chunkSize:10485760 // 10Mb
,retryChunks: true // retry chunks on failure
,retryChunksLimit: 3
,chunksUploaded:function(file, done){
// called only once, when chunks are finished > do something ajax > php to reassemble the file?
done();
}
,params: function(file, xhr, chunk){
// called once per every chunk > do something ajax > php?
if(chunk){
$.extend(true, p, {
dzuuid: chunk.file.upload.uuid,
dzchunkindex: chunk.index,
dztotalfilesize: chunk.file.size,
dzchunksize: this.options.chunkSize,
dztotalchunkcount: chunk.file.upload.totalChunkCount,
dzchunkbyteoffset: chunk.index * this.options.chunkSize
});
}
return p;
}// params
,init: function(){
this.on('success', function(newfile){
// called after chunksUploaded > do something ajax > php?
});// onsuccess
this.on('uploadprogress', function(file, progress, bytesent){
// called continuously
})
}// dropzone init option
}// dropzone options
);
答案 0 :(得分:0)
简而言之,服务方块处理所需的唯一回调是传递给params
的函数。这样的东西(摘录自我的代码):
,params: function(files, xhr, chunk){
var p = { // $_POST
app_type: 'configurator'
,app_code: manager.code
,file_types: filetypes
,max_filesize: maxfilesize
,upf: upf
}
if(chunk){
$.extend(true, p, {
dzuuid: chunk.file.upload.uuid,
dzchunkindex: chunk.index,
dztotalfilesize: chunk.file.size,
dzchunksize: this.options.chunkSize,
dztotalchunkcount: chunk.file.upload.totalChunkCount,
dzchunkbyteoffset: chunk.index * this.options.chunkSize
});
}
return p;
}// params
被调用的url只是一般dropzone的url参数。每块调用一次。
例如,在php中,您可以使用$ _POST ['dzchunkindex']保存名称已修改的块。
// do all the sanitisation tasks, then:
$target_chunk = $this->target_path . DS . $filename . $chunk_index;
// and then do the file saving tasks
在处理完所有块之后,您将拥有与服务器上的块一样多的文件。然后,在同一函数上,检查块索引是否像dztotalchunkcount - 1
一样(在其他情况下,如果当前块是最后一个),并且在这种情况下,还将所有块合并到一个文件中。示例:
if($chunk_index == $total_chunks - 1){
$final = fopen($target_file, 'wb'); // Open for write and start from beginning of file
for ($i = 0; $i < $total_chunks; $i++) {
$file = fopen($target_file.$i, 'rb');
while($buff = fread($file, 4096)){ fwrite($final, $buff); }
fclose($file);
unlink($target_file.$i);
}
fclose($final);
}
答案 1 :(得分:0)
我正在chunksUploaded
选项中执行此操作。在Dropzone为我上传了所有块之后,我在chunksUploaded
内执行了另一个ajax调用,该调用与我的上传器连接到一个单独的PHP脚本,该脚本连接了所有上传的文件。
因此,每个块上传均调用与PHP中的块上传相同的Dropzone网址:
<?php
/* ========================================
VARIABLES
======================================== */
// chunk variables
$fileId = $_POST['dzuuid'];
$chunkIndex = $_POST['dzchunkindex'] + 1;
$chunkTotal = $_POST['dztotalchunkcount'];
// file path variables
$ds = DIRECTORY_SEPARATOR;
$targetPath = dirname( __FILE__ ) . "{$ds}uploads{$ds}";
$fileType = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
$fileSize = $_FILES["file"]["size"];
$filename = "{$fileId}-{$chunkIndex}.{$fileType}";
$targetFile = $targetPath . $filename;
/* ========================================
DEPENDENCY FUNCTIONS
======================================== */
$returnResponse = function ($info = null, $filelink = null, $status = "error") {
die (json_encode( array(
"status" => $status,
"info" => $info,
"file_link" => $filelink
)));
};
/* ========================================
VALIDATION CHECKS
======================================== */
// I deleted a bunch of validation that goes here to keep the code short
/* ========================================
CHUNK UPLOAD
======================================== */
move_uploaded_file($_FILES['file']['tmp_name'], $targetFile);
// Be sure that the file has been uploaded
if ( !file_exists($targetFile) ) $returnResponse("An error occurred and we couldn't upload the requested file.");
chmod($targetFile, 0777) or $returnResponse("Could not reset permissions on uploaded chunk.");
$returnResponse(null, null, "success");
然后,chunksUploaded对串联php脚本执行另一个ajax调用(注意,我如何使用放置区上传ID作为序列来识别哪些文件块属于一起):
<?php
// get variables
$fileId = $_GET['dzuuid'];
$chunkTotal = $_GET['dztotalchunkcount'];
// file path variables
$ds = DIRECTORY_SEPARATOR;
$targetPath = dirname( __FILE__ ) . "{$ds}uploads{$ds}";
//$fileType = strtolower(pathinfo($_GET['fileName'], PATHINFO_EXTENSION));
$fileType = $_GET['fileName'];
/* ========================================
DEPENDENCY FUNCTIONS
======================================== */
$returnResponse = function ($info = null, $filelink = null, $status = "error") {
die (json_encode( array(
"status" => $status,
"info" => $info,
"file_link" => $filelink
)));
};
/* ========================================
CONCATENATE UPLOADED FILES
======================================== */
// loop through temp files and grab the content
for ($i = 1; $i <= $chunkTotal; $i++) {
// target temp file
$temp_file_path = realpath("{$targetPath}{$fileId}-{$i}.{$fileType}") or $returnResponse("Your chunk was lost mid-upload.");
// copy chunk
$chunk = file_get_contents($temp_file_path);
if ( empty($chunk) ) $returnResponse("Chunks are uploading as empty strings.");
// add chunk to main file
file_put_contents("{$targetPath}{$fileId}.{$fileType}", $chunk, FILE_APPEND | LOCK_EX);
// delete chunk
unlink($temp_file_path);
if ( file_exists($temp_file_path) ) $returnResponse("Your temp files could not be deleted.");
}
// and by the time you get here you should have your concatenated file in the "uploads" folder to do with what you want