Discuz! 链接提示插件

第一个插件终于开发完成了。
下载地址:http://addon.discuz.com/?@linktips.plugin
功能:论坛、微博中的链接,当鼠标滑过时进行提示:打开、复制、举报。后台可以看到举报信息哦,管理员可以根据用户举报的地址进行核对,如果是违法地址,既可以放入黑名单,如果确定是合理的地址,即可放入白名单。

31
May 2012
AUTHOR WiFeng
CATEGORY Web,Asset
COMMENTS 1 Comment

javascript 事件绑定(兼容各种浏览器)

IE中的 attachEvent 函数在添加事件绑定的时候不传递this对象。这让开发者很纠结,不过有政策就有对策。使用如下方法代替事件绑定函数,兼容各种浏览器。

<script type="text/javascript">
function addEvent(o,e,f) {
	if(o.addEventListener) {
		o.addEventListener(e,f,false)
	} else {
		var ctype="_"+e,a,i;
		if(!o[ctype]){
			a=o[ctype]=[];
			o.attachEvent("on"+e,function(evt){
			evt=event;
			evt.target=event.srcElement;
			for(var i=0,l=a.length;i<l;i++)
				a[i].call(o,evt);
			});
		}
		a=o[ctype];
		i=a.length;
		while(i--)if(a[i]==f)return;
		a.push(f);
	}
}

function delEvent(o,e,f) {
	if(o.removeEventListener) {
		o.removeEventListener(e,f,false);
	} else {
		var ctype="_"+e;
		if(o[ctype]) {
			var a=o[ctype],i=a.length;
			while(i--)
			if(a[i]==f) {
			 a.splice(i,1);break;
			}
		}
	}
}
</script>

addEventListener-事件流(小插曲,只是提醒注意这个知识点)
说到 addEventListener 不得不说到事件流,先说事件流对后面的解释比较方便。
当一个事件发生时,分为三个阶段:
捕获阶段 从根节点开始顺序而下,检测每个节点是否注册了事件处理程序。如果注册了事件处理程序,并且 useCapture 为 true,则调用该事件处理程序。(IE 中无此阶段。)
目标阶段 触发在目标对象本身注册的事件处理程序,也称正常事件派发阶段。
冒泡阶段 从目标节点到根节点,检测每个节点是否注册了事件处理程序,如果注册了事件处理程序,并且 useCapture 为 false,则调用该事件处理程序。
上面提到的 useCapture 也就是 addEventListener 的第三个参数了。

还要谢谢Ander的帮助:http://user.qzone.qq.com/81839603/infocenter#!app=2&pos=1319529117

31
May 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 1 Comment

js中document.body.scrollTop始终为0

代码改成 document.documentElement.scrollTop这样就没有问题了。
造成这个的原因是html页面声明了:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
当然这一条还是不能删除的。

27
May 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 2 Comments

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