plupload支持技術: 1:Flash 2:Gears 3:HTML 5 4:Silverlight 5:BrowserPlus 6:HTML 4
plupload主要功能:
1:突破HTTP上傳限制,可上傳大文件,官方論壇中有討論上傳2G文件的應用。
2:多文件隊列上傳
3:圖片自動生成縮略圖
4:上傳后自動生成唯一文件名
5:自定制UI
由于plupload 確實是一個功能比較強大的組件所以無法一一介紹所有功能特色,這里主要就網站開發中plupload上傳大文件的問題進行思路與代碼的解析 。
大文件上傳思路:plupload的上傳思路是將一個較大的文件分成多個小塊進行上傳從而達到突破服務器上傳限制的目的。這估計也是唯一的方法了,但本人測試過程中根據虛擬主機差異分塊上傳時對于可能會出現塊數太多中斷的原因,但這肯定是服務器的配置問題,更換服務器后該問題解決,也就是說大部分服務器均沒有問題的。
下載最新版本后按照官方DEMO進行安裝。
JS參數配置說明:
~~~
<script type="text/javascript">
$(function() {
$("#uploader").pluploadQueue({
runtimes : 'gears,flash,silverlight,browserplus,html5', // 這里是說用什么技術引擎,由于國內瀏覽器問題這里一般使用flash即可。其他的刪除掉。
url : 'upload.php', // 服務端上傳路徑
max_file_size : '10mb', // 文件上傳最大限制。
chunk_size : '1mb', // 上傳分塊每塊的大小,這個值小于服務器最大上傳限制的值即可。(文件總大小/chunk_size = 分塊數)。
unique_names : true, // 上傳的文件名是否唯一
resize : {width : 320, height : 240, quality : 90}, // 是否生成縮略圖(僅對圖片文件有效)。
filters : [
{title : "Image files", extensions : "jpg,gif,png"},
{title : "Zip files", extensions : "zip"}
], // 這個數組是選擇器,就是上傳文件時限制的上傳文件類型
flash_swf_url : '/plupload/js/plupload.flash.swf', // plupload.flash.swf 的所在路徑
silverlight_xap_url : '/plupload/js/plupload.silverlight.xap' // silverlight所在路徑
});
// 這一塊主要是防止在上傳未結束前表帶單提交,具體大家可酌情修改編寫
$('form').submit(function(e) {
var uploader = $('#uploader').pluploadQueue(); // 取得上傳隊列
if (uploader.files.length > 0) { // 就是說如果上傳隊列中還有文件
uploader.bind('StateChanged', function() {
if (uploader.files.length === (uploader.total.uploaded + uploader.total.failed)) {
$('form')[0].submit();
}
});
uploader.start();
} else {
alert('You must queue at least one file.');
}
return false;
});
});
</script>
~~~
由于參數過多大家可以到官方網站查看API參數說明。
服務端代碼說明:
官方自帶了PHP版本的DEMO文件。大家一定要參考這個DEMO進行編寫或者直接使用。在此我簡單的做一下官方upload.php的注釋說明。
~~~
<?php
// HTTP headers for no cache etc 頭部沒有緩存
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
//上傳路徑
$targetDir = 'uploads/';
// 腳本執行時間
@set_time_limit(5 * 60);
// 延遲
// usleep(5000);
// 接收 pluploa的參數
$chunk = isset($_REQUEST["chunk"]) ? $_REQUEST["chunk"] : 0;
$chunks = isset($_REQUEST["chunks"]) ? $_REQUEST["chunks"] : 0;
$fileName = isset($_REQUEST["name"]) ? $_REQUEST["name"] : '';
// 文件名整理
$fileName = preg_replace('/[^\w\._]+/', '', $fileName);
// 這里主要是如果JS參數設置了唯一文件名,則進行唯一文件名的處理,chunks<2 的意思是只有在不分塊上傳的情況下才會進行唯一文件名。否則將和分塊上傳的原理沖突,第1塊以后的文件流將無法寫入正確的文件中。
if ($chunks < 2 && file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName)) {
$ext = strrpos($fileName, '.');
$fileName_a = substr($fileName, 0, $ext);
$fileName_b = substr($fileName, $ext);
$count = 1;
while (file_exists($targetDir . DIRECTORY_SEPARATOR . $fileName_a . '_' . $count . $fileName_b))
$count++;
$fileName = $fileName_a . '_' . $count . $fileName_b;
}
/*創建文件目錄*/
if (!file_exists($targetDir))
@mkdir($targetDir);
if (is_dir($targetDir) && ($dir = opendir($targetDir))) {
while (($file = readdir($dir)) !== false) {
$filePath = $targetDir . DIRECTORY_SEPARATOR . $file;
// Remove temp files if they are older than the max age
if (preg_match('/\\.tmp$/', $file) && (filemtime($filePath) < time() - $maxFileAge))
@unlink($filePath);
}
closedir($dir);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 100, "message": "Failed to open temp directory."}, "id" : "id"}');
*/
// 上傳寫文件步驟,這一部分以下的代碼可直接引用
if (isset($_SERVER["HTTP_CONTENT_TYPE"]))
$contentType = $_SERVER["HTTP_CONTENT_TYPE"];
if (isset($_SERVER["CONTENT_TYPE"]))
$contentType = $_SERVER["CONTENT_TYPE"];
// Handle non multipart uploads older WebKit versions didn't support multipart in HTML5
if (strpos($contentType, "multipart") !== false) {
if (isset($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen($_FILES['file']['tmp_name'], "rb");
if ($in) {
while ($buff = fread($in, 4096))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($in);
fclose($out);
@unlink($_FILES['file']['tmp_name']);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 103, "message": "Failed to move uploaded file."}, "id" : "id"}');
} else {
// Open temp file
$out = fopen($targetDir . DIRECTORY_SEPARATOR . $fileName, $chunk == 0 ? "wb" : "ab");
if ($out) {
// Read binary input stream and append it to temp file
$in = fopen("php://input", "rb");
if ($in) {
while ($buff = fread($in, 4096))
fwrite($out, $buff);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 101, "message": "Failed to open input stream."}, "id" : "id"}');
fclose($in);
fclose($out);
} else
die('{"jsonrpc" : "2.0", "error" : {"code": 102, "message": "Failed to open output stream."}, "id" : "id"}');
}
// Return JSON-RPC response
die('{"jsonrpc" : "2.0", "result" : null, "id" : "id"}');
?>
~~~
#### **配置文檔說明:**
Browse_button:觸發瀏覽文件按鈕標簽的唯一id,,在flash、html5、和silverlight中能找到觸發事件的
Container: 展現上傳文件列表的容器,[默認是body]
chunk_size:當上傳文件大于服務器接收端文件大小限制的時候,可以分多次請求發給服務器,如果不需要從設置中移出
drop_element:當瀏覽器支持拖拽的情況下,能夠文件拖放到你想要的容器ID里
file_data_name:設置上傳字段的名稱。默認情況下被設置為文件。(我試驗了沒找到該如何使用它,暫且不提)
filters:選擇文件擴展名的過濾器,每個過濾規則中只有title和ext兩項[{title:'', extensions:''}]
flash_swf_url:flash文件地址
headers:自定義的插入http請求的鍵值對
max_file_size:最大上傳文件大小(格式100b, 10kb, 10mb, 1gb)
multipart:布爾值,如果用mutlipart 代替二進制流的方式,在webkit下無法工作
multipart_params: 跟 multipart關聯在一起的鍵值對
multi_selection: 多選對話框
resize:修改圖片屬性 resize: {width: 320, height: 240, quality: 90}
runtimes:上傳插件初始化選用那種方式的優先級順序,如果第一個初始化失敗就走第二個,依次類推
required_features:需要那些特性,才能初始化插件
url:上傳服務器地址
unique_names:是否生成唯一的文件名,避免與服務器文件重名
urlstream_upload:布爾值 如果是flash上傳應該用URLStream 代替FileReference.upload
#### **jquery部件的屬性:**
dragdrop:是否支持拖拽,默認值true
multiple_queues:是否可以多次上傳
preinit:插件初始化前回調函數
rename:布爾值,上傳之前可以重命名文件,默認false,
API文檔:方法列表:
Uploader(setting):創建實例的構造方法
var uploader = new plupload.Uploader({
runtimes : 'gears,html5,flash',
browse_button : 'button_id'
});
bind(event, function[, scope]):綁定事件
uploader.bind('Init', function(up) {
alert('Supports drag/drop: ' + (!!up.features.dragdrop));
});
destroy():銷毀plupload的實例對象
uploader.destroy()
getFile(id): 獲取上傳文件信息
uploader.bind('FilesAdded', function(up, files) {
for (var i in files) {
up.getFile(files[i].id);
}
});
注:file:{
id:文件編號,
loaded: 已經上傳多少字節,
name: 文件名,
percent: 上傳進度,
size: 文件大小,
status: 有四種狀態 QUEUED, UPLOADING, FAILED, DONE.對應數值
}
init:初始化plupload實例,添加監聽對象
refresh:重新實例化uploader
removeFile(id):從file中移除某個文件
splice(start,length):從隊列中start開始刪除length個文件, 返回被刪除的文件列表
start() 開始上傳
stop()停止上傳
unbind(name, function): 接觸事件綁定
unbindAll()解綁所有事件
屬性集合:
features:uploader中包含那些特性
files:當前隊列中的文件列表
id:uploader實例的唯一id
runtime:當前運行環境(是html5、flash等等)
state:當前上傳進度狀態
total:當前上傳文件的信息集合
事件集合:(up為uploader縮寫)
BeforeUpload(up, file):文件上傳完之前觸發的事件
ChunkUploaded(up, file,response)文件被分塊上傳的事件
Destroy(up):uploader的destroy調用的方法
Error(up, err):上傳出錯的時候觸發
Fileadded(up, files):用戶選擇文件時觸發
FileRemoved(up, files):當文件從上傳隊列中移除觸發
FileUploaded(up, file, res):文件上傳成功的時候觸發
Init(up):當初始化的時候觸發
PostInit(up):init執行完以后要執行的事件觸發
QueueChanged(up):當文件隊列變化時觸發
Refresh(up):當silverlight/flash或是其他運行環境需要移動的時候觸發
StateChanged(up)當整個上傳隊列被改變的時候觸發
UploadComplete(up,file)當隊列中所有文件被上傳完時觸發
UploadFile(up,file)當一個文件被上傳的時候觸發
UploadProgress(up,file):當文件正在被上傳中觸發
獲取上傳文件值:
前臺上傳文件后提交,在控制器中 print_r($_POST),就會得到下面信息
[uploader_0_tmpname] => p17bfctda8kdq19711p7ck4e1jqv1.png
[uploader_0_name] => ques_title.png
[uploader_0_status] => done
[uploader_1_tmpname] => p17bfctda81b5idpc1ek01u8a1tjf2.jpg
[uploader_1_name] => title2bg.jpg
[uploader_1_status] => done
[uploader_count] => 2
上面傳了2張圖片
[uploader_0_tmpname] 表示第一張圖片的臨時文件名 ;
[uploader_0_name] 表示第一張圖片的原文件名
[uploader_0_status] => done 表示文件上傳狀態,done表示成功
[uploader_1_tmpname] 表示第二張圖片的臨時文件名 ;
[uploader_1_name] 表示第二張圖片的原文件名
[uploader_1_status] => done 表示文件上傳狀態,done表示成功
以此類推......
[uploader_count] 表示上傳文件的個數,一般用來獲取文件總數
放入數組中:
~~~
$sum= $_POST['uploader_count'];
for ($i = 0; $i < $sum; $i++) {
$con[] = $_POST["uploader_" . $i . "_tmpname"];
}
~~~
$con 數組就是上傳的文件的臨時文件名