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


Posted in PHP onApril 28, 2013

正式接触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

打开模板文件.模板文件上面引入了一堆文件:

<?php $show_header = $show_validator = $show_scroll = 1; include $this->admin_tpl('header', 'attachment');?>
<link href="<?php echo JS_PATH?>swfupload/swfupload.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/swfupload.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/fileprogress.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/handlers2.js"></script>
<script type="text/javascript">
<?php echo initupload($_GET['module'],$_GET['catid'],$args,$this->userid,$this->groupid,$this->isadmin)?>
</script>

首先是引入了头文件.我大概看里一下.里面有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来控制<li>以页签的形式显示.我们可以用firebug去找到带有我们要找到的swfupload按钮的那个页签的id

那个id是tab_swf_1

这个是一个div 代码如下.

<div id="div_swf_1" class="content pad-10 <?php echo $div_status?>">
            <div>
                <div class="addnew" id="addnew">
                    <span id="buttonPlaceHolder"></span>
                </div>
                <input type="button" id="btupload" value="<?php echo L('start_upload')?>" onClick="swfu.startUpload();" />
                <div id="nameTip" class="onShow"><?php echo L('upload_up_to')?><font color="red"> <?php echo $file_upload_limit?></font> <?php echo L('attachments')?>,<?php echo L('largest')?> <font color="red"><?php echo $file_size_limit?></font></div>
                <div class="bk3"></div>
                <div class="lh24"><?php echo L('supported')?> <font style="font-family: Arial, Helvetica, sans-serif"><?php echo str_replace(array('*.',';'),array('','、'),$file_types)?></font> <?php echo L('formats')?></div><input type="checkbox" id="watermark_enable" value="1" <?php if(isset($watermark_enable) &&$watermark_enable == 1) echo 'checked'?> onclick="change_params()"> <?php echo L('watermark_enable')?>
            </div>
            <div class="bk10"></div>
            <fieldset class="blue pad-10" id="swfupload">
            <legend><?php echo L('lists')?></legend>
            <ul class="attachment-list"  id="fsUploadProgress">
            </ul>
            </fieldset>
        </div>

在这里我们看到有一个span   id是buttonPlaceHolder  而在配置文件中有这么一行button_placeholder_id: "buttonPlaceHolder",很明显.当页面被加载的时候 id为buttonPlaceHolder的元素会被JS替换成swfupload的上传控件.

之后一步我们要在点选完文件之后触发swf的上传方法

会在代码中找到如下代码.这里面调用了swfu.startUpload()方法.这个方法定义的地方在swfupload.js里面.我们无需理会.

<input type="button" id="btupload" value="<?php echo L('start_upload')?>" onClick="swfu.startUpload();" />

至此.我们已经找到了swfupload的上传控件使用方法

怎么在我的程序里面调用这个东东呢 

首先一点 我们需要在这个控件出现的模板里面引入这些必要的文件

<link href="<?php echo JS_PATH?>swfupload/swfupload.css" rel="stylesheet" type="text/css" />
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/swfupload.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/fileprogress.js"></script>
<script language="JavaScript" type="text/javascript" src="<?php echo JS_PATH?>swfupload/handlers2.js"></script>
<script type="text/javascript">
<?php echo initupload($_GET['module'],$_GET['catid'],$args,$this->userid,$this->groupid,$this->isadmin)?>
</script>

代码如上所示.

然后在我们的模板里面想要放置swfupload的地方写上这样的标签

<span id="buttonPlaceHolder"></span>
<input type="button" id="btupload" value="<?php echo L('start_upload')?>" onClick="swfu.startUpload();

这样我们就已经把swfupload引入到我们需要的地方了.接着就是能够正常执行上传等功能.

但是这样还不能达到我们的需求.而且有一个问题.我们把文件上传到神马地方去了.那我们就来找找我们把文件上传到神马地方去了

在配置文件(用initupload函数输出的)里面有这样一行

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(/<div.*?<\/div>/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 = '<a href="javascript:;" onclick="javascript:att_cancel(this,'+id+',\'upload\')" class="on"><div class="icon"></div><img src="'+src+'" width="80" imgid="'+id+'" path="'+src+'" title="'+filename+'"/></a>';
    } else {
        var img = '<a href="javascript:;" onclick="javascript:att_cancel(this,'+id+',\'upload\')" class="on"><div class="icon"></div><img src="statics/images/ext/'+ext+'.png" width="80" imgid="'+id+'" path="'+src+'" title="'+filename+'"/></a>';
    }
    $.get('index.php?m=attachment&c=attachments&a=swfupload_json&aid='+id+'&src='+src+'&filename='+filename);
    $('#fsUploadProgress').append('<li><div id="attachment_'+id+'" class="img-wrap"></div></li>');
    $('#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方法来修改.

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

PHP 相关文章推荐
一个程序下载的管理程序(三)
Oct 09 PHP
PHP XML备份Mysql数据库
May 27 PHP
如何在smarty中增加类似foreach的功能自动加载数据
Jun 26 PHP
php jquery 多文件上传简单实例
Dec 23 PHP
php格式化电话号码的方法
Apr 24 PHP
Yii2.0预定义的别名功能小结
Jul 04 PHP
利用PHP自动生成印有用户信息的名片
Aug 01 PHP
php+mysql查询实现无限下级分类树输出示例
Oct 03 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
Dec 14 PHP
PHP实现的装箱算法示例
Jun 23 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
Aug 14 PHP
php输出文字乱码的解决方法
Oct 04 PHP
php中get_headers函数的作用及用法的详细介绍
Apr 27 #PHP
使用php get_headers 判断URL是否有效的解决办法
Apr 27 #PHP
php中serialize序列化与json性能测试的示例分析
Apr 27 #PHP
php gzip压缩输出的实现方法
Apr 27 #PHP
PHP字符串的编码问题的详细介绍
Apr 27 #PHP
php正则表达式使用的详细介绍
Apr 27 #PHP
基于PHP编程注意事项的小结
Apr 27 #PHP
You might like
支持数组的ADDSLASHES的php函数
2010/02/16 PHP
php新建文件自动编号的思路与实现
2011/06/27 PHP
服务器迁移php版本不同可能诱发的问题
2015/12/22 PHP
PHP二进制与字符串之间的相互转换教程
2016/10/14 PHP
jQuery一步一步实现跨浏览器的可编辑表格,支持IE、Firefox、Safari、Chrome、Opera
2009/08/28 Javascript
js防止表单重复提交的两种方法
2013/09/30 Javascript
浅析jquery的作用与优势
2013/12/02 Javascript
jQuery中delegate与on的用法与区别示例介绍
2013/12/20 Javascript
jQuery实现的多屏图像图层切换效果实例
2015/05/07 Javascript
jquery.map()方法的使用详解
2015/07/09 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
2015/07/29 Javascript
轻量级网页遮罩层jQuery插件用法实例
2015/07/31 Javascript
谈一谈javascript闭包
2016/01/28 Javascript
javascript每日必学之继承
2016/02/23 Javascript
jQuery简单实现点击文本框复制内容到剪贴板上的方法
2016/08/01 Javascript
jQuery自制提示框tooltip改进版
2016/08/01 Javascript
JavaScript实现图片轮播组件代码示例
2016/11/22 Javascript
select自定义小三角样式代码(实用总结)
2017/08/18 Javascript
vue实现路由切换改变title功能
2019/05/28 Javascript
产制造追溯系统之通过微信小程序实现移动端报表平台
2019/06/03 Javascript
js实现简单点赞操作
2020/03/17 Javascript
解决vuex数据页面刷新后初始化操作
2020/07/26 Javascript
使用python搭建Django应用程序步骤及版本冲突问题解决
2013/11/19 Python
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
python中正则表达式的使用方法
2018/02/25 Python
Python定义二叉树及4种遍历方法实例详解
2018/07/05 Python
关于sys.stdout和print的区别详解
2019/12/05 Python
Python绘制组合图的示例
2020/09/18 Python
AmazeUI 单选框和多选框的实现示例
2020/08/18 HTML / CSS
动态密码技术
2012/10/18 面试题
学校安全管理责任书
2014/07/23 职场文书
党员自我评价2015
2015/03/03 职场文书
给校长的建议书作文300字
2015/09/14 职场文书
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
2022/04/20 Python
MySQL 条件查询的常用操作
2022/04/28 MySQL
解决IIS7下无法绑定https主机的问题
2022/04/29 Servers