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