Discuz! X2.5 添加自定义数据调用模块(简单方法)

Discuz!X系列的diy功能还是相当不错的,在对其进行二次开发的过程中,或许需要加入新的数据调用模块,这样可以使你开发的功能模块也像原来的模块一样,只需要点点鼠标,填写一些简单的信息,就可以在各个页面的各个位置显示你想显示的数据啦。

以下就目前最新版X2.5做一个简答的介绍:
大致可以分为以下三个步骤:
一、添加数据调用程序
二、后台更新diy模块分类缓存
三、添加相应的数据模板

具体操作如下:
一、添加数据调用程序
1> 在  source/class/block/ 目录下新建文件夹如 :news
2>
在news文件夹下,新建 blockclass.php,内容如下:

<?php
if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}
$blockclass = array(
	'name' => lang('blockclass', 'blockclass_resource'),
);
?>

再在news文件夹下,新建 block_news.php,内容如下:

<?php
if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}

class block_news extends discuz_block {
	
	public $setting = array();

	public function block_news() {
		$this->setting = array(.........); //这儿对setting进行初始化
	}
	
	public function name() {
                // 这儿设置数据来源
		return lang('blockclass', 'blockclass_news_script_news');
	}
	
	public function blockclass() {
                // 这儿设置调用模块类型
		return array('news', lang('blockclass', 'blockclass_news'));
	}
	
	public function fields() {
		$fields = array(.........); //这儿对fields进行设置,除了discuz本身支持的变量外,只有这儿设置的字段才可以在模板中调用。
                return $fields;
	}
	
	public function getsetting() {
		return $this->setting;
	}

	public function getdata($style, $parameter) {
		$list = array(.........);  // 这儿根据实际情况从数据库或许相应的数据
                return array('html' => '', 'data' => $list);
	}
}

?>

以上代码中 lang(....),均为语言处理,这里略过。还有 $setting,$fields,$list的格式可以参考 source/class/block/member/block_member.php中对应变量的格式。

二、进入后台-工具-更新缓存,一定要勾选“DIY 模块分类缓存”,然后开始更新。

三、进入后台-门户-模块模板,在这个下添加你对应的模板。

以上,只是简单说明,~~,因时间有限,只能到此为止啦。。。。。

22
May 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 10 Comments

preg_replace的/e修饰符妙用与慎用

preg_replace — 执行正则表达式的搜索和替换
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit ] )
在 subject 中搜索 pattern 模式的匹配项并替换为 replacement 。如果指定了 limit ,则仅替换 limit 个匹配,如果省略 limit 或者其值为 -1,则所有的匹配项都会被替换。

特别注意:
/e 修正符使 preg_replace() 将 replacement 参数当作 PHP 代码(在适当的逆向引用替换完之后)。提示:要确保 replacement 构成一个合法的 PHP 代码字符串,否则 PHP 会在报告在包含 preg_replace() 的行中出现语法解析错误。
在Discuz程序中很聪明的利用了这个“e”,比如说在生成模板缓冲的时候,部分php代码执行了,而部分php代码未执行。如下代码:

$template = preg_replace("/([\n\r]+)\t+/s", "\\1", $template);
$template = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}", $template);
$template = preg_replace("/\{lang\s+(.+?)\}/ies", "\$this->languagevar('\\1')", $template);
$template = preg_replace("/[\n\r\t]*\{block\/(\d+?)\}[\n\r\t]*/ie", "\$this->blocktags('\\1')", $template);

可以看出文字替换就是提前处理了。
上面的这种写法完全可以用下面的方式,显得更加易读易懂

$template = preg_replace("/\{lang\s+(.+?)\}/is", $this->languagevar('\\1'), $template);
在有这些好处的同时,这个"e"往往在不注意的情况下很容易产生漏洞,还请慎用。下面举例说明:

比如说某程序文件中有这样的写法

<?php
function test($str){
	//......
	//......
	return $str;
}
echo preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", 'test("\1")', $_GET["h"]);
?>

提交 ?h=[php]phpinfo()[/php]phpinfo()会被执行吗?
肯定不会。
因为经过正则匹配后, replacement 参数变为'test("phpinfo()")',此时phpinfo仅是被当做一个字符串参数了。
有没有办法让它执行呢?
当然有。
在这里我们如果提交?h=[php]{${phpinfo()}}[/php]phpinfo()就会被执行。
为什么呢?
在php中,双引号里面如果包含有变量,php解释器会将其替换为变量解释后的结果;单引号中的变量不会被处理。
注意:双引号中的函数不会被执行和替换
在这里我们需要通过{${}}构造出了一个特殊的变量,'test("{${phpinfo()}}")',达到让函数被执行的效果 ${phpinfo()} 会被解释执行。

phpinfo() 可以获取到服务器端的各种信息,方便进一步攻击,所以这是每个网站基本应该预防的一点。

如何避免出现上面的漏洞呢?
可以把上面的代码这样写,用户就没有办法攻击了

echo preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", "test('\\1')", $_GET["h"]);

上面的内容仅供学习参考,并无任何恶意。

上面的程序还有一点点小的区别哦,看下面两行代码对比

echo preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", "test('\1')", $_GET["h"]);
//下面两行代码替换是等价的,注意单引号与双引号
echo preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", "test('\\1')", $_GET["h"]);
echo preg_replace("/\s*\[php\](.+?)\[\/php\]\s*/ies", 'test("\1")', $_GET["h"]);


17
May 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 2 Comments

Mysql Explain 语法详细解析

结合实例,详细解释了如何使用mysql explain进行查询优化。

17
May 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 1 Comment

送你十句改变你命运的话

    第一句:“人都是逼出来的”。每个人都是有潜能的,生于安乐,死于忧患,所以,­ 当面对压力的时候,不要焦燥,也许这只是生活对你的一点小考验,相信自己,一切都能 处理好,逼急了好汉可以上梁山,时世造英雄,穷者思变,人只有压力才会有动力。

    第二句:“如果你简单,这个世界就对你简单”。简单生活才能幸福生活,人要自足常乐, 宽容大度,什么事情都不能想繁杂,心灵的负荷重了,就会怨天忧人。要定期的对记忆进行一次 删除,把不愉快的人和事从记忆中摈弃,人生苦短,财富地位都是附加的,生不带来死不带去,­ 简简单单的生活就是快快乐乐的生活。­

   第三句:“人生没有彩排,每一天都是现场直播”。偶尔会想,如果人生真如一场电子­ 游戏,玩坏了可以选择重来,生活会变成什么样子?正因为时光流逝一去不复返,每一天都不 可追回,所以更要珍惜每一寸光阴,孝敬父母、疼爱孩子、体贴爱人、善待朋友。­

   第四句:“怀才就象怀孕,时间久了会让人看出来”。人,切莫自以为是,地球离开­ 了谁都会转,古往今来,恃才放肆的人都没有好下场。所以,即便再能干,也一定要保持谦虚 谨慎,做好自己的事情,是金子总会发光。­

   第五句:“过去酒逢知已千杯少,现在酒逢千杯知已少”。不甚酒力,体会不了酒的美味, 但却能感受知已的妙处。没有朋友的人生是孤独的,不完整的,可是,因为生活的忙碌,渐渐少­ 了联络,友谊就变的淡了,所以,抽点时间,联络朋友一起聊聊天,让情谊在笑声中升腾,当­ 朋友遇到了难题的时候,一定要记得挺身而出,即便帮不了忙,安慰也是最大的支持。­

   第六句:“人生如果错了方向,停止就是进步”。人,总是很难改正自己的缺点,人, 也总是很难发现自己的错误,有时,明知错了,却欲罢不能,一错再错,把握正确的方向, 坚守自己的原则,世界上的诱惑很多,天上永远不会掉馅饼,不要因为贪图一时的快乐而­ 付出惨痛的代价,如果发现错了,一定要止步。­

   第七句:“人生两大悲剧:一是万念俱灰,一是踌躇满志”。现代的人好象特别脆弱, 报纸上天天报道众多名人得抑郁症,这些人一定是从一个极端走向别一个极端。正因为踌躇 满志,才坚信自已是完美的,是无所不能的,如果受到一点挫折,就会变得极度自卑,甚至­ 失去继续生活的勇气。为自己找一个准确的定位,享受生活乐趣。­

   第八句:“人生和爱情一样,错过了爱情就错过了人生”。爱情是什么?让人无所适 从,让人神魂颠倒,面对爱情的时候,勇敢一点,大胆说出自己的爱,有花堪摘直须摘,莫待 无花空折枝。人,总会生老病死,怎么过都是一生,错过了爱情就错过了生命的精彩。­

   第九句:“天下有钱人终成眷属”。现代社会的人变得越来越势利,爱情也越来越无足轻 重,于是我不得不相信“天下有钱人终成眷属”就对现代爱情的最确切的描述。­

   第十句:“要成功,需要朋友,要取得巨大的成功,需要敌人”。有竞争才有发展,因为 有了敌人的存在,因为有了不服输的决心,才会努力的做好自己的事,所以,有时候,敌人比­ 朋友的力量更大,天下没有永远的敌人,却有永远的朋友,有些时候,敌人也可以变成朋友。

28
Apr 2012
AUTHOR WiFeng
CATEGORY Jotting
COMMENTS 1 Comment

typecho 及时邮件通知(回复)插件

一直被模仿,从未被超越。
对于大多数博客主来说评论是非常宝贵的数据,因为听取别人的意见或建议可以使你走的更远更正确。在别人对你所发的文章进行评论之后,这些评论可能是别人的疑惑之处想请您讲解,所以这时你就需要认真来对这些评论进行回复,当然别人也可以回复啊。有个对于原评论者来说非常不友好的体验就是他不知道你是否回复了他的评论,这时你只需轻点几下鼠标把这个插件安装就可以了。

插件安装:
1. 到以下下载地址下载插件压缩包,解压之后把TimelyNotice这个文件夹复制到你的站点下的 usr/plugins/ 目录下。
2. 打开管理后台,激活该插件。
3. 这步就是对发送邮件的详细配置了。参数具体说明如下:
通知功能:如果关闭,将不会进行提醒,但是可以继续保存您对以下项的设置。如果开启,将需要正确填写以下各项。
SMTP地址:就是发送邮件的服务器。对于普通用户来说肯定没有自己的邮件服务器,很多人还是使用163 qq sina 这些邮件服务器来发送邮件。比如如果你的邮箱是:xxx@163.com  那么你可以在这里填写 smtp.163.com 。如果你的邮箱是:xxx@qq.com 那么你可以在这里填写 smtp.qq.com
SMTP端口:邮件系统使用的端口,一般情况下是 25。
发送者名称:这个就是你想展示给用户的邮件名称,可以自己定义
发送者Email地址:这个就是你想使用哪个账号来替你发送这些邮件,比如我的是noreply@521-wf.com。这个需要与上面的SMTP地址对应。
SMTP密码:上面填写的这个邮箱的登录密码
发送超时时长:如果你使用的发送邮箱服务器响应比较慢,可以把这个值稍微调大点。
邮件主题:这个就是发送给用户的邮件标题了,可以自定义,其中内容可以使用一些支持的标签。具体标签,见设置项下给出的提示。
邮件内容:这个就是发送给用户的邮件内容了,可以自定义,也可以支持一些标签。当然可以图文并茂,这就看你的设计了。

以下为更新记录,及时关注更新哦

已更新到1.0.1版本(2012-04-27)
优化:禁用插件时删除一些有关该插件的残余信息

已更新到1.1.0版本(2012-06-16)
优化:把iframe隐藏标签替换为script,这样可以对搜索引擎更友好

已更新到2.0版本(2012-09-03
修正:后台管理员回复评论,不发邮件通知bug
优化:默认邮件模板显示

最新版本下载(github) 
名称:KindEditor 
地址:https://github.com/WiFeng/typecho-plugin/

25
Apr 2012
AUTHOR WiFeng
CATEGORY Asset
COMMENTS 45 Comments

Discuz! X2.5 的 forum_thread 和 forum_post 表的各标记位字段对应的值的说明

forum_thread 的 status 字段备注 (位运算存储 0x0000 - FFFF 总共支持16个标志位,其中)
  6543 2109 8765 4321 序号
#B 0000 0000 0000 0001 是否缓存帖子位置信息
#B 0000 0000 0000 0010 是否回帖只对管理人员和发帖者可见
#B 0000 0000 0000 0100 是否抢楼贴
#B 0000 0000 0000 1000 是否倒序查看回帖
#B 0000 0000 0001 0000 是否存在主题图章标志位
#B 0000 0000 0010 0000 回复是否通知作者
#B 0000 0000 0100 0000 是否需要推送到QQ空间
#B 0000 0000 1000 0000 是否需要推送到腾讯微博
#B 0000 0001 0000 0000 是否被收入专辑
#B 0000 0010 0000 0000 是否被转播
#B 0000 0100 0000 0000 [手机标识(联动)] 001(1):含手机文本
#B 0000 1000 0000 0000 [手机标识(联动)] 010(2):含地理位置 011(3):含手机照片
#B 0001 0000 0000 0000 [手机标识(联动)] 100(4):含手机录音
#B 0010 0000 0000 0000 是否成功推送到腾讯微博

forum_thread/forum_post 的 attachment 字段备注
0        无附件
1        有附件
2        有图片附件

forum_thread 的 displayorder 字段备注
4        跨版块置顶
3        3级置顶
2        2级置顶
1        1级置顶
0        正常
-1        回收站
-2        审核中
-3        审核忽略
-4        草稿

forum_post 的 status 字段备注 (位运算存储 0x00000000 - FFFFFFFF 总共支持32个标志位,其中)
  2109 8765 4321 0987 6543 2109 8765 4321 序号
#B 0000 0000 0000 0000 0000 0000 0000 0001 帖子被屏蔽
#B 0000 0000 0000 0000 0000 0000 0000 0010 帖子被警告
#B 0000 0000 0000 0000 0000 0000 0000 0100 帖子审核后再编辑标记,用于防止重复加分
#B 0000 0000 0000 0000 0000 0000 0000 1000 手机版发帖标示
#B 0000 0000 0000 0000 0000 0000 0001 0000 微博回流的帖子标记
#B 0000 0000 0000 0000 0000 0000 0010 0000 [手机]是否显示地理位置
#B 0000 0000 0000 0000 0000 0000 0100 0000 [手机]含手机录音
#B 0000 0000 0000 0000 0000 0000 1000 0000 [手机型号(联动)] 001(1):iOS
#B 0000 0000 0000 0000 0000 0001 0000 0000 [手机型号(联动)] 010(2):Android 011(3):WindowsPhone
#B 0000 0000 0000 0000 0000 0010 0000 0000 [手机型号(联动)] 100:

forum_post 的 invisible 字段备注
0        正常
-1        回收站
-2        审核中
-3        审核忽略/草稿
-4        N/A
-5        回收站回帖

25
Apr 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 5 Comments

Js中window.onload会覆盖

之前好长时间都注重项目的开发,没有整理一些知识要点,是不是有点自私,其实这是一种懒惰。闲话完毕,转入正题。在前些日子开发完typecho的验证码插件(seccode)之后,在后台的该插件设置页面中加了一个window.onload函数来处理一些事件。但是过了一天,感觉这个好像会被其他插件覆盖,那么这段代码将不会执行,显然这不是我们想要的。

下面代码说明:
<script type="text/javascript">
window.onload=function() {
	alert(123);
}

window.onload=function() {
	alert(345);
}
</script>
上面的程式将会弹出 345,显然可以说明一个问题,函数覆盖了。
接着看下面的代码:
<script type="text/javascript">
window.attachEvent('onload', function(){
	alert(123);
});
window.attachEvent('onload', function(){
	alert(345);
});
</script>
上面的程式将会先弹出 345,然后弹出 123。这说明函数没有覆盖掉,不过要注意是先执行最后绑定的事件。但是这个代码只有在ie下可执行,在FF,chrome下是不行的。
继续往下看,下面的代码将完美实现window.onload不覆盖问题:
<script type="text/javascript">
function fun1() {
	alert(123);
}
function fun2() {
	alert(345);
}
if(document.all) {
	window.attachEvent('onload', fun2);     //注意这里是 fun2
	window.attachEvent('onload', fun1);
} else {
	window.addEventListener('load', fun1);  //注意这里是 fun1
	window.addEventListener('load', fun2);
}
</script>

为了让ie浏览器与其他浏览器,比如chrome,Firfox得到相同的执行结果,请注意区分上面的几行代码。在ie下是先执行后绑定的事件函数,而在其他浏览器中却是先执行先绑定的事件函数,所以这里写的顺序不一样,但是执行结果一样的,都是先执行fun1这个函数。

31
Mar 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 2 Comments

typecho 绚丽验证码插件(功能齐全)

typecho灌水机好多好多,没有专门放外链,竟然被灌水机发现了。刚开始没发现,过了几天,评论达到数百条,全部是垃圾。typecho后台有个限制设置,可以在一定的程度上加以控制,但是这样的方法太死板,属于一刀切。于是抽了点时间把Discuz中的验证码功能转换成了typecho插件。
可设置的类型:1. 英文图片验证码;2. 中文图片验证码;3. Flash验证码;4. 位图验证码。
对于中、英文验证码可自定义设置项很多,这里就不一一罗列了,要多酷,有多酷,决定权让给你。

阅读剩余部分...

29
Mar 2012
AUTHOR WiFeng
CATEGORY Asset
COMMENTS 34 Comments

Js与PHP中同一个表达式的差异

在好多编程语言中,各自的语法可能会不同,这很正常。不过,运算符之间的差异就需要仔细探讨了,如果不清晰的理解这些微小的差异,很容易混在一起,就会写出可能有bug的程序,这是很严重的问题,这也不是一个“高手”的作风,所以摘出来,分享,研究研究。
谁能更好的解释这一点,不胜感激。

Js 代码如下:
<script>
function fun(script) {
	script = script || 'common_extra';
	alert(script);  
}
fun('common');   //alert common
</script>
PHP代码如下:
<?php
function fun($script) {
	$script = $script || 'common_extra';
	var_dump($script);
}
fun('common');   //output bool(true) 
?> 

28
Mar 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 5 Comments

解读php中clone方法的适用场合

在php语言中,对象之前相互传递是传其引用,如下:
<?php
class stu {
	public $age;
}

$s1 = new stu();
$s1->age = 2;

$s2 = $s1;
$s2->age = 3;

echo $s1->age;  //output 3
?>
从上面可以看出,$s1,$s2 指向是相同的,修改其中一个的属性值,另一个对应的属性值也在跟着变。普通的变量则是直接重新拷贝一份给其传递,如果对象之间想要实现这种结果,可以的,这就是clone的作用了。如下:
<?php
class stu {
	public $age;
}

$s1 = new stu();
$s1->age = 2;

$s2 = clone $s1;
$s2->age = 3;

echo $s1->age;  //output  2
?>
综上所述,如果想复制一个对象,那就用 clone(克隆)吧,普通的 等号(=) 赋值不是真正的复制,而是把指针指到同一块区域了。
26
Mar 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 1 Comment