phpcms模組開發之swfupload的使用介紹_PHP教程

來源:互聯網
上載者:User
正式接觸phpcms模組開發後.開發了幾個功能模組.其中遇到了需要批量上傳圖片的問題.於是開始挖掘phpcms裡面的swfupload的用法.

在phpcms裡面內建的內容類型裡面能夠直接指定圖片組.不過這樣的圖片組功能並不是我想用的.我需要上傳一整個靜態html檔案.需要

能夠找到一個方法上傳整個檔案夾.並且能夠保留原來的檔案名稱.

目的總結如下:

1,不改變系統的檔案和目錄結構.

2,實現多附件上傳功能.

3,能夠得到上傳後的檔案夾名稱.

在phpcms中內建了附件上傳的功能.我想去用swfupload功能,而這個功能被phpcms的附件上傳功能整合進去了.那我要做的就是抽出來並加以修改.

第一步,我來研究研究這個是怎麼調用的.

首先,開啟firefox瀏覽器的firebug 開啟網路面板.找到phpcm中swfupload唄調出的那個按鈕.看看系統是請求的什麼串連.
複製代碼 代碼如下:
?m=attachment&c=attachments&a=swfupload&args=10,,1&module=&catid=&authkey=b756a93dea2e627293e88fa9d62af709&pc_hash=iXFbo1

我們捕捉到一串這樣的請求.調用了attachment模組的attachements控制器裡面的swfupload方法.

我們去找到這個模組中的這個控制器裡面的這個方法.

在phpcms/modoules/attachemet/attachemts.php裡面

開啟看看,代碼如下
複製代碼 代碼如下:
public function swfupload(){
$grouplist = getcache('grouplist','member');
if(isset($_POST['dosubmit'])){
      //if裡面的內容我們暫時不看.因為這是上傳之後的處理.我們要先找到是如何引入swfupload的.
} else {
if($this->isadmin==0 && !$grouplist[$this->groupid]['allowattachment']) showmessage(L('att_no_permission'));
$args = $_GET['args'];//得到參數
$authkey = $_GET['authkey'];//得到密匙
if(upload_key($args) != $authkey) showmessage(L('attachment_parameter_error'));//驗證密匙
extract(getswfinit($_GET['args']));//拆分參數
$siteid = $this->get_siteid();//得到網站id
$site_setting = get_site_setting($siteid);//得到網站設定
$file_size_limit = sizecount($site_setting['upload_maxsize']*1024);//允許上傳大小
$att_not_used = param::get_cookie('att_json');//得到未處理的檔案清單
if(empty($att_not_used) || !isset($att_not_used)) $tab_status = ' class="on"';//如果有未處理的設定標籤樣式為on
if(!empty($att_not_used)) $div_status = ' hidden';//否則隱藏標籤
$att = $this->att_not_used();//擷取臨時未處理檔案清單
include $this->admin_tpl('swfupload');//這個地方才是關鍵.載入了這個模板.
}
}

前面的我們就先不管了 ,那是處理上傳的東西.我從else開始看.首先驗證了是否允許附件上傳

然後從$_GET裡面得到swfupload的參數args,然後去驗證了密匙,密匙通過了去解析args.得到網站的id,得到網站的設定,得到允許上傳附件的大小.從cookie裡面得到未使用的附件列表.

設定模板裡面的各種顯示.最後也是最關鍵的.它使用了swfupload模板.也就是說我要找到這個模板.看看swfupload是怎麼引過來的.

模板在這裡:phpcms/modules/attachment/templates/swfupload.tpl.php

開啟模板檔案.模板檔案上面引入了一堆檔案:
複製代碼 代碼如下:
admin_tpl('header', 'attachment');?>






首先是引入了標頭檔.我大概看裡一下.裡面有jquery什麼的.是必要檔案.所以一會我們要用的時候也要引入這個頭.

之後是swfupload的樣式檔案和必要的JS.這裡調用了一個系統函數initupload,這個函數到底是幹嘛的.

千萬別小覷這行.整個swfupload的配置都在這裡了.

我們去找找看這個函數.

在phpcms/modules/attachment/functions/golable.func.php裡面找到了它的蹤跡.代碼如下,這個函數的主要作用就是配置swfupload這個外掛程式.
複製代碼 代碼如下:
/* flash上傳初始化
* 初始化swfupload上傳中需要的參數
* @param $module 模組名稱
* @param $catid 欄目id
* @param $args 傳遞參數
* @param $userid 使用者id
* @param $groupid 使用者組id
* @param $isadmin 是否為管理員模式
*/
function initupload($module, $catid,$args, $userid, $groupid = '8', $isadmin = '0'){
$grouplist = getcache('grouplist','member');
if($isadmin==0 && !$grouplist[$groupid]['allowattachment']) return false;
extract(getswfinit($args));
$siteid = param::get_cookie('siteid');
$site_setting = get_site_setting($siteid);
$file_size_limit = $site_setting['upload_maxsize'];
$sess_id = SYS_TIME;
$swf_auth_key = md5(pc_base::load_config('system','auth_key').$sess_id);
$init = 'var swfu = \'\';
$(document).ready(function(){
swfu = new SWFUpload({
flash_url:"'.JS_PATH.'swfupload/swfupload.swf?"+Math.random(),
upload_url:"'.APP_PATH.'index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1",
file_post_name : "Filedata",
post_params:{"SWFUPLOADSESSID":"'.$sess_id.'","module":"'.$module.'","catid":"'.$_GET['catid'].'","userid":"'.$userid.'","siteid":"'.$siteid.'","dosubmit":"1","thumb_width":"'.$thumb_width.'","thumb_height":"'.$thumb_height.'","watermark_enable":"'.$watermark_enable.'","filetype_post":"'.$file_types_post.'","swf_auth_key":"'.$swf_auth_key.'","isadmin":"'.$isadmin.'","groupid":"'.$groupid.'"},
file_size_limit:"'.$file_size_limit.'",
file_types:"'.$file_types.'",
file_types_description:"All Files",
file_upload_limit:"'.$file_upload_limit.'",
custom_settings : {progressTarget : "fsUploadProgress",cancelButtonId : "btnCancel"},

button_image_url: "",
button_width: 75,
button_height: 28,
button_placeholder_id: "buttonPlaceHolder",
button_text_style: "",
button_text_top_padding: 3,
button_text_left_padding: 12,
button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
button_cursor: SWFUpload.CURSOR.HAND,

file_dialog_start_handler : fileDialogStart,
file_queued_handler : fileQueued,
file_queue_error_handler:fileQueueError,
file_dialog_complete_handler:fileDialogComplete,
upload_progress_handler:uploadProgress,
upload_error_handler:uploadError,
upload_success_handler:uploadSuccess,
upload_complete_handler:uploadComplete
});
})';
return $init;
}

回到正題.我們來看模板swfupload.tpl.php

這個模板使用了一個js來控制

  • 以頁簽的形式顯示.我們可以用firebug去找到帶有我們要找到的swfupload按鈕的那個頁簽的id

    那個id是tab_swf_1

    這個是一個div 代碼如下.
    複製代碼 代碼如下:
    ">





    ,

    onclick="change_params()">









    在這裡我們看到有一個span id是buttonPlaceHolder 而在設定檔中有這麼一行button_placeholder_id: "buttonPlaceHolder",很明顯.當頁面被載入的時候 id為buttonPlaceHolder的元素會被JS替換成swfupload的上傳控制項.

    之後一步我們要在點選完檔案之後觸發swf的上傳方法

    會在代碼中找到如下代碼.這裡面調用了swfu.startUpload()方法.這個方法定義的地方在swfupload.js裡面.我們無需理會.
    複製代碼 代碼如下:


    至此.我們已經找到了swfupload的上傳控制項使用方法

    怎麼在我的程式裡面調用這個東東呢

    首先一點 我們需要在這個控制項出現的模板裡面引入這些必要的檔案
    複製代碼 代碼如下:






    代碼如上所示.

    然後在我們的模板裡面想要放置swfupload的地方寫上這樣的標籤
    複製代碼 代碼如下:

    複製代碼 代碼如下:
    upload_url:"'.APP_PATH.'index.php?m=attachment&c=attachments&a=swfupload&dosubmit=1",

    這個很明顯就透露出了我們把檔案上傳到了attachment模組中attachments控制器裡面的swfupload方法去處理了

    這個地方也就是我之前沒有關注的if裡面的東西.

    拿出來看看
    複製代碼 代碼如下:
    if( $_POST['swf_auth_key'] != md5(pc_base::load_config('system','auth_key').$_POST['SWFUPLOADSESSID']) || ($_POST['isadmin']==0 && !$grouplist[$_POST['groupid']]['allowattachment'])) exit();
    pc_base::load_sys_class('attachment','',0);
    $attachment = new attachment($_POST['module'],$_POST['catid'],$_POST['siteid']);
    $attachment->set_userid($_POST['userid']);
    $aids = $attachment->upload('Filedata',$_POST['filetype_post'],'','',array($_POST['thumb_width'],$_POST['thumb_height']),$_POST['watermark_enable']);
    if($aids[0]) {
    $filename= (strtolower(CHARSET) != 'utf-8') ? iconv('gbk', 'utf-8', $attachment->uploadedfiles[0]['filename']) : $attachment->uploadedfiles[0]['filename'];
    if($attachment->uploadedfiles[0]['isimage']) {
    echo $aids[0].','.$this->upload_url.$attachment->uploadedfiles[0]['filepath'].','.$attachment->uploadedfiles[0]['isimage'].','.$filename;
    } else {
    $fileext = $attachment->uploadedfiles[0]['fileext'];
    if($fileext == 'zip' || $fileext == 'rar') $fileext = 'rar';
    elseif($fileext == 'doc' || $fileext == 'docx') $fileext = 'doc';
    elseif($fileext == 'xls' || $fileext == 'xlsx') $fileext = 'xls';
    elseif($fileext == 'ppt' || $fileext == 'pptx') $fileext = 'ppt';
    elseif ($fileext == 'flv' || $fileext == 'swf' || $fileext == 'rm' || $fileext == 'rmvb') $fileext = 'flv';
    else $fileext = 'do';
    echo $aids[0].','.$this->upload_url.$attachment->uploadedfiles[0]['filepath'].','.$fileext.','.$filename;
    }
    exit;
    } else {
    echo '0,'.$attachment->error();
    exit;

    這個裡面有幾行是比較重要的.

    首先它載入了系統的attachment類.並且用到了裡面的方法.

    程式對上傳成功做了echo操作.返回的東西是 返回了編號,上傳後的地址,拓展名,檔案名稱.

    這些東西是給誰用的啊 我們還得回去看設定檔.

    設定檔裡面有一段是上傳過程中各個事件將觸發的方法. 有開始上傳的.有上傳成功的,有上傳失敗的.等等.

    我們可以看見有一個方法是file_dialog_complete_handler:fileDialogComplete,

    其實這些已經升級到swfupload的範疇了.有興趣可以去研究研究

    然後我們在phpcms/static/swfupload/handler.js裡面找到這個方法.

    看見上傳成功後echo出來的資料被解析了.

    解析的方法如下
    複製代碼 代碼如下:
    function att_show(serverData,file)
    {
    var serverData = serverData.replace(//g,'');
    var data = serverData.split(',');
    var id = data[0];
    var src = data[1];
    var ext = data[2];
    var filename = data[3];
    if(id == 0) {
    alert(src)
    return false;
    }
    if(ext == 1) {
    var img = '';
    } else {
    var img = '';
    }
    $.get('index.php?m=attachment&c=attachments&a=swfupload_json&aid='+id+'&src='+src+'&filename='+filename);
    $('#fsUploadProgress').append('

  • ');
    $('#attachment_'+id).html(img);
    $('#att-status').append('|'+src);
    $('#att-name').append('|'+filename);
    }

    這個方法的目的是在id為fsuuploadprogress的元素裡面添加我們上傳成功的附件.但是我們還木有找到檔案到底去哪裡了

    關鍵的地方來了.我們在swfupload方法裡面不是有個attachment的系統類別的執行個體麼

    真正上傳附件是在這裡實現的.我們調用了attachment裡面的upload方法來實現了檔案的上傳.

    這個attachment檔案裡面的upload方法在系統類別裡面 也就是phpcms/libs/classes/attachment.class.php裡面

    在這個類裡面我們可以找到upload方法裡面有這樣一行
    複製代碼 代碼如下:
    $this->savepath = $this->upload_root.$this->upload_dir.date('Y/md/');

    這個自然就是指定了上傳到的目錄.檔案名稱是通過getname方法來擷取的.

    到這裡我們就理清思路了.

    系統是這麼啟動並執行

    首先在模板裡面引用swfupload(設定檔是用函數產生的)->上傳檔案->attachment模組裡的swfupload方法處理(使用系統的attachment類裡面的upload方法迴圈上傳附件.並返回結果給swfupload方法)->處理結果通過swfupload的方法(fileDialogComplete)返回給頁面.

    在上面我們已經實現了在模板裡面引入swfupload.但是我們使用的設定檔和上傳附件的方法等都是系統原來內建的.並不能實現我想要的目錄結構和檔案命名方法.怎麼辦..

    改.

    怎麼改,首先們要把設定檔改掉. 在自己的模組裡面的functions檔案夾裡面建立自己的函數.我們用自己的函數名稱 檔案命名為global.func.php這樣系統會通過auto_load把我們的函數載入

    進去我們把系統中attachment模組functions檔案夾下面的global.func.php裡面的initupload函數全盤拷貝進來.只修改其中的一行
    複製代碼 代碼如下:
    upload_url:"'.APP_PATH.'index.php?m=你的模組名稱&c=你的控制器名稱&a=你的方法名稱&dosubmit=1",

    這樣檔案就會提交到我們的控制器下面.並且調用我們自己寫的方法

    然後我們去改系統的attachment類 我們在自己的模組下的classes檔案夾下面建立一個myattachment.class.php

    寫一個我們自己的類.去整合系統的attachment類.(記得吧裡面的私人方法copy過來.)我們需要修改幾行.首先一點是吧upload方法裡面的上傳目錄改掉.然後是改掉檔案名稱的命名方法.
    複製代碼 代碼如下:
    function upload($field, $alowexts = '', $maxsize = 0, $overwrite = 0,$thumb_setting = array(), $watermark_enable = 1) {
    if(!isset($_FILES[$field])) {
    $this->error = UPLOAD_ERR_OK;
    return false;
    }
    if(empty($alowexts) || $alowexts == '') {
    $site_setting = $this->_get_site_setting($this->siteid);
    $alowexts = $site_setting['upload_allowext'];
    }
    $fn = $_GET['CKEditorFuncNum'] ? $_GET['CKEditorFuncNum'] : '1';

    $this->field = $field;
    $this->savepath = $this->upload_root.$this->upload_dir.date('Ymd');//這裡我們需要修改下.也可以不修改.在我們執行個體化這個類的時候再來指定目錄.
    $this->alowexts = $alowexts;
    $this->maxsize = $maxsize;
    $this->overwrite = $overwrite;
    $uploadfiles = array();
    $description = isset($GLOBALS[$field.'_description']) ? $GLOBALS[$field.'_description'] : array();
    if(is_array($_FILES[$field]['error'])) {
    $this->uploads = count($_FILES[$field]['error']);
    foreach($_FILES[$field]['error'] as $key => $error) {
    if($error === UPLOAD_ERR_NO_FILE) continue;
    if($error !== UPLOAD_ERR_OK) {
    $this->error = $error;
    return false;
    }
    $uploadfiles[$key] = array('tmp_name' => $_FILES[$field]['tmp_name'][$key], 'name' => $_FILES[$field]['name'][$key], 'type' => $_FILES[$field]['type'][$key], 'size' => $_FILES[$field]['size'][$key], 'error' => $_FILES[$field]['error'][$key], 'description'=>$description[$key],'fn'=>$fn);
    }
    } else {
    $this->uploads = 1;
    if(!$description) $description = '';
    $uploadfiles[0] = array('tmp_name' => $_FILES[$field]['tmp_name'], 'name' => $_FILES[$field]['name'], 'type' => $_FILES[$field]['type'], 'size' => $_FILES[$field]['size'], 'error' => $_FILES[$field]['error'], 'description'=>$description,'fn'=>$fn);
    }

    if(!dir_create($this->savepath)) {
    $this->error = '8';
    return false;
    }
    if(!is_dir($this->savepath)) {
    $this->error = '8';
    return false;
    }
    @chmod($this->savepath, 0777);

    if(!is_writeable($this->savepath)) {
    $this->error = '9';
    return false;
    }
    if(!$this->is_allow_upload()) {
    $this->error = '13';
    return false;
    }
    $aids = array();
    foreach($uploadfiles as $k=>$file) {
    $fileext = fileext($file['name']);
    if($file['error'] != 0) {
    $this->error = $file['error'];
    return false;
    }
    if(!preg_match("/^(".$this->alowexts.")$/", $fileext)) {
    $this->error = '10';
    return false;
    }
    if($this->maxsize && $file['size'] > $this->maxsize) {
    $this->error = '11';
    return false;
    }
    if(!$this->isuploadedfile($file['tmp_name'])) {
    $this->error = '12';
    return false;
    }
    //$temp_filename = $this->getname($fileext);//名稱在這裡.我們需要修改下
           $temp_filename = $file['tmp_name'].$fileext; //修改成原來的系統檔案名稱.
           $savefile = $this->savepath.$temp_filename; $savefile = preg_replace("/(php|phtml|php3|php4|jsp|exe|dll|asp|cer|asa|shtml|shtm|aspx|asax|cgi|fcgi|pl)(\.|$)/i", "_\\1\\2", $savefile); $filepath = preg_replace(new_addslashes("|^".$this->upload_root."|"), "", $savefile); if(!$this->overwrite && file_exists($savefile)) continue; $upload_func = $this->upload_func; if(@$upload_func($file['tmp_name'], $savefile)) { $this->uploadeds++; @chmod($savefile, 0644); @unlink($file['tmp_name']); $file['name'] = iconv("utf-8",CHARSET,$file['name']); $uploadedfile = array('filename'=>$file['name'], 'filepath'=>$filepath, 'filesize'=>$file['size'], 'fileext'=>$fileext, 'fn'=>$file['fn']); $thumb_enable = is_array($thumb_setting) && ($thumb_setting[0] > 0 || $thumb_setting[1] > 0 ) ? 1 : 0; $image = new image($thumb_enable,$this->siteid); if($thumb_enable) { $image->thumb($savefile,'',$thumb_setting[0],$thumb_setting[1]); } if($watermark_enable) { $image->watermark($savefile, $savefile); } $aids[] = $this->add($uploadedfile); } } return $aids; }

    注:這裡我們可以再系統的attachment模組下建立MY_attachment.php 但是這樣會影響系統的附件上傳功能.

    在我們自己的控制器裡面.我們這個時候就需要載入自己寫的類了.
    複製代碼 代碼如下:
    pc_base::load_app_class('你的模組名','',0);

    其餘的操作可以參照系統的attachment模組下的attachments控制器裡面的swfupload方法來修改.

    至此.我便完成了我的目的.在不改變系統檔案目錄的基礎上.完成我自己想要的檔案上傳功能.

    http://www.bkjia.com/PHPjc/326932.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/326932.htmlTechArticle正式接觸phpcms模組開發後.開發了幾個功能模組.其中遇到了需要批量上傳圖片的問題.於是開始挖掘phpcms裡面的swfupload的用法. 在phpcms裡面自...

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.