存档

2010年8月 的存档

php性能测试工具:xhprof

2010年8月31日 effect 没有评论

以前最常用的工具是是xdebug加上Webgrind来检测,效果也不错。现在推荐另外一个工具:xhprof,facebook开源的工具。
最主要的是他提供了一个WEB方式的UI界面,提供的参数有:相应时间,内存占用,函数调用次数等,还有把每个函数调用的次数、执行时间和内存占用都有列出,让你一目了然,知道瓶颈在什么地方,看图说话:

请求总揽

函数调用情况

看到上面的效果是不是有点心动呢?开始进入正题。

安装

从pecl下载安装包,下载地址:http://pecl.php.net/get/xhprof-0.9.2.tgz

开始标准化的安装流程:

tar -zxvf xhprof-0.9.2.tgz
cd xhprof-0.9.2
/usr/local/php5.3/bin/phpize
./configure --with-php-config=/usr/local/php5.3/bin/php-config
make
make install

然后在你的php.ini加上:

extension=xhprof.so
[xhprof]
xhprof.output_dir=/data/tmp/ #日志文件保存路径

现在可以看看phpinfo();是不是已经有了xhprof的信息。到这里,安装就完成了。

应用

看官方推荐的标准例子:

// start profiling
xhprof_enable();
 
// run program
//这里就是你要检测的代码段,拿kohana为例,应该是:
require SYSPATH.'core/Bootstrap'.EXT;
// stop profiler
$xhprof_data = xhprof_disable();
 
//
// Saving the XHProf run
// using the default implementation of iXHProfRuns.
//
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_lib.php";
include_once $XHPROF_ROOT . "/xhprof_lib/utils/xhprof_runs.php";
 
$xhprof_runs = new XHProfRuns_Default();
 
// Save the run under a namespace "xhprof_foo".
//
// **NOTE**:
// By default save_run() will automatically generate a unique
// run id for you. [You can override that behavior by passing
// a run id (optional arg) to the save_run() method instead.]
//
$run_id = $xhprof_runs->save_run($xhprof_data, "kohana");
 
echo "---------------\n".
     "Assuming you have set up the http based UI for \n".
     "XHProf at some address, you can view run at \n".
     "http://<xhprof-ui-address >/index.php?run=$run_id&source=kohana\n".
     "---------------\n";

这样每次访问这个脚本,都会在底部打印出类似这样的:————— Assuming you have set up the http based UI for XHProf at some address, you can view run at http:///index.php?run=4c7cd4869704f&source=kohana ————— 。这个是告诉你可以通过他的提供的工具来查看这次请求的分析结果,看第一步下载的xhprof-0.9.2解压后,里面有个文件夹xhprof_html,这里就是提供给我们看的工具。

查看结果
这里提供一个简单的方法,赋值xhprof_html和xhprof_lib到你的web目录,然后访问:http://your.domian/xhprof_html/index.php?run=4c7cd4869704f&source=kohana
是不是看到了和上面截图类似的界面,到这里就完成了。

查看资料:http://www.162cm.com/p/xhprofdoc.html

分类: php, 性能优化 标签: ,

编写php扩展入门流程

2010年8月21日 effect 1 条评论

本文是在PHP5.2版本下试验,操作系统为centos。

废话不多说了,直接按步骤来。

第一步:安装PHP

去下载PHP的源码包,本文的源码包在所在路径为:/root/php-5.2.13,直接编译安装,安装过程不多说,如果你不清楚去网上搜索下,教程一大把。我安装在/usr/local/myphp/目录

第二步:新建一个扩展

网上的教程有,是用ext目录下的ext_skel脚本生成:

# cd /root/php-5.2.13/ext/
# ./ext_skel --extname=yzmf

上面这两行命令是生成了一个名称为yzmf的扩展。好了,按照教程要修改配置文件:

#cd yzmf   //进入目录:/root/php-5.2.13/ext/yzmf
#vi config.m4

阅读全文…

分类: php, 文档记录 标签:

kohana整合smarttemplate

2010年8月20日 effect 没有评论

什么是kohana?

Kohana 是一款纯 PHP5 的框架,基于 MVC 模式开发, 它的特点就是高安全性,轻量级代码,容易使用。

什么是smarttemplate?

一个轻量级的PHP模板引擎。教程见:http://bbs.chinaunix.net/viewthread.php?tid=593973

为什么要整合?

实在受不了模板里面还有那么多的$ <?php 这种符号,模板里面应该是要刨除掉这些php特有的符号。
阅读全文…

分类: php 标签:

web项目中的虫洞

2010年8月19日 effect 没有评论

虫洞?看看爱因斯坦对虫洞的定义:“虫洞”就是连接宇宙遥远区域间的时空细管。暗物质维持着虫洞出口的敞开。虫洞可以把平行宇宙和婴儿宇宙连接起来,并提供时间旅行的可能性。虫洞也可能是连接黑洞和白洞的时空隧道,所以也叫”灰道”。看起来虫洞就是连接两个距离很远的物体。在我们的WEB项目中会存在这种情况吗?

假设你有一个域名:domain.com。现在主站是www.domain.com。好了,还有一个博客的子域名:blog.domian.com。现在有个需求:要在主站上调用博客子站里面的数据,而且是客户端(通俗的说是页面上)调用。你想到的有几种方式?这个是不是两个感觉很远的物体,好了,让我们来制造一个虫洞来连接这两个跨域的站点。

虫洞一:iframe

是的,iframe在不跨域子域的情况下完全可以互通。假如现在你要在http://www.domian.com/parent.html和http://blog.domain.com/child.html互通,那么在parent.html里面嵌入一个iframe,id为child,src指向child.html。只要满足一个条件:在两个页面上都这样设置:

document.domain='domain.com'

。这样设置之后两个页面的JS对象完全可以互通。在parent.html里面获得child.html的window对象:

var obj=document.getElementById('child').contentWindow

。这样obj对象就是child.html里面的window对象了,有了这个对象可以操作child.html里面的任何东西。在child.html里面操作parent.html更加方便:parent对象就是parent.html的window对象。

上面所说的iframe虫洞只能适用一些简单的需求,但是我接来下所说的一些却是以这个为基础的。 阅读全文…

分类: javascript, 文档记录 标签:

轻量级JS框架:kissy介绍

2010年8月18日 effect 没有评论

kissy好像是淘宝开源出来的JS框架,官方更愿意称之为ui library。提供一些基本的dom操作,event util,cookie等。最惊艳的是datalazyload模块,真的非常非常的实用。不足的地方ajax方面还没整合进去,相信不久就会出来。

作为一个js框架,难免会拿来和目前非常火爆的Jquery来做比较,Jquery目前发展到1.4版本,比较稳定,而且新版本在性能上也有所提升,而且还有非常多的插件提供。但是kissy和jquery不同的是:在Jquery的世界里,都是Jquery对象,但是kissy没有这个概念,比如选择器:S.query(‘.date’) 这里得到的是一个数组对象,每个元素都是标准的dom对象。比如给所有的a标签增加一个class:DOM.addClass(‘a’, ‘val’)。这样感觉更像在操作DOM,而不是Jquery对象,给人的感觉更加亲近原生的JS,而不像Jquery那样和原生的JS隔离的那么远。

文档地址:http://kissyteam.github.com/kissy/docs/
源码地址:http://github.com/kissyteam/kissy

分类: javascript 标签:

Kohana之Layout

2010年8月14日 effect 没有评论

kohana是一款基于php5(5.2)的框架,MVC的模式,高安全性,代码轻量级。但是kohana并没有提供layout,至少我熟悉的2.3版本没有。在实际的开发过程中感觉到没有layout还真有点别扭,就想到自己开发一个layout的库类。

通过看kohana的手册和代码,了解到kohana是基于事件驱动的框架,输出之前的事件为system.display。所以可以添加一个这样的事件,在事件注册的方法中改变Kohana::$output的内容即可。库类代码如下: 阅读全文…

分类: php 标签:

代码分享之图片延迟载入

2010年8月10日 effect 没有评论

对于图片很多,而且很长的页面,也许第三屏后面的很少有用户滚动下去查看。如果图片也照样载入的话,是不是觉得有点浪费带宽,也浪费图片服务器的连接数。这个时候延迟载入很重要,按需载入。PV越大的效果越明显,废话少说,先看代码:

var LAZY=(function(){
	var pResizeTimer = null;
	var imgs={};
	function addEventHandler (oTarget, sEventType, fnHandler) {
		if (oTarget.addEventListener) {
			oTarget.addEventListener(sEventType, fnHandler, false);
		} else if (oTarget.attachEvent) {
			oTarget.attachEvent("on" + sEventType, fnHandler);
		} else {
			oTarget["on" + sEventType] = fnHandler;
		}
	};
	function resize(){
		if(pResizeTimer) return '';
		pResizeTimer = setTimeout(function(){
							resize_run();
							try{
								clearTimeout(pResizeTimer);
							}
							catch(e){}
							pResizeTimer=null;
						}, 100);
	}
	function resize_run(){
		var min={};
		var max={};
        min.Top = document.body.scrollTop + document.documentElement.scrollTop;
		min.Left=document.documentElement.scrollLeft;
		max.Top=min.Top+document.documentElement.clientHeight;
		max.Left=min.Left+document.documentElement.clientWidth;
 
		for(var i in imgs){
			if(imgs[i]){
				var _img=imgs[i];
				var img=document.getElementById(i);
				var width = img.clientWidth;
				var height = img.clientHeight;
				var wh=position(img);
				if(
					(wh.Top>=min.Top && wh.Top<=max.Top)
					||
					((wh.Top+height)>=min.Top && wh.Top<=max.Top)
				)
				{
					img.src=_img.src;
					delete imgs[i];
				}
 
			}
		}
	}
 
	function position(o){
		var p={Top:0,Left:0};
		while(!!o){
			p.Top+=o.offsetTop;
			p.Left+=o.offsetLeft;
			o=o.offsetParent;
		}
		return p;
	}
 
	return {
		init:function(){
			for(var i=0;i<document.images.length;i++){
				var img = document.images[i];
				var config={};
				config.id = img.id;
				config.src = img.getAttribute('_src');
				if(config.src && !config.id){
					config.id = encodeURIComponent(config.src) + Math.random();
					img.id = config.id;
				}
				if(!config.id || !config.src) continue;
				LAZY.push(config);
			}
			return LAZY;
		},
		push:function(config){
			imgs[config.id] = config;
		},
		run:function(){
			resize_run();
			addEventHandler(window,'scroll',resize);
		}
	};
})();

使用方法很简单,2个步骤:
1 img的标签的src属性指向一个空地址,或者一个1×1的空白图片,_src属性指向实际图片地址,如:

<img src="" _src="path/to/img.jpg" />

2 在页面底部或者body onload里面:

LAZY.init().run();

在公司千万级的PV项目上使用了,据说效果不错喔!

分类: javascript 标签:

代码分享之js事件处理

2010年8月7日 effect 1 条评论

此方法提供跨浏览器的事件操作。
提供的API有addEvent、removeEvent、getEvent等。具体的见代码:

var util=util || {};
util.Event = (function(){
	var sUserAgent = navigator.userAgent;
	var fAppVersion = parseFloat(navigator.appVersion);
	var isOpera = sUserAgent.indexOf("Opera") > -1;
	var isMinOpera4 = isMinOpera5 = isMinOpera6 = isMinOpera7 = isMinOpera7_5 = false;
	var isIE = sUserAgent.indexOf("compatible") > -1
           && sUserAgent.indexOf("MSIE") > -1
           && !isOpera;
	var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
 
	return {
		//获得事件对象,比如util.Event.addEvent(dom,'click',function(){var e=util.Event.getEvent();})
		getEvent: function(){
			if (window.event) {
				return util.Event.formatEvent(window.event);
			} else {
				return util.Event.getEvent.caller.arguments[0];//调用此方法的函数的第一个参数
			}
		},
		//获得时间的target,也就是事件的发生地,返回dom对象
		getTarget: function(e) {
			return e.target || e.srcElement;
		},
		//阻止冒泡,比如一个div里面嵌套了一个a,这两个标签都绑定了click事件,如果你想点击a标签的时候并不想执行div上面的click时间。可以用这个方法阻止
		stopPropagation: function(e) {
			if (e.stopPropagation) {
			  e.stopPropagation();
			}
			else {
			  e.cancelBubble = true;
			}
		},
		//阻止默认行为,比如一个a标签绑定一个click事件,如果你想阻止执行此事件之后并不做跳转,可以用这个方法
		preventDefault: function(e) {
			if (e.preventDefault) {
			  e.preventDefault();
			}
			else {
			  e.returnValue = false;
			}
		},
		//阻止冒泡或者捕捉和阻止默认行为
		stopEvent: function(e) {
			this.stopPropagation(e);
			this.preventDefault(e);
		},
		//增加一个事件 util.Event.addEvent(window,'load',function(){})
		addEvent:function (oTarget, sEventType, fnHandler) {
			if (oTarget.addEventListener) {
				oTarget.addEventListener(sEventType, fnHandler, false);
			} else if (oTarget.attachEvent) {
				oTarget.attachEvent("on" + sEventType, fnHandler);
			} else {
				oTarget["on" + sEventType] = fnHandler;
			}
		},
		//取消莫事件的绑定的某个函数
		removeEvent:function (oTarget, sEventType, fnHandler) {
			if (oTarget.removeEventListener) {
				oTarget.removeEventListener(sEventType, fnHandler, false);
			} else if (oTarget.detachEvent) {
				oTarget.detachEvent("on" + sEventType, fnHandler);
			} else {
				oTarget["on" + sEventType] = null;
			}
		},
		//格式化事件对象
		formatEvent:function (oEvent) {
			if (isIE &amp;&amp; isWin) {
				oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
				oEvent.eventPhase = 2;
				oEvent.isChar = (oEvent.charCode &gt; 0);
				oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
				oEvent.pageY = oEvent.clientY + document.body.scrollTop;
				oEvent.preventDefault = function () {
					this.returnValue = false;
				};
 
				if (oEvent.type == "mouseout") {
					oEvent.relatedTarget = oEvent.toElement;
				} else if (oEvent.type == "mouseover") {
					oEvent.relatedTarget = oEvent.fromElement;
				}
 
				oEvent.stopPropagation = function () {
					this.cancelBubble = true;
				};
 
				oEvent.target = oEvent.srcElement;
				oEvent.time = (new Date).getTime();
			}
			return oEvent;
		}
	};
})();
分类: javascript 标签: ,

js日志函数

2010年8月6日 effect 没有评论

console是一个非常好用的日志调试对象,让你告别alert的调试工具。在Firefox中的Firebug插件中存在,在Chrom浏览器的开发工具,IE8的调试工具(启动调试)中。

下面列出这个对象所有的方法:

console.log():记录一行信息,无任何图标提示

console.debug():记录一行信息,带超链接,可以链接到语句调用的地方

console.error():向控制台中写入错误信息,带错误图标显示和高亮代码链接

console.info():向控制台中写入提示信息,带信息图标显示和高亮代码链接

console.warn():向控制台中写入警告信息,带警告图标显示和高亮代码链接

阅读全文…

分类: javascript 标签:

JavaScript中的Error对象

2010年8月6日 effect 没有评论

JS中常用的有Array,Math,Date等对象,但是Error对象不常见吧,现在简单剖析一下。

一 定义

在JavaScript中Error类表示一个异常,是其他异常类的父类,构造一个Error类的基本语法为:

var objError = new Error(message);

Error对象具有name和message两个属性,name表示异常的类型,message表示异常详细信息字符串
JavaScript还预定义了其他一些异常类,这些类都是Error类的子类,如下:
1.EvalError //当不正确使用eval函数时,会抛出EvalError类的一个实例
2.RangeError //当数值超出JavaScript中合法的数值范围时,会抛出RangeError类的一个实例
3.ReferenceError //当读取一个不存在的变量的值时,会抛出ReferenceError类的一个实例
4.SyntaxError //当JavaScript中出现语法错误时,会抛出SyntaxError类的一个实例
5.TypeError //当JavaScript中类型不符合要求时,会抛出TypeError类的一个实例
6.URIError //当字符串不符合编码或解码要求时,会抛出URIError类的一个实例
二、用法
为了说明如何在JavaScript中使用异常机制,我来用代码说明,这样会更加清晰:

try{
   ...
}catch(error){
     throw new Error("对不起,出错啦!");
}
//或者这样:
if(some false){
      throw new Error("对不起,出错啦!");
}
分类: javascript 标签: