Discuz!插件开发 作者简介:童虎,Discuz!论坛程序研发经理,负责Discuz!论坛程序研发团队的管 理工作,曾是Discuz!早期插件作者,担任过Freediscuz 插件区版主。 曾开发过社区 宠物、社区监狱、社区虚拟形象等多个Discuz!热门插件。 论坛向社区化发展已经成为趋势,站长对网站的个性化需求越来越高,同时随着网站规 模的扩大,站长对于一些特殊功能的需求也越来越多, Discuz! 标准程序作为一个通用 程序,从某种意义上讲很难满足所有站长个性化功能的需求,因此论坛插件就成为对标准程 序最好的功能补充。 从目前来看,正在做插件和想做插件的人越来越多,从Discuz!官方论坛的统计数据 大家就可以看出,目前插件区已经成为仅次于安装使用区之后的第二大版块。于此我们同时 也发现许多希望开发插件的作者,有时候感觉插件开发很难上手,一定程度上也影响了插件 的丰富性和多样性。特此,写这样一篇文章,谈不上有什么教育意义,只是给那些希望开发 插件的朋友一块敲门砖,让更多的人成为一名插件作者,拿出你们的创意,让论坛更加丰富 多彩。 闲话少叙,书归正言,首先我们来介绍一些Discuz!插件从程序实现的方式,主要是 分两种: 第一种是利用已有的插件机制,这种机制官方有详细的开发文档,可以利用现有的一些 接口和函数,按照文档规定的文件以及目录结构,进行开发就可以了,这种方式是官方鼓励 的开发方式,所开发的插件比较标准,在后台可以轻松管理并导入导出,利于插件的安装。 但是这种方式需要插件作者看懂开发文档,严格按照开发文档做。个人感觉局限性相对而言 比较大,不过推荐新手可以试试这种方式,毕竟这种方式插件方便插件使用者安装,相对而 言比较利于插件的推广。 第二种就是我这篇文章可能要重点推荐的,我称它为自由方式,这种方式需要插件作者 Discuz!程序相关接口和函数有一定了解。当然我会在下面的文章里面对一些常用函 数做一个简单介绍。这种方式的好处就是在编写程序时候比较自由,不需要像第一种那样需 要放在规定的目录中,给插件作者发挥的余地更大。还有,就是这样写出的程序更像论坛程 序的一部分,而不是一个插件,哈哈。不过这种方式编写的插件也有一定的缺陷,比如安装 上面相对第一种方式比较繁琐,如果需要管理后台,还需要自己来编写。不过这些对于大家 来说应该是小意思了吧,呵呵。 下面我一步一步来介绍自由方式编写插件的过程,以及一些常用的函数和其用法。先强 调一点,我这里所介绍的插件是有独立运行文件的,而不是那种只修改原文件。 首先介绍一下插件的组成,一个普通的插件不管是小型的还是大型的,一般都会有一个 主程序文件,作为 Discuz! 的插件,如果有独立页面一般会有模板文件。当然随着插件 功能增加可能还会有其他文件,比如后台管理文件、自定义函数文件等等。总的来说一个插 件最低限度要有一个主程序 php 文件,基本上都会有一个主程序文件和模板文件。高级一 些插件还会存在后台管理文件以及相关程序文件。 文件存放目录,一般主程序会放在论坛根目录下,这样比较规范而且方便插件前台调用。 模板目录一般放在 templatesdefault 目录下,这样即使更换风格也可以正常使用,因 Discuz!模板处理程序会有这样的一个机制:如果生成模板缓存的时候,当前模板目 录下没有需要的模板文件,会自动到默认模板目录下获取,如果还没有才会报错。所以作为 插件的模板最好放在默认模板目录下。 其他文件可以根据功能不同放在不同的目录下,比如说后台管理文件,一般会放在论坛 根目录 admin 目录下,然后通过 admincp.php 里面调用,调用方法我会在后面说到。 用的一些 functiON 之类的东西,可以写成一个文件放在 include 目录下,不过最好是 单独建立一个目录放在里面,这样比较方便今后的拆卸。 最后还有一部分文件,就是你页面中可能会用到的图片文件,这些图片文件一般放在 images 目录下,至于放在那里在这里我们就没有严格的要求了。 说完了文件,下面简单介绍一下插件中对数据表的操作。对于插件而言实际上是不希望 对论坛的数据表进行修改的,特别是论坛的几个主要数据表:members、 posts、threads, 对这几个表如果修改的不恰当,很可能造成整个论坛系统性能的下降。为了防止给插件拆卸 带来不便,所以我们在制作插件时候尽量避免对上面三个数据表的结构进行修改。如果非要 修改,尽量能单独建立数据表,然后通过 uid tid进行数据关联,当使用的 时候再调用。 退一步说如果非要在上述三个数据表里面添加字段,所添加的字段如果是字符类型必须 是定长字段,例如 char ,如果是数字类型根据数值范围不同,尽量用 tinyint smallint、int ,这样尽可能不影响论坛效率。当然在实际使用中还有许多要注意的地 方,鉴于文章的篇幅有限这里不做太多详细的说明,另外我会对插件数据库要注意的问题, 单独写成文档和大家一起讨论。 上面都是一些常识问题,下面我以一个以前我写过的插件为例子,具体对插件的编写, 以及一些 Discuz! 常用函数的使用做说明。 这个插件很简单,就是一个抽奖的插件,主要功能是根据会员的一些论坛资料,比如发 帖数、精华帖、在线时间、注册时间等计算出获奖几率,并获得一定数量指定积分。主要由 三部分文件组成,主程序文件:luck.php、模板文件 templatesdefaultluck.htm 板文件和图片文件imagesdefault ,增加了一个数据表:cdb_luck。 下面我将 luck.php 和模板文件部分关键代码进行详解,讲解前我先介绍几个必备的 文件和自定义函数。 首先是几乎在所有插件都要用到的文件.php ,这个文件是 Discuz! 核心文件,几乎所有的程序文件都会用到,这个文件主要是一些重要的变量进行初始化以及 赋值,调用常用的自定义函数,以及一些共用程序。并且在里面对用户登陆以及相关操作做 了处理,具体的代码这里就不详细分析了,大家可以到 上找到详解的 文章。 其次就是几个自定义函数了: functionshowmessage($message, $url_forward 这个函数的主要作用就是返回提示信息,参数变量有三个:$memssage 要返回的提示信息,支持 html $url_forward返回提示信息后跳转的 url $extra其他参数,主要有两个 HALTED NOPERM,其中 NOPERM 是比较常用的,是 当一个用户没有权限时候,用这个参数会自动出现无权限页面以及要求登陆的界面。 这个函数使用还有一个小技巧,就是当 $memssage 包含“返回”这个字样的时候,无 需填写 $url_forward 变量,会自动返回上一页。 2、function submitcheck($var, $allowget 主要作用验证表单提交是否合法,Discuz! 系统中为了防止非法表单提交,所有的表 单提交页面都会有一个隐藏 input formhash,这个 hash 是根据一些用 户资料经过加密生成的,主要验证该用户的表单提交动作是否合作。这个函数在有表单提交 的时候会经常用到。 这个函数的参数变量有四个: $var 提交 submit $allowget这个表单是否允许 get 方式提交; $seccodecheck 提交表单是否需要验证码; $secqaacheck 提交表单是否需要验证问题。 functiontemplate($file, $templateid $file要生成模板的文件名(不包括扩展名)这个指的是上面所说的模板文件; $templateid 指定模板 ID Discuz!系统支持多套模板,每个模板都有对应的 ID ,这里可以指定某套模板的 id 下面的某个模板文件,一般不需要填写; $tpldir 模板文件目录,这个一般情况下也不用填写。 因为Discuz!的模板最终会编译成 PHP 文件,所以在用这个函数的时候,还需要引用 一下,一般用 PHP include函数引用。 4、严格说这个是一个 class ,主要用于一些数据库操作,比较多,这里就不一一描 述了,大家可以自己看 includedb_mysql.class.php 文件,简单说 两个常用: $db-query(“$sql”) 执行某一特定的 SQL 语句,支持几乎所有的 MYSQL 常用语 SQL语句的结果输出为数组,主要用于 SELECT 操作。 最后还要提一下一些在插件中可能用到的, Discuz! 系统中一些全局变量: $discuz_uid 用户 uid $discuz_user 用户名 $tablepre 数据表前缀 $timestamp 当前时间(时间戳形式) 说了这么多了,下面我们来看具体代码,我会把程序中每行代码做解释,希望大家能获 得一点启发吧 require_once .includecommon.inc.php; 这行代码就是前面说的 common.inc.php 这个系统核心文件的引用,几乎所有插件 都会用到。 代码如下: 以下为引用的内容: if(!$discuz_uid) showmessage(not_loggedin,NULL, NOPERM); 这段的含义是当程序发现访问者是游客时,自动会提示无权访问,请登陆的界面,在Discuz! 里面是通过 common.inc.php 做处理,然后给 $discuz_uid 这个变量赋 值,当这个变量为空或者为 时,程序会认为这个访问者是游客,否则这个变量将被赋值为该会员的 uid 。和这个变量类似的还有 $discuz_user 这个是用于显示会员用户名 的,如果为空也说明访问者为游客。 代码如下: $startdate 2007-02-17;开始日期,填写格式2007-02-17 $enddate 2007-02-24;结束日期,填写格式2007-02-24 $joincount 30;可以参与抽奖的次数 $getcredit 增加扩展积分1~8$mincredit 获得积分的最小值$maxcredit 100;获得积分的最大值 这段代码是一些程序里面用到的设置变量,如果你的插件有后台程序可以把这些变量放 到后台进行设置,然后写到数据库或者缓存为文件。 代码如下: 以下为引用的内容: if(empty($getcredit) $getcredit 里面的条件时,就会跳到提示页面,提示:积分设置有问题,请返回修改,大家注意这个的提示语言有“返回”的字样,这 样我们不需要在填写提示后返回的页面。 Showmessage 会自动生成返回上一页的连接。 代码如下: 以下为引用的内容: $starttime ($timeoffset3600); $endtime ($timeoffset3600); if($startdate $enddate) elseif($timestamp$starttime) elseif($timestamp$endtime) showmessage(活动已经结束了,index.php); 这段代码主要是对抽奖这个活动开始和结束时间做了计算,把标准时间格式转换为UNIX 时间戳。并对开始结束时间和当前时间做比较,返回一些错误情况的提示信息。 代码如下: 以下为引用的内容: $query $db-query(SELECTCOUNT(uid) joinnum,SUM(credits) creditsFROM {$tablepre}luck); $total $db-fetch_array($query);$query $db-query(SELECTcount, credits FROM {$tablepre}luck WHERE uid=$discuz_uid); if($luck $luck[count];$remaincount 从这段开始涉及到一些数据库的查。
Discuz! 插件开辟
本文来自网络,不代表主机宝贝立场,转载请注明出处:http://www.idcbaby.com/1858/