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

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

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

页面中图片如何等比显示

页面中很多时候都需要图片显示其原样,但是有时候图片实际大小与页面中显示区域的大小又有差距,这个怎么办?只有图片等比显示(只是等比缩小,不会等比放大,因为放大会失真,我想哪个产品经理都不想要这样的结果)
虽然之前项目中多次用到,但是没有保存起来,这里就显摆显摆,以后直接复制就可以哦。

用到的Javascript代码如下:
<script type="text/javascript">
function imgsizeauto(obj, width, height) {
	var img = new Image();
	img.src = obj.src;
	
	var realwidth = img.width;
	var realheight = img.height;
	var w_diff = realwidth - width;
	var h_diff = realheight - height;
	if(w_diff > 0 || h_diff > 0) {
		if(w_diff > h_diff) {
			obj.style.width = width + "px";
			obj.style.height = "auto";
		} else {
			obj.style.height = height + "px";
			obj.style.width = "auto";
		}
	} else {
		obj.style.width = "auto";
		obj.style.height = "auto";
	}	
}
</script>
在HTML中像如下这样调用
<img src="C:/Pictures/51syj3j.jpg" width="100" height="200" onload="imgsizeauto(this, 100, 200)" />
<img src="C:/Pictures/Desert.jpg" onload="imgsizeauto(this, 200, 100)" />

需要注意的是:
1. 一定要把这两个示例代码在页面中载入的次序调整对,如果按照上面的写法,那就必须先载入Js 代码,然后才可以写这个<img>,否则会提示脚本错误哦。
2. 为了完全控制图片不乱跑,可以在样式里初始化的时候控制这个<img> 的宽高,或者是标签里加上 width ,height 属性值,虽然在加载的时候图片可能是模糊的,但是那个时间不会超过0.5秒,所以不必多虑。
3. 上面函数的第一个参数值:当前img对象;第二个参数:控制图片显示的最大宽度(不想让它超过这个宽度);第三个参数:控制图片显示的最大高度(不想让它超过这个高度)。

20
Mar 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS 4 Comments

命令行下执行curl类函数报错,而从浏览器执行却正常

在国内,WAMP集成开发环境成了大多数php选手的第一选择。过于人性话的点击就可以实现自己想要处理的事情,但是这背后却让开发者变的越来越愚昧,越来越迟钝。 今天写了一个脚本,想让他在命令行下执行,却提示:
D:\WAMP\www\gzmama\appcron>php activity.php
Fatal error: Call to undefined function curl_init() in D:\WAMP\www\gzmama\appcro
n\source\class\class_appclient.php on line 50 
而通过直接在浏览器的地址栏输入相应地址执行却完全正常,因为我之前在 WAMP->PHP settings->php_curl 打钩了,这个在情理之中,可以理解。 然后通过phpinfo(),查看详细信息,发现了一行很重要的配置
Loaded Configuration File	D:\WAMP\Apache2\bin\php.ini
很显然,通过浏览器执行脚本的时候,是载入的上面这个路径下的php.ini,而在命令行下确实载入的 D:\WAMP\php\php.ini 。通过打钩选择,修改的是 D:\WAMP\Apache2\bin\php.ini , 所以直接打开 D:\WAMP\php\php.ini
;extension=php_curl.dll 
把上面一行最前面的 “;”去掉即可。
6
Mar 2012
AUTHOR WiFeng
CATEGORY Web
COMMENTS No Comments