搜尋
首頁後端開發php教程phpcms模块开发之swfupload的使用介绍_PHP教程

phpcms模块开发之swfupload的使用介绍_PHP教程

Jul 21, 2016 pm 03:11 PM
phpcms介紹使用幾個開發模組正式

正式接触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 = '
    phpcms模块开发之swfupload的使用介绍_PHP教程
    ';
        } else {
            var img = '
    phpcms模块开发之swfupload的使用介绍_PHP教程
    ';
        }
        $.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方法来修改.

    至此.我便完成了我的目的.在不改变系统文件目录的基础上.完成我自己想要的文件上传功能.

    www.bkjia.comtruehttp://www.bkjia.com/PHPjc/326932.htmlTechArticle正式接触phpcms模块开发后.开发了几个功能模块.其中遇到了需要批量上传图片的问题.于是开始挖掘phpcms里面的swfupload的用法. 在phpcms里面自...
    陳述
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型?PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型?Apr 17, 2025 am 12:25 AM

    PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

    PHP如何處理對象克隆(克隆關鍵字)和__clone魔法方法?PHP如何處理對象克隆(克隆關鍵字)和__clone魔法方法?Apr 17, 2025 am 12:24 AM

    PHP中使用clone關鍵字創建對象副本,並通過\_\_clone魔法方法定制克隆行為。 1.使用clone關鍵字進行淺拷貝,克隆對象的屬性但不克隆對象屬性內的對象。 2.通過\_\_clone方法可以深拷貝嵌套對象,避免淺拷貝問題。 3.注意避免克隆中的循環引用和性能問題,優化克隆操作以提高效率。

    PHP與Python:用例和應用程序PHP與Python:用例和應用程序Apr 17, 2025 am 12:23 AM

    PHP適用於Web開發和內容管理系統,Python適合數據科學、機器學習和自動化腳本。 1.PHP在構建快速、可擴展的網站和應用程序方面表現出色,常用於WordPress等CMS。 2.Python在數據科學和機器學習領域表現卓越,擁有豐富的庫如NumPy和TensorFlow。

    描述不同的HTTP緩存標頭(例如,Cache-Control,ETAG,最後修飾)。描述不同的HTTP緩存標頭(例如,Cache-Control,ETAG,最後修飾)。Apr 17, 2025 am 12:22 AM

    HTTP緩存頭的關鍵玩家包括Cache-Control、ETag和Last-Modified。 1.Cache-Control用於控制緩存策略,示例:Cache-Control:max-age=3600,public。 2.ETag通過唯一標識符驗證資源變化,示例:ETag:"686897696a7c876b7e"。 3.Last-Modified指示資源最後修改時間,示例:Last-Modified:Wed,21Oct201507:28:00GMT。

    說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1?說明PHP中的安全密碼散列(例如,password_hash,password_verify)。為什麼不使用MD5或SHA1?Apr 17, 2025 am 12:06 AM

    在PHP中,應使用password_hash和password_verify函數實現安全的密碼哈希處理,不應使用MD5或SHA1。1)password_hash生成包含鹽值的哈希,增強安全性。 2)password_verify驗證密碼,通過比較哈希值確保安全。 3)MD5和SHA1易受攻擊且缺乏鹽值,不適合現代密碼安全。

    PHP:服務器端腳本語言的簡介PHP:服務器端腳本語言的簡介Apr 16, 2025 am 12:18 AM

    PHP是一種服務器端腳本語言,用於動態網頁開發和服務器端應用程序。 1.PHP是一種解釋型語言,無需編譯,適合快速開發。 2.PHP代碼嵌入HTML中,易於網頁開發。 3.PHP處理服務器端邏輯,生成HTML輸出,支持用戶交互和數據處理。 4.PHP可與數據庫交互,處理表單提交,執行服務器端任務。

    PHP和網絡:探索其長期影響PHP和網絡:探索其長期影響Apr 16, 2025 am 12:17 AM

    PHP在過去幾十年中塑造了網絡,並將繼續在Web開發中扮演重要角色。 1)PHP起源於1994年,因其易用性和與MySQL的無縫集成成為開發者首選。 2)其核心功能包括生成動態內容和與數據庫的集成,使得網站能夠實時更新和個性化展示。 3)PHP的廣泛應用和生態系統推動了其長期影響,但也面臨版本更新和安全性挑戰。 4)近年來的性能改進,如PHP7的發布,使其能與現代語言競爭。 5)未來,PHP需應對容器化、微服務等新挑戰,但其靈活性和活躍社區使其具備適應能力。

    為什麼要使用PHP?解釋的優點和好處為什麼要使用PHP?解釋的優點和好處Apr 16, 2025 am 12:16 AM

    PHP的核心優勢包括易於學習、強大的web開發支持、豐富的庫和框架、高性能和可擴展性、跨平台兼容性以及成本效益高。 1)易於學習和使用,適合初學者;2)與web服務器集成好,支持多種數據庫;3)擁有如Laravel等強大框架;4)通過優化可實現高性能;5)支持多種操作系統;6)開源,降低開發成本。

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    1 個月前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    1 個月前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您聽不到任何人,如何修復音頻
    1 個月前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.聊天命令以及如何使用它們
    1 個月前By尊渡假赌尊渡假赌尊渡假赌

    熱工具

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    Safe Exam Browser

    Safe Exam Browser

    Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

    Atom編輯器mac版下載

    Atom編輯器mac版下載

    最受歡迎的的開源編輯器

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    Dreamweaver Mac版

    Dreamweaver Mac版

    視覺化網頁開發工具