有多少人了解云计算? what’s Cloud computing

没有评论

2010 年 09 月 27 日 at 下午 7:10分类:WEB开发

再早个十年,你会发现几乎每个大学附近的电脑光盘生意都很火爆,而现在呢?DVD影碟的生意 还算差强人意,但卖电脑光盘可真的赚不到钱了.因为光盘里的东西几乎全部可以从网上免费下载到,那谁还花这个冤枉钱呢?大胆设想一下未来的远景。如果哪个 电脑用户还想使用盗版软件,那么他将在未来的互联网世界寸步难行——因为所有软件都是按点击收费的,在网络带宽足够快的情况下,家中的电脑成为一副“躯 壳”,不再拥有运算功能,所有的一切都由远端的某个超级计算机实现……这绝不是电影《盗梦空间》或《黑客帝国》中营造的幻象,这一切正在真真实实地发生 着.

未来,我们只需要使用一个靠屏幕、键盘与网络接头运作的电脑,再需缴纳一定的费用,就可以像水、电、煤气一样,任意取用这种计算能力,而不再需 要花费高昂的费用购买最新的英特尔(或AMD)芯片和快速的硬盘驱动器来更新系统,虽然我们未来办公桌上还会有一个长得和PC电脑很像的“家伙”,但我们 其实还没给这台未来的“虚拟电脑”取好名字.

云计算
云计算

99%的人不理解“云”

据权威研究机构Gartner预计,到2012年时,在全球财富1000强企业中,80%会通过不同方式使用“云计算”服务.这是一朵越飘越近的“云”,可以看成我们实现未来互联网梦想的第一步.

“云计算”鼎鼎大名,相信90%的人都听说过,在信息科技领域,它比“人脚一双”的Crocs更加流行,几乎每个行业都希望和其沾上边,例如云存储、云安全、云支付等等.可是,对于老百姓来说,究竟什么才是“云计算”,99%仍然“云里雾里”.

按照维基百科的资料照本宣科,“云计算”(英文:Cloud computing)是一种基于互联网的计算新方式,通过互联网上异构、自治的服务为个人和企业用户提供按需即取的计算.由于资源是在互联网上,而在电脑 流程图中,互联网常以一个云状图案来表示,因此可以形象地类比为“云”.

现在我们用电脑,大量运算在本机上进行,如Word编辑、处理图片、玩网络游戏;而未来运算工作都交给“云”了,你可以将“云”看成是一大片计算能力超群的计算机和服务器,它们可以帮助你完成任何复杂的运算,利用超高带宽的互联网,我们只要在家坐享其成就行了.

如果你还不能理解“云”的概念,这里还有一个更加容易理解的比喻.现在的电脑应用方式,就像是在每个人家里都装一台发电机,自己发电给自己用;而将来,只要统一由发电厂发电,再将电力送至你的家里就行,这样方式显然更加省力.

光纤到户拉近“云”距离

回顾过往,2006年前谷歌首次提出“云计算”理念,紧接着,IBM推出了“蓝云计划”,将这个概念成功推向市场.之后,“云计算”受到了众多IT厂商的关注,亚马逊、微软、惠普等众多IT巨头纷纷加入.

自奥巴马总统上台以来,美国政府一直着力推动“云计算”技术的大规模使用.2009 年3月,奥巴马总统提名昆德拉担任联邦CIO,而昆德拉上任之后,立即把“云计算”技术作为重点推进的工作之一.2010年5月,昆德拉表示,美国政府的 一家网站已经完全使用了亚马逊的“云计算”服务,也成为美国政府IT系统第一个“云计算”项目,这目前已成为奥巴马展开的一项影响深远的长期性“云计算” 政策.

现在业界流行着这样一句话,“云计算”是比尔·盖茨最怕听到的一个词.《哈佛商业评论》的前主编尼古拉斯·卡尔出版过一本名为《下一场IT的完 美风暴》,他在书中指出:“PC正在给应用时代让路.”分析师们甚至已经将PC销售乏力归咎于“云计算”惹的祸,他们认为,PC的黄金时代已经过去,当初 的时代弄潮儿如今已是英雄迟暮,就在PC未来仍然恍惚不定之时,“云计算”与虚拟化作为新的科技趋势早已隐秘在时代的浪潮之中,随时等待将PC取代.

虽然这看起来有些危言耸听,但未来PC将不再负责工作,而是被用来“发号施令”.通过网络人们将指令发出,那头的“云”则迅速给出答案,并通过网络回传给PC那头的用户.

为了让这种“发号施令”变得更加有效,中国和上海都正进行着规模浩大的光纤到户计划.作为老百姓,我们不用去理会“三网融合”的几家纷争,最终我们得到的好处将是——一个几十倍于目前的宽带网络.

也许你现在还觉得光纤太贵,可以选择暂缓安装.不过这就像当年装电话和电视一样是迟早的事,光纤网络对于人们未来生活的影响,几乎可以看成是必 然,业界专家目前根本看不到光纤的替代技术,如果要为光纤的生命力加一个期限,那么将是“一千年”,这是诺贝尔物理学奖得主高琨坚信的.

手机也可以连接“云”

除了光纤网络,将你连接到“云端”的另一个“狠角色”是4G,利用4G网络,你的手机和笔记本电脑可以在任何地方,随时向“云端”发送指 令.2010年10月,北京,全球瞩目的4G标准即将正式公布.什么是4G?也就是3G之后的第四代通信技术,利用4G上网,理论下载速度可以达到 100MB/秒,下载一部4G多的全高清电影只要40多秒.

如果你仍觉得上面的“天方夜谭”离自己太远的话,那么只要走入上海世博园,由中国电信和中国移动架设的LTE(Long-Term Evolution)无线网络,已经环绕在你的周围,虽然它看不见、摸不着,但却真实存在.LTE可以被看成“准4G”网络,严格来说它是3.9G,咨询 机构Juniper Research认为,到2014年,至少有1亿人使用LTE移动宽带,在未来数年中,上海很可能成为中国LTE和4G最早商用的城市之一.

比中国更快的是美国,美国移动运营商Sprint已在堪萨斯城进行4G网络部署,除此之外,Sprint今年计划新增的4G网络覆盖城市还有纽 约、华盛顿、旧金山、波士顿、丹佛、明尼阿波里斯和休斯顿,全美将新增覆盖8个城市.据悉,美国客户每月只需交付60美元费用,就可以将4G卡插入笔记本 使用网络服务,或者使用HTC专门发布的EVO4G手机.

4G的好处还不止于此,在当下的3G时代,电信、联通、移动三家的手机芯片各不相同,手机型号也不能互通,而在4G时代,各种制式手机的融合将 变得非常有趣.比如同一块芯片,既支持TD-LTE,又支持FDD-LTE,只需要更换软件,就可以进行自由切换.用户只需要购买一部手机,未来就能在各 种不同4G网络间自由切换.

jQuery中的Ajax传值出现中文乱码解决方法

没有评论

2010 年 09 月 25 日 at 下午 4:22分类:jQuery

最近在写jQuery的Ajax异步传输操作时,偶尔会碰到传输中文字符时,会出现乱码,今天有空把这个问题解决了

我们在用jQuery的Ajax事件进行页面交互的时候,通常页面的编码都是utf-8的,因此我们必须要设置我们的页面之间的编码

是一样的,如果还是出现乱码的情况的话,那就在变量上加上encodeURIComponent这个函数;如:变量username,就username = encodeURIComponent(username);这样子的话就不会出现乱码的现象了!!

  1. escape 不转换 @*/+
  2. encodeURI  不转换  ~!@#$&*()=:/,;?+’
  3. encodeURIComponent 不转换 ~!*()’

在Ajax的异步请求的时候,最好在请求的php页面加上以下的头文件

header(“Expires: 0″); /* 实际Expires会被max-age覆盖 */
header(“Cache-Control: no-store, private, post-check=0, pre-check=0, max-age=0″, FALSE);
header(“Pragma: no-cache”); /* 与HTTP1.0兼容 */

自己写的背景变黑层效果代码

没有评论

2010 年 09 月 24 日 at 下午 10:33分类:HTML

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<title>层</title>
<style type=”text/css”>
#ceng{
width:100%;
height:100%;
position:absolute;
left:0px;
top:0px;
display:none;
}
#yan{
width:100%;
height:100%;
background:gray;
position:absolute;
top:0px;
left:0px;
z-index:-1;
filter:alpha(opacity=20);
}
#bin{
position:absolute;
width:100%;
left:0px;
}
#show{
width:300px;
height:250px;
border:2px solid red;
background:green;
margin-left:auto;
margin-right:auto;
margin-top:200px;
}
</style>
<script type=”text/javascript”>
function show() {
document.getElementById(“ceng”).style.display=”block”;
}
</script>
<!– 弹窗end –>
</head>
<body>
<input type=”button” value= “点击” onclick=”show()”>
<div id=”ceng”>
<div id=”bin”>
<div id=”show”><input type=text></div>
</div>
<div id=”yan”></div>
</div>
</body>
</html>
原理:
<html>
<head>
<style type=”text/css”>
img{
position:absolute;
left:100px;
top:0px;
z-index:-1;
}
</style>
</head>
<body>
<h1>This is a heading</h1>
<img src=”eg_smile.gif” />
<p>由于图像的 z-index 是 -1,因此它在文本的后面出现。</p>
</body>
</html>

$_SERVER 个人感觉还是很有用的

没有评论

2010 年 09 月 23 日 at 下午 9:00分类:PHP

$_SERVER['HTTP_ACCEPT_LANGUAGE'] //浏览器语言
$_SERVER['REMOTE_ADDR'] //当前用户 IP 。
$_SERVER['REMOTE_HOST'] //当前用户主机名
$_SERVER['REQUEST_URI'] //URL
$_SERVER['REMOTE_PORT'] //端口。
$_SERVER['SERVER_NAME'] //服务器主机的名称。
$_SERVER['PHP_SELF'] #当前正在执行脚本的文件名,与 document root相关。
$_SERVER['argv'] #传递给该脚本的参数。
$_SERVER['argc'] #包含传递给程序的命令行参数的个数(如果运行在命令行模式)。
$_SERVER['GATEWAY_INTERFACE'] #服务器使用的 CGI 规范的版本。例如,“CGI/1.1”。
$_SERVER['SERVER_NAME'] #当前运行脚本所在服务器主机的名称。
$_SERVER['SERVER_SOFTWARE'] #服务器标识的字串,在响应请求时的头部中给出。
$_SERVER['SERVER_PROTOCOL'] #请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。
$_SERVER['REQUEST_METHOD'] #访问页面时的请求方法。例如:“GET”、“HEAD”,“POST”,“PUT”。
$_SERVER['QUERY_STRING'] #查询(query)的字符串。
$_SERVER['DOCUMENT_ROOT'] #当前运行脚本所在的文档根目录。在服务器配置文件中定义。
$_SERVER['HTTP_ACCEPT'] #当前请求的 Accept: 头部的内容。
$_SERVER['HTTP_ACCEPT_CHARSET'] #当前请求的 Accept-Charset: 头部的内容。例如:“iso-8859-1,*,utf-8”。
$_SERVER['HTTP_ACCEPT_ENCODING'] #当前请求的 Accept-Encoding: 头部的内容。例如:“gzip”。
$_SERVER['HTTP_ACCEPT_LANGUAGE']#当前请求的 Accept-Language: 头部的内容。例如:“en”。
$_SERVER['HTTP_CONNECTION'] #当前请求的 Connection: 头部的内容。例如:“Keep-Alive”。
$_SERVER['HTTP_HOST'] #当前请求的 Host: 头部的内容。
$_SERVER['HTTP_REFERER'] #链接到当前页面的前一页面的 URL 地址。
$_SERVER['HTTP_USER_AGENT'] #当前请求的 User_Agent: 头部的内容。
$_SERVER['HTTPS'] — 如果通过https访问,则被设为一个非空的值(on),否则返回off
$_SERVER['REMOTE_ADDR'] #正在浏览当前页面用户的 IP 地址。
$_SERVER['REMOTE_HOST'] #正在浏览当前页面用户的主机名。
$_SERVER['REMOTE_PORT'] #用户连接到服务器时所使用的端口。
$_SERVER['SCRIPT_FILENAME'] #当前执行脚本的绝对路径名。
$_SERVER['SERVER_ADMIN'] #管理员信息
$_SERVER['SERVER_PORT'] #服务器所使用的端口
$_SERVER['SERVER_SIGNATURE'] #包含服务器版本和虚拟主机名的字符串。
$_SERVER['PATH_TRANSLATED'] #当前脚本所在文件系统(不是文档根目录)的基本路径。
$_SERVER['SCRIPT_NAME'] #包含当前脚本的路径。这在页面需要指向自己时非常有用。
$_SERVER['REQUEST_URI'] #访问此页面所需的 URI。例如,“/index.html”。
$_SERVER['PHP_AUTH_USER'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的用户名。
$_SERVER['PHP_AUTH_PW'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是用户输入的密码。
$_SERVER['AUTH_TYPE'] #当 PHP 运行在 Apache 模块方式下,并且正在使用 HTTP 认证功能,这个变量便是认证的类型。

点击input 弹出框

没有评论

2010 年 09 月 21 日 at 上午 8:26分类:JavaScript

&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="utf-8" /&gt;
&lt;title&gt;Mr.Think&lt;/title&gt;
&lt;style type="text/css"&gt;
body {
font-size:12px;
}
#m_tagsItem {
background:#fff;
position:absolute;
top:0px;
left:0px;
overflow:hidden;
width:590px;
*width:561px;
width:561px\9;
padding:10px;
border:1px solid #ccc;
z-index:1000;
display:none;
}
#m_tagsItem p {
text-align:left;
line-height:22px;
padding:2px 0;
margin:0;
border:0;
}
#m_tagsItem span {
font-weight:bold;
}
#m_tagsItem a {
margin:0 5px;
}
.m_tagsname {
color:#999;
vertical-align:middle;
font-size:12px;
text-indent:3px;
line-height:20px;
}
#tagClose {
font-size:12px;
color:#888;
cursor:pointer;
position:absolute;
top:-2px;
right:5px;
}
&lt;/style&gt;
&lt;script src="jquery.js"&gt;&lt;/script&gt;
&lt;script&gt;
(function($){
$.fn.bgIframe = $.fn.bgiframe = function(s) {
// This is only for IE6
if ( $.browser.msie &amp;&amp; /6.0/.test(navigator.userAgent) ) {
s = $.extend({
top     : 'auto', // auto == .currentStyle.borderTopWidth
left    : 'auto', // auto == .currentStyle.borderLeftWidth
width   : 'auto', // auto == offsetWidth
height  : 'auto', // auto == offsetHeight
opacity : true,
src     : 'javascript:false;'
}, s || {});
var prop = function(n){return n&amp;&amp;n.constructor==Number?n+'px':n;},
html = '&lt;iframeframeborder="0"tabindex="-1"src="'+s.src+'"'+
'style="display:block;position:absolute;z-index:-1;'+
(s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')+
'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'+
'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'+
'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'+
'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'+
'"/&gt;';
return this.each(function() {
if ( $('&gt; iframe.bgiframe', this).length == 0 )
this.insertBefore( document.createElement(html), this.firstChild );
});
}
return this;
};
})(jQuery);
jQuery.fn.selectCity = function(targetId) {
var _seft = this;
var targetId = $(targetId);

this.click(function(){
var A_top = $(this).offset().top + $(this).outerHeight(true);  //  1
var A_left =  $(this).offset().left;
targetId.bgiframe();
targetId.show().css({"position":"absolute","top":A_top+"px" ,"left":A_left+"px"});
});

targetId.find("#tagClose").click(function(){
targetId.hide();
});
$(document).click(function(event){
if(event.target.id!=_seft.selector.substring(1)){
targetId.hide();
}
});

targetId.click(function(e){
e.stopPropagation(); //  2
});

return this;
}
$(function(){
$("#selecttags").selectCity("#m_tagsItem");
});
//为文本域连续赋值
function checktag(o){
var tagid = function(id){return document.getElementById(id);}
var tags = [];//存放标签,避免重复加入
var tagidSPLITCHAR = ' ';//设定分隔符,根据程序需求可改
var d = tagid('selecttags');
if (d.value)
tags = d.value.split(tagidSPLITCHAR);
var v = o.innerHTML;//如果tag有别的值或者别的非innerHTML里体现的内容
var s = tagidSPLITCHAR+tags.join(tagidSPLITCHAR)+tagidSPLITCHAR
if (!new RegExp(tagidSPLITCHAR+v+tagidSPLITCHAR,'g').test(s)){
s+=v;
}
s = s.replace(new RegExp("(^"+tagidSPLITCHAR+"*|"+tagidSPLITCHAR+"*tagid)","g"),'');
d.value = s;
tags = s.split(tagidSPLITCHAR);
}
&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;input type="text" size="110" id="selecttags" name="m_tagsname" Value="点击查看热门标签和您曾经使用过的标签" onClick="if(this.value=='点击查看热门标签和您曾经使用过的标签'){this.value=''; this.className='m_tagsname'}"/&gt;
&lt;div id="m_tagsItem" style="display:none"&gt;
&lt;div id="tagClose"&gt;关闭&lt;/div&gt;
&lt;p&gt;&lt;span&gt;温馨提示:&lt;/span&gt;标签间请用“空格”、“逗号”或“分号”隔开,用简练的词语概括您的博文内容。&lt;/p&gt;
&lt;p&gt;&lt;span&gt;热门标签:&lt;/span&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;bbb&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;aaa&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;ccc&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;dddd&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;eee&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;fff&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;ggg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;您使用过的标签:&lt;/span&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩s妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美sf发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优s博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;彩妆&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美发&lt;/a&gt;&lt;a href="javascript:void(0)" onClick="checktag(this)"&gt;美优博客&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;

一些应该熟记于心的jQuery函数和技巧

没有评论

2010 年 09 月 19 日 at 上午 10:17分类:jQuery

http://developer.51cto.com/art/201006/205042.htm

http://developer.51cto.com/art/201005/202450.htm

//jquery从入门到精通学习网站

jQuery学习笔记

没有评论

2010 年 09 月 19 日 at 上午 9:32分类:jQuery

query 学习笔记和部分实例代码,教程是《Jquery基础教程》,在VeryCD下的PDF版本。比较乱,大家将就一下
——————————————————————————
筛选出可见的元素 ,.filter(“:visible”).这个选择器在hide()和show()时常用
$(“#play_list a”).filter(“:visible”).fadeOut(500).parent().children().eq(i).fadeIn(1000);
——————————————————————————
定时与取消定时
t = setInterval(“showAuto()”, 2000);
clearInterval(t)},
jquery在图片联播时的
t = setInterval(“showAuto()”, 2000);
$(“#play”).hover(function(){clearInterval(t)}, function(){t = setInterval(“showAuto()”, 2000);});
——————————————————————————
表单的确认提交
$(“input[name='submit']“).click(
function(){
//这里可先插入检查内容的代码
sure=window.confirm(‘你确定要提交吗’);
if(sure){
$(this).parent().submit();
}else
{return false;}
});
——————————————————————————
//DOM加载完后执行
$(document).ready( )
——————————————————————————
//ID下的某个子元素
$(‘#selected-play > li’)
选择ID为selected-play 子元素(>)中所有的列表项(li)
没有>则选取了所有的后代元素li
——————————————————————————
//ID为#zhu下的后代li元素中不属于test类的li 注意引号的位置
$(‘#zhu li:not(.test)’).addClass(‘test2′);
——————————————————————————
XPath选择符  //严重怀疑教程使用的Jquery版本过低或者错误使用方法
这个主要是针对元素的子元素或属性来筛选元素。
属性选择符   元素[@属性]         //选到的元素为要操作的对象
选择所有带title属性的链接,个人怀疑不用@才是正确的。
$(‘a[@title]‘)
选择包含一个ol的所有div元素  //貌似也不灵。
$(‘div[ol]‘)

//这个很值得怀疑。@根本不用使用。使用了反而行不通
$(‘a[@href^=”‘).addClass(‘mailto’);
//可以使用正则表达式对属性元素筛选
$(‘a[href^=mailto]‘).addClass(‘mailto’);
$(‘a[href$=".pdf"]‘).addClass(‘pdf’);
$(‘a[href*="52mtk"]‘).addClass(‘inlink’);
——————————————————————————
自定义选择符
$(‘div.horizontal:eq(1)’) /*类名为horizontal的第二个div元素*/
$(‘a.inlink:eq(0)’).addClass(‘new’).removeClass(‘inlink’);
$(‘li:eq(1)’).addClass(‘new’); /*所有匹配li的元素的第二项   js索引从0开始 自定义选择符*/
$(‘div:nth-child(1)’).addClass(‘newer’); //第一个div.   CSS索引从1开始。CSS选择符
——————————————————————————
:odd 奇数
:even偶数
第一个元素从0开始 ,其中0是偶数

$(‘li:odd’).addClass(‘odd’);
$(“li:even”).addClass(‘even’); //第一个li (以0开始)应用了偶数 的样式。
——————————————————————————
:contains(“..”) 包含某内容

<li>dream</li>
//可这样得到
$(‘li:contains(“dream”)’).addClass(‘highlight’);
——————————————————————————
//注意:相同属性的最终选择与样式表中定义的顺序有关
——————————————————————————
$(‘tr’).filter(‘:odd’).addClass(‘odd’); ==$(‘tr:odd).addClass(‘odd’);
——————————————————————————
parent() 选择父结点。即使有多个th,但JQ不会重复给同一个父结点增加相同的类。
$(‘th’).parent().addClass(‘class’) ;
$(‘tr:not([th]):odd).addClass(‘class’) ;结合Xpath。注意:not([th])这个写法。
——————————————————————————
next() 下一项
$(‘td:contains(“2″)’).parent().next().addClass(‘hl2′);
——————————————————————————
兄弟元素,有点问题的。。。
sibling()
——————————————————————————
查找 .find(‘element’) 排除条件.not(“:contains(‘XXX’)”)
$(‘td:contains(“4″)’).parent().find(‘td’).not(“:contains(’4′)”).addClass(‘hl2′);
——————————————————————————
get 返回一个DOM对象
$(‘#my-element’).get(0) 可简写成$(‘#my-element’)[0]
如下取得DOM对象标签名
var myTag=$(‘#my-element’).get(0).tagName;
******************************************************************************
事件
$(document).ready() 一般比onload事件优越。
但是有时可能由于支持文件未下载完,所以类似图像的宽度和高度这样的属性未必有效,这时可以利用jQuery 的load()来处理
——————————————————————————
$(document).ready(function(){…});
另一写法
$().ready(function() { …});
再一写法
$(function(){…});
但第一种最常用 。
——————————————————————————
样式切换
绑定元素到点击事件在 $().ready()中
$(‘#id’).bind(‘click’,function(){…}); 等价于$(‘#id’).click(function(){…});
$(this).addClass(‘myclass’);
这里的this是一个DOM对象
可以这样判断
if(this.id==’large’)
$(this).addClass(‘large’);
——————————————————————————
toggle点击元素时交替执行两个函数 /接受两个参数是函数
$(‘#hid’).toggle(function(){
$(‘#switcher’).addClass(‘hidden’);
this.value=’显示’;},
function(){
$(‘#switcher’).removeClass(‘hidden’);
this.value=’隐藏’;
}
)
也可以用toggleClass来交替使用类
$().ready(function() {
$(‘#hid’).click(function(){$(‘#hid’).toggleClass(‘hidden’);})
});
——————————————————————————
hover 放在元素上面的时候执行一个函数,离开时执行另一个操作,参数同toggle
$(‘#hov’).hover(
function() {$(this).addClass(‘hover’);
$(‘.normal’).addClass(‘hidden’)
},
function(){ $(this).removeClass(‘hover’);
$(‘.normal’).removeClass(‘hidden’);}
);

——————————————————————————
事件捕获 (从一般到具体)与事件冒泡(从具体到一般)
DOM的标准是先从一般到具体,再通过事件冒泡返回DOM树的顶层
事件处理程序可以注册到这个过程的任何一部分

/*演示事件冒泡 ,点击div的后代元素也会触发该事件*/
$(‘#switcher’).click(function(){
$(‘p’).toggleClass(‘hidden’);
});
——————————————————————————
解决方法:加入JS的event.target与this的DOM目标元素比较
$(‘#switcher’).click(function(event){
if(event.target==this){
$(‘p’).toggleClass(‘hidden’);
}
});
——————————————————————————
方法二:event.stopPropagation();
但还是会冒泡,无论是火狐还是IE!奇怪了。
——————————————————————————
阻止默认动作
$(“a:contains(‘link’)”).click(function(){
return false;//相当于同时调用了.stopPropagation()和.preventDefault()
}); //如此,点击<a href=”Xpath1.htm”>it’s a link</a><br />并不跳转了。
——————————————————————————
.unbind 注意函数不加引号
$(‘#switch’).unbind(‘click’,somefunction);
.one方法   切换操作只会发生一次。
toggleStylesSwitcher是事先定义的。
$().ready(function(){
$(‘#switcher’).one(‘click’,toggleStylesSwitcher);
});
——————————————————————————
hide方法
$(‘#switcher’).hide();
——————————————————————————
.trigger()模拟事件操作
$().ready(function(){
$(‘#switcher’).trigger(‘click’); //模拟点击了。触发对象的click事件
});
******************************************************************************
操作CSS
——————————————————————————
.css方法 两种参数
.css(‘property’,'value’)  //属性值对
.css({property1: ‘value1′, ‘property2:’value2′}) //对象字面量

——————————————————————————
改变字号
$(document).ready(function() {
$(‘#larger’).hover(function(){
$(this).css({“cursor”:”pointer”});
});

$(‘#larger’).click(function(){
var $speech=$(‘div.speech’);
var currentSize=$speech.css(‘fontSize’);
var num=parseFloat(currentSize); 字符串转浮点数,开头为数字,后面字符忽略
var unit=currentSize.slice(-2); //相当于PHP的substr
num*=1.5;
$speech.css(‘fontSize’,num + unit);

console.log(num);

});
——————————————————————————
一般都是通过取得一组jquery对象,通过this.id筛选
$(document).ready(function() {
$(‘div.button’).hover(function(){
$(this).css({“cursor”:”pointer”});
});

$(‘div.button’).click(function(){
var $speech=$(‘div.speech’);
var currentSize=$speech.css(‘fontSize’);
var num=parseFloat(currentSize);
var unit=currentSize.slice(-2);
if(this.id==’larger’){
num*=1.5;}
else if(this.id==’smaller’)
{num/=1.5;}else {
num=12;
}

$speech.css(‘fontSize’,num + unit);

console.log(num);

});

})
隐藏显示与动画效果:

$(‘p:eq(1)’).hide();

$(‘span.more’).click(function(){
$(‘p:eq(1)’).fadeIn(‘slow’); //渐显效果

$(this).hide();
});

$(‘span.less’).click(
function(){
//$(‘p:eq(1)’).fadeTo(‘slow’);
$(‘p:eq(1)’).hide(‘fast’); //收缩时动画效果,不加参数则无

$(‘span.more’).show();
}
);
——————————————————————————
动画参数:第一个类似.css方法,第二个速度,第三个可选的缓动类型,最后一个是回调函数(可选)
.animate({param1:’value1′,param2:’value2′}, speed,[easing] ,function(){alert(‘…’)});
/*动画效果*/
$(‘#moveText’).toggle(function(){

$(‘span#animate’).animate({left:800},’slow’);
},function(){
$(‘span#animate’).animate({left:0},’slow’);
});
——————————————————————————
.css(‘属性’) 取得对象的CSS属性,
$(‘div.button:eq(1)’).css(‘width’) 带有单位px
$(‘div.button:eq(1)’).width() 这个不带px
$(‘div.button:eq(1)’).css(‘backgroundColor’); 属性骆驼命名法,跟JS是一样的
——————————————————————————
连缀的写法
$(‘span#animate’).animate({left:0},’slow’).animate({top:0},’slow’);
——————————————————————————
//$(‘span#animate’).slideUp(‘slow’);//幻灯片式向上折叠消失
——————————————————————————
$(this).slideUp(‘slow’).next().slideDown(‘slow’);          //对一组元素,(这里是$(this)和$(this).next()  )如果不使用回调 函数,这两个效果是同时发生的。。。。

——————————————————————————
使用回调函数安排多个元素的顺序
var $thisPara=$(this);
$thisPara.next().slideDown(‘slow’,function(){$thisPara.slideUp(‘slow’)});
//第二个元素先从下切入,第一个元素再向上切出
——————————————————————————
对同一个元素的不动方法如.animate后使用.css 也可以使用回调函数的做法。
$(this).next() 这样使用后$(this)已经改变了。。。。
为了安全使用可以var $thisPara=$(this)先
——————————————————————————
DOM操作
******************************************************************************
属性工具
$(‘div.article a’).attr({‘rel’:'external’})
——————————————————————————
.each的循环遍历,index是计数器,text()是链接的文本
$(‘div.article a’).each(function(index){
var $thisLink=$(this);
$thisLink.attr({‘title’:'点击了解更多关于:’+$thisLink.text(),’id’:'article_’+parseInt(index+1)});
});
——————————————————————————
创建节点与加入到元素
//before与insertBefore
//after与insertAfter
//append与appendTo
//prepend…
//区别在于连缀的元素不同。
$(“<a href=’#top’>回到顶部</a>”).insertAfter(‘div.article p’);
另一写法
$(‘div.article p’).after(“<a href=’#top’>回到顶部</a>”)
——————————————————————————
在其他元素中插入元素
prependTo
——————————————————————————
从第二个段落开始添加一个链接到页面顶部
//gt ==greater than 索引从0开始。
//lt  /less than
//eq  /equal
$(“<a class=’goTop’ href=’#top’ >回到顶部</a>”).insertAfter(‘div.article p:gt(1)’);
$(“<a id=’top’></a>”).prependTo(‘body’);
——————————————————————————
添加到子节点
//append与appendTo
添加子节点/依附到某母节点 ,顺序是按after
//prepend与prependTo
添加子节点/依附到某母节点 , 顺序是before
——————————————————————————
这段代码表现注释的链接和反链接回去
$(‘span.footNote’).each(function(index){
$(this).before(‘<a href=#foot-’+parseInt(index+1)+ ‘ id=content-’+parseInt(index+1)+’><sup>’+parseInt(index+1)+’</sup></a>’)
.appendTo(‘#notes’)
.append(‘<a href=#content-’+parseInt(index+1)+’ id=foot-’+(index+1)+’><sup>’+'返回</sup></a>’);
});

$(‘a[id*="foot"]‘).each(function(index){
$(this).click(function(){
$(‘a#content-’+parseInt(index+1)).css(‘backgroundColor’,'blue’);
});
});
——————————————————————————
wrap
包装,创建一个新元素并把自己作该元素的子节点
.wrap(‘<li id=”foot-note-’+(index+1)+’”></li>’);
——————————————————————————
克隆
.clone()
如果只不克隆子节点,如Text Node 可加入参数false
$(‘p:eq(0)’).clone(false);
——————————————————————————
$(this).clone()
此时操作的是clone后的结点
——————————————————————————
/*引言设置*/
$(‘span.pull-quote’).each(function(index){
var $parentPara=$(this).parent(‘p’);
$parentPara.css(‘position’,'relative’);
var $clonePara=$(this).clone(false);
$clonePara.addClass(‘pulled’).prependTo($parentPara);
$clonePara[0].id=’quote_’+(index+1);

});
——————————————————————————
find查找后返回原对象
$clonePara.find(‘span’).html(‘&hellip’).end()
——————————————————————————
.html / .text() 修改对象的文本节点
要移除每个匹配元素中的元素
.empty()
要从文档中移除每个匹配的元素及其后代元素,但并不实际删除它们
使用
.remove()
******************************************************************************
Ajax
——————————————————————————
$(‘div#test’).load() 将取得的内容直接放入元素内
$(‘div#test’).load(‘http://localhost/11/joinarray.php’,function(){alert(‘finished’);});
——————————————————————————
Json
全局函数
$.getJSON(json文件,回调函数)
$.getJSON(‘../11/json.php’,function(data){
$(‘div#test’).empty();
$(‘div#test’).text(data.name);
});
——————————————————————————
用for …in遍历
$.getJSON(‘../11/json.php’,function(data){
$(‘div#test’).empty();
var key;
for(key in data) {
for(key2 in data[key]){
console.log(data[key][key2]);
}
}

——————————————————————————
用全局函数each遍历
$.each(data,function(entryIndex,entry){ //索引与条目,映射或数组

var html =’<div>’;
html+=’<div>’+entry.num+’</div>’;
html+=’<div>’+entry.name+’</div>’;
html+=’</div>’;
//$(‘div.entry’).appendTo(‘#test’);
$(‘#test’).append(html); //新创建的节点貌似多用原有节点append,用appendTo主动依附好像不行。appendTo应该多用于移动复制节点的操作
}
或者可以这样,用this关键字
$each (data,function(){
alert (this.num);

});
——————————————————————————
全局函数$.getScript(‘a.js’);
立即加载并执行一个脚本!
——————————————————————————
加载XML $.get(‘d.xml’)
用find操作子节点
用attr操作子节点属性
用text()取得节点的文本
用原有元素.append加入新元素

/*取得XML数据*/
$(‘#getXml’).click(function(){

$(‘div#test’).empty();
$.get(‘d.xml’,function(data){
//console.log(data);
$(data).find(‘entry’).each(function(){
var $entry=$(this);
var html=’<div>’;
html+=’<h3>’+$entry.attr(‘term’)+’</h3>’;//取得属性值
html+=’<h3>’+$entry.attr(‘part’)+’</h3>’;
html+=’<div>’;
html+=$entry.find(‘definition’).text();  //取得节点的文本
var $quote=$entry.find(‘quote’);
if($quote.length) { //判断是否存在
html+=’<div>’;
$quote.find(‘line’).each(function(){
html+=’<div>’+$(this).text()+’</div>’;

})
}
if ($quote.attr(‘author’)) {
html+=’<div>’+$quote.attr(‘author’)
+’</div>’;

}

html +=’</div>’;
html +=’</div>’;
$(‘#test’).append(html);

});
});
/*遍历DOM*/

}) ;
——————————————————————————
我的实验 全局变量与未定义变量的判断和使用

var queryId=$(this).attr(“value”);
/*定义只有两次输入不同数字时才会进行提交*/
if(typeof(oldId)!=”undefined” && oldId==queryId) {return false;} //其中typeof(oldId)!=”undefined”相当于php的!isset
oldId=queryId;              //这里调用了全局变量

——————————————————————————
POST与GET  //为了对付IE的缓存:多使用了一个随机参数
gt=new Date();
sgt=gt.getTime();
GET:
- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – -
$(‘a.link#get’).click(function(){
gt=new Date();
sgt=gt.getTime();
$.get(‘../11/testBrowser.php’,{‘phrase’:$(this).text(),’rbs’:sgt},
function(data){
$(‘#test’).empty();
$(‘#test’).html(data);
});
return false;
});

POST:LOAD方法实际使用的是POST,但 更简洁
- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – -
$(‘a.link#post’).click(function(){
/*  $.post(‘../11/testBrowser.php’,{‘phrase’:$(this).text()},
function(data){
$(‘#test’).empty();
$(‘#test’).html(data);
});*/
/*这里的POST等价于LOAD*/
$(‘#test’).load(‘../11/testBrowser.php’,{‘phrase’:$(this).text()});

return false;

});
- – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – - – -
每隔一秒取得服务器时间 ,这里也要加参数,否则在IE有缓存问题
但这个参数不必可变,因为是POST的
setInterval(myTime,1000);
function myTime(){
/*
$.get(‘../11/getTime.php’,function(data){
$(‘#time’).text(data);

});*/
$(‘#time’).load(‘../11/getTime.php’,{‘id’:'ii’});
//alert(‘hello’);
return false;
}
——————————————————————————
$(‘form’).submit 方法与提交按钮的click方法效果是一样的。
——————————————————————————
$(this).find(‘input’).serialize() ;注意这个序列化语句

——————————————————————————
完整的序列化操作
//序列化 ,但在处理多选项目时有些问题。
$(“form”).submit(function(){

if($(‘#sendMe’).val()==” || $(‘#sendPassword’).val()==”) {
$(“#state”).html(‘<b>字段不能为空</b>’);
// console.log($(‘input[@value=""]‘).attr(‘id’));//.focus();
return false;
}
$.post(“../11/testAjax.php”,$(this).find(‘input’).serialize(),function(data){
//判断登录是否成功
if(data==’0′) { var html=’登陆失败,请重试’;}
if(data==’1′) {
var html=’登录成功,欢迎你,’+$(‘#sendMe’).val();
//后台写入session,前台隐藏登录框
$(‘#login’).hide();

}

$(‘#state’).html(html);

});
return false;
});
——————————————————————————
/*ajax状态控制*/
//以下两个方法是全局的,只要页面有ajax触发,就会执行这些动作
$(‘#state’).ajaxStart(function(){
var loading=”<img src=’images/loading.gif’ />”;

$(‘#state’).html(loading);

}).ajaxStop(function(){
var finish=’ <font color=”red”>done!</font>’

var ok=$(‘#state’).html()+finish;
$(‘#state’).html(ok);
//$(‘#state’).append(finish);
});
——————————————————————————
用load处理Ajax时
load是这样一个玩意:根据提交的内容要决定提交的方法,之前认为默认是POST的理解是错误的。
对于json方式的数据,使用POST来提交,对于字符串或者序列化以后的数据,一般 也就是采用serialize()方法处理过的输入内容,使用的是GET方法提交.
手册上是这样说的:
载入远程 HTML 文件代码并插入至 DOM 中。
默 认使用 GET 方式 – 传递附加参数时自动转换为 POST 方式。jQuery 1.2 中,可以指定选择符,来筛选载入的 HTML 文档,DOM 中将仅插入筛选出的 HTML 代码。语法形如 “url #some > selector”。请查看示例。
——————————————————————————
用.post()提交数据,并处理返回的json格式字符串,一个重要的JS函数 eval()
eval():把字符串语句当JS执行。。。
注意,返回的json格式字符串并非json对象。
$data=$(this).find(‘input’).serialize();
$.post(‘../11/arrayPost.php’,$data,function(result){
eval(‘var myjson=’ + result + ‘;’); //这里是关键,作用是把result从字符串转化为对象。
console.log(myjson);//firebug测试,显示是对象
$(‘div#result’).html(myjson.name);
});
——————————————————————————
渐显,要先使用hide方法。。
$(‘#submit’).click(function(){
$data=$(‘input’).serialize();
$(‘div#feedback’).hide().load(“../11/arrayPost.php”,$data,function(){
$(this).fadeIn(2000); //渐显,要先使用hide方法。。。

});
return false;
});
——————————————————————————
双触发与作用域
$()函数的第二个参数
$(‘h3′,scope)
//第一个bindBehaviors绑定到document对象作用域,第二个绑定到feedback的div。
作用域不同,如果不设定这个参数,则同为document作用域,提交表单操作后再操作先前的h3,则为执行了两次bindBehaviors,所以样式不会改变。
$(document).ready(function() {
var bindBehaviors=function(scope){
$(‘h3′,scope).click(function(){$(this).hide().fadeIn(1000).toggleClass(‘customh3′);});
}
bindBehaviors(this);
$(‘#submit’).click(function(){
$data=$(‘input’).serialize();
$(‘div#feedback’).hide().load(“../11/returnHtml.php”,$data,function(){
$(this).fadeIn(1000); //渐显,要先使用hide方法。。。
bindBehaviors(this);
});
return false;
});

});
——————————————————————————
使用事件冒泡 解决 双触发       event.target
is(expr)用一个表达式来检查当前选择的元素集合,如果其中至少有一个元素符合这个给定的表达式就返回true
绑定到一个公共父元素。通过对事件目标的判断进行动作,效果同上
$(‘body’).click(function(event){
if ($(event.target).is(‘h3′) ) {
$(event.target).toggleClass(‘customh3′);
}
});
——————————————————————————
AJAX取得外部域数据:不使用服务器代理
1.动态加载第三方脚本。
$(document.createElement(‘script’))
.attr(‘src’,'http://外部域/XXX.js).appendTo(‘head’);
2.使用<iframe>加载第三方服务器的数据,
这些iframe的脚本需要向文档的父对象提供数据。

******************************************************************************
第七章:表格操作
******************************************************************************

jQuery 写一个插件方法

.blur()方法
$(‘form > input[name="blur"]‘).css(‘color’,'#999999′).val(‘请输入内容’).click(function(){
if($(this).val()==’请输入内容’)
$(this).val(”);
}).blur(function(){

if($(this).val()==”) {$(this).val(‘请输入内容’);}
//else $(this).unbind(“click”);
});

—————————————————————————
未试验
因为IE6不支持  list-style-type:upper-alpha;
所以用JS和jquery做以下事件:
1.浏览器/能力检测
2.加上标志
$(‘ul.questions’).each({ function(){
var chars=array(‘A’,'B’,'C’,'D’,'E’,'F’);
var $qs=$(this);
count=$qs.find(‘li’).size();
for(i=0;i<count;i++){
var newText=chars+’.'+$qs.find(‘li’).eq(i).text();
$qs.find(‘li’).eq(i).text(newText);
}
)

用ob_start()控制缓冲,给页面做文件缓存,加速页面

没有评论

2010 年 09 月 18 日 at 下午 9:44分类:PHP

Output Control 函数可以让你自由控制脚本中数据的输出。它非常地有用,特别是对于:当你想在数据已经输出后,再输出文件头的情况。输出控 制函数不对使用 header() 或 setcookie(), 发送的文件头信息产生影响,只对那些类似于 echo() 和 PHP 代码的数据块 有作用。

我们先举一个简单的例子,让大家对Output Control有一个大致的印象:
Example 1.

CODE<?php
ob_start(); //打开缓冲区
echo \”Hellon\”; //输出
header(“location:index.php”); //把浏览器重定向到index.php
ob_end_flush();//输出全部内容到浏览器
?>

所有对header()函数有了解的人都知道,这个函数会发送一段文件头给浏览器,但是如果在使用这个函数之前已经有了任何输出(包括空输出,比 如空格,回车和换行)就会提示出错。如果我们去掉第一行的ob_start(),再执行此程序,我们会发现得到了一条错误提 示:”Header had all ready send by”!但是加上ob_start,就不会提示出错,原因是当打开了缓冲区,echo后面的 字符不会输出到浏览器,而是保留在服务器,直到你使用flush或者ob_end_flush才会输出,所以并不会有任何文件头输出的错误!

一、 相关函数简介:
1、Flush:刷新缓冲区的内容,输出。
函数格式:flush()
说明:这个函数经常使用,效率很高。
2、ob_start :打开输出缓冲区
函数格式:void ob_start(void)
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。
3 、ob_get_contents :返回内部缓冲区的内容。
使用方法:string ob_get_contents(void)
说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。
4、ob_get_length:返回内部缓冲区的长度。
使用方法:int ob_get_length(void)
说明:这个函数会返回当前缓冲区中的长度;和ob_get_contents一样,如果输出缓冲区没有激活。则返回 FALSE。
5、ob_end_flush :发送内部缓冲区的内容到浏览器,并且关闭输出缓冲区。
使用方法:void ob_end_flush(void)
说明:这个函数发送输出缓冲区的内容(如果有的话)。
6、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区
使用方法:void ob_end_clean(void)
说明:这个函数不会输出内部缓冲区的内容而是把它删除!
7、ob_implicit_flush:打开或关闭绝对刷新
使用方法:void ob_implicit_flush ([int flag])
说明:使用过Perl的人都知道$|=x的意义,这个字符串可以打开/关闭缓冲区,而ob_implicit_flush函数也和那个一样,默认为关闭缓冲区,打开绝对输出后,每个脚本输出都直接发送到浏览器,不再需要调用 flush()

二、深入了解:

1. 关于Flush函数:
这个函数在PHP3中就出现了,是一个效率很高的函数,他有一个非常有用的功能就是刷新browser的cache.我们举一个运行效果非常明显的例子来说明flush.
Example 2.

CODE<?php
for($i = 1; $i <= 300; $i++ ) print(“ ”);
// 这一句话非常关键,cache的结构使得它的内容只有达到一定的大小才能从浏览器里输出
// 换言之,如果cache的内容不达到一定的大小,它是不会在程序执行完毕前输出的。经
// 过测试,我发现这个大小的底限是256个字符长。这意味着cache以后接收的内容都会
// 源源不断的被发送出去。
For($j = 1; $j <= 20; $j++) {
echo $j.”
“;
flush(); //这一部会使cache新增的内容被挤出去,显示到浏览器上
sleep(1); //让程序”睡”一秒钟,会让你把效果看得更清楚
}
?>

具体效果你可以到这里看看[url]http://www.php2000.com/~uchinaboy/out.php[/url]
PHP2000的最新的PHP聊天室就是用的这个技术,可惜的是源代码未公开

注:如果在程序的首部加入ob_implicit_flush()打开绝对刷新,就可以在程序中不再使用flush(),这样做的好处是:提高效率!

2. 关于ob系列函数:
我想先引用我的好朋友y10k的一个例子:
Example 3.

比如你用得到服务器和客户端的设置信息,但是这个信息会因为客户端的不同而不同,如果想要保存phpinfo()函数的输出怎么办呢?在没有缓冲区控制之前,可以说一点办法也没有,但是有了缓冲区的控制,我们可以轻松的解决:
CODE<?php
ob_start(); //打开缓冲区
phpinfo(); //使用phpinfo函数
$info=ob_get_contents(); //得到缓冲区的内容并且赋值给$info
$file=fopen(\’info.txt\’,\’w\’); //打开文件info.txt
fwrite($file,$info); //写入信息到info.txt
fclose($file); //关闭文件info.txt
?>

用以上的方法,就可以把不同用户的phpinfo信息保存下来,这在以前恐怕没有办法办到!其实上面就是将一些”过程”转化为”函数”的方法!
或许有人会问:”难道就这个样子吗?还有没有其他用途?”当然有了,比如笔者论坛的PHP 语法加亮显示就和这个有关(PHP默认的语法加亮显示 函数会直接输出,不能保存结果,如果在每次调用都显示恐怕会很浪费CPU,笔者的论坛就把语法加亮函数显示的结果用控制缓冲区的方法保留了),大家如果感 兴趣的话可以来看看[url]http://www.zphp.com/bbs/[/url]

可能现在大家对ob_start()的功能有了一定的了解,上面的一个例子看似简单,但实际上已经掌握了使用ob_start()的要点。
<1>.使用ob_start打开browser的cache,这样可以保证cache的内容在你调用flush(),ob_end_flush()(或程序执行完毕)之前不会被输出。
<2>.现在的你应该知道你所拥有的优势:可以在任何输出内容后面使用header,setcookie以及session,这是 ob_start一个很大的特点;也可以使用ob_start的参数,在cache被写入后,然后自动运行命令,比如 ob_start(\”ob_gzhandler\”);而我们最常用的做法是用ob_get_contents()得到cache中的内容,然后再进行 处理……
<3>.当处理完毕后,我们可以使用各种方法输出,flush(),ob_end_flush(),以及等到程序执行完毕后的自动输出。当然,如果你用的是ob_get_contents(),那么就要你自己控制输出方式了。

来,让我们看看能用ob系列函数做些什么……

一、 静态模版技术

简介:所谓静态模版技术就是通过某种方式,使得用户在client端得到的是由PHP产生的html页面。如果这个html页面不会再被更新,那 么当另外的用户再次浏览此页面时,程序将不会再调用PHP以及相关的数据库,对于某些信息量比较大的网站,例如sina,163,sohu。类似这种的技 术带来的好处是非常巨大的。

我所知道的实现静态输出的有两种办法:
<1>.通过y10k修改的phplib的一个叫template.inc.php类实现。
<2>.使用ob系列函数实现。
对于第一种方法,因为不是这篇文章所要研究的问题,所以不再赘述。
我们现在来看一看第二种方法的具体实现:
Example 4.

CODE<?php
ob_start();//打开缓冲区
?>
php页面的全部输出
<?
$content = ob_get_contents();//取得php页面输出的全部内容
$fp = fopen(“output00001.html”, ”w”); //创建一个文件,并打开,准备写入
fwrite($fp, $content); //把php页面的内容全部写入output00001.html,然后……
fclose($fp);
?>

这样,所谓的静态模版就很容易的被实现了……

二、 捕捉输出

以上的Example 4.是一种最简单的情况,你还可以在写入前对$content进行操作……
你可以设法捕捉一些关键字,然后去对它进行再处理,比如Example 3.所述的PHP语法高亮显示。个人认为,这个功能是此函数最大的精华所在,它可以解决各种各样的问题,但需要你有足够的想象力……
Example 5.

CODE<?
Function run_code($code) {If($code) {
ob_start();
eval($code);
$contents = ob_get_contents();
ob_end_clean();
}else {
echo ”错误!没有输出”;
exit();
}
return $contents;
}

以上这个例子的用途不是很大,不过很典型$code的本身就是一个含有变量的输出页面,而这个例子用eval把$code中的变量替换,然后对输出结果再进行输出捕捉,再一次的进行处理……

Example 6. 加快传输

CODE<?
/*
** Title………: PHP4 HTTP Compression Speeds up the Web
** Version…….: 1.20
** Author……..: catoc <[email]catoc@163.net[/email]>
** Filename……: gzdoc.php
** Last changed..: 18/10/2000
** Requirments…: PHP4 >= 4.0.1
** PHP was configured with –with-zlib[=DIR]
** Notes………: Dynamic Content Acceleration compresses
** the data transmission data on the fly
** code by sun jin hu (catoc) <[email]catoc@163.net[/email]>
** Most newer browsers since 1998/1999 have
** been equipped to support the HTTP 1.1
** standard known as \”content-encoding.\”
** Essentially the browser indicates to the
** server that it can accept \”content encoding\”
** and if the server is capable it will then
** compress the data and transmit it. The
** browser decompresses it and then renders
** the page.
**
** Modified by John Lim ([email]jlim@natsoft.com.my[/email])
** based on ideas by Sandy McArthur, Jr
** Usage……..:
** No space before the beginning of the first \’<?\’ tag.
** ————Start of file———-
** |<?
** | include(\’gzdoc.php\’);
** |? >
** |<HTML>
** |… the page …
** |</HTML>
** |<?
** | gzdocout();
** |? >
** ————-End of file———–
*/
ob_start();
ob_implicit_flush(0);
function CheckCanGzip(){
global $HTTP_ACCEPT_ENCODING;
if (headers_sent() || connection_timeout() || connection_aborted()){
return 0;
}
if (strpos($HTTP_ACCEPT_ENCODING, \’x-gzip\’) !== false) return \”x-gzip\”;
if (strpos($HTTP_ACCEPT_ENCODING,\’gzip\’) !== false) return \”gzip\”;
return 0;
}
/* $level = compression level 0-9, 0=none, 9=max */
function GzDocOut($level=1,$debug=0){
$ENCODING = CheckCanGzip();
if ($ENCODING){
print \”n<!– Use compress $ENCODING –>n\”;
$Contents = ob_get_contents();
ob_end_clean();
if ($debug){
$s = \”<p>Not compress length: \”.strlen($Contents);
$s .= \”
Compressed length: \”.strlen(gzcompress($Contents,$level));
$Contents .= $s;
}
header(\”Content-Encoding: $ENCODING\”);
print \”x1fx8bx08x00x00x00x00x00\”;
$Size = strlen($Contents);
$Crc = crc32($Contents);
$Contents = gzcompress($Contents,$level);
$Contents = substr($Contents, 0, strlen($Contents) - 4);
print $Contents;
print pack(\’V\’,$Crc);
print pack(\’V\’,$Size);
exit;
}else{
ob_end_flush();
exit;
}
}
?>

这是catoc的一段很早以前的代码,是在weblogs.com看到的,他利用了zlib的函数,对传输的内容进行了压缩,测试表明,对于10k以上的页面,会产生效果,而且页面越大,效果越明显……

Apache环境下PHP利用HTTP缓存协议原理解析及应用分析

没有评论

2010 年 09 月 18 日 at 下午 9:20分类:PHP

一、先来看第一种情况:apache 静态页面

apache发送给客户端的静态页面一般包含Last-Modified和Etag,这两个标签的值来自静态文件的修改时间和inode。

下面是截取得apache返回客户端的头

XML/HTML代码

复制代码 代码如下:
Last-Modified: Fri, 26 Jan 2007 01:53:34 GMT
ETag: “3f9f640-318-cb9f8380″

搜索引擎之所以喜欢静态文件是因为有这两个标识,可以判断文件是否更新过

二、PHP等动态页面

由于php是动态生成的,它的内容是不能根据php程序的时间来确定最后修改日期,所以默认php返回客户端的时候补包含任何缓存控制,要想利用好缓存就必须了解缓存机制,和理减少b,s的交互,缩减带宽流量,减轻服务器负担…好处多多。

三、缓存控制的具体含义

先解释一下本人经过测试理解的这几个标签的含义

Cache- Control:指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。 请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响 应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、 proxy-revalidate、max-age。

各个消息中的指令含义如下:

Public指示响应可被任何缓存区缓存。

Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。

no-cache指示请求或响应消息不能缓存

no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。

max-age指示客户机可以接收生存期不大于指定时间(以秒为单位)的响应。

min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。

max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

php用法:

在输出之前用header(),(如果使用ob_start()可以将header放在程序任意地方)

PHP代码

复制代码 代码如下:
header(‘Cache-Control: max-age=8′);

max-age=8表示最大生存期8秒,超过8秒浏览器必须去服务器重新读取,这个时间是以用户的读取页面开始计时的,而Expires是绝对时间。

Expires:缓存过期的绝对时间,如果过了它指定的那个时间点,浏览器就不认缓存了,要去服务器重新请求一份最新的。

Last-Modified:文档的最后修改时间,它的妙用就是:1

如果是静态文件,客户端会发上来它缓存里的时间,apache会来比对,如果发现没有修改就直接返回一个头,状态码是304,字节数非常少,(高级版本还会增加比较Etag来确定文件是否变化)

2 php动态文件:

客户端发上比对时间,php会判断是否修改,如果修改时间相同,就只会返回1024字节,至于为什么返回1024不得而知,如果你的php生成的文件非常大,它也只返回1024,所以比较省带宽,客户端会根据服务器端发过来的修改时间自动从缓存文件里显示。

注:如果没有Last-Modified头,Cache-Control和Expires也是可以起作用的,但每次请求要返回真实的文件字节数,而不是1024

四、HOW ?

静态页面不用去管它了,如果想更好的控制静态页面的缓存,apache有几个模块可以很好的控制,这里不讨论

php页面:

这里分两种:

1、 不经常改动的页面,类似新闻发布,这类页面的特点:第一次发布之后会有几次改动,随着时间推移基本不会再修改。控制策略应该是:1第一次发布之发送 Last-Modified,max-age设定1天,修改过之后更新Last-Modified,max-age时间随着修改次数正常。这样似乎比较繁 琐,还要记录修改次数,也可以预计一下下次可能的修改时间用Expires指定到大概时间过期

PHP代码

复制代码 代码如下:
//header(‘Cache-Control: max-age=86400′);//缓存一天
header(‘Expires: Mon, 29 Jan 2007 08:56:01 GMT’);//指定过期时间
header(‘Last-Modified: ‘.gmdate(‘D, d M Y 01:01:01′,$time).’GMT’);//格林尼治时间,$time是文件添加时候的时间戳

2 经常改动的页面

类似bbs,论坛程序,这种页面更新速度比较快,缓存的主要作用是防止用户频繁刷新列表,导致服务器数据库负担,既要保证更新的及时性,也要保证缓存能被利用

这里一般用Cache-Control来控制,根据论坛的发帖的频率灵活控制max-age。

PHP代码

复制代码 代码如下:
header(‘Cache-Control: max-age=60′);//缓存一分钟
header(‘Last-Modified: ‘.gmdate(‘D, d M Y 01:01:01′,$time).’GMT’);//格林尼治时间,$time是帖子的最后更新时间戳

五 额外

1 刷新,转到,强制刷新的区别

浏览器上有刷新和转到按键,有的浏览器支持用ctrl+F5强制刷新页面,它们的区别是什么?

转到:用户点击链接就是转到,它完全使用缓存机制,如果有Last-Modified那么不会和服务器通讯,用抓包工具可以查看到发送字节是0byte,如果缓存过期,那么它会执行F5刷新的动作。

刷新(F5):这种刷新也是根据缓存是否有Last-Modified来决定,如果有会转入304或1024(php),如果没有最后更新时间那么去服务器读取,返回真实文档大小

强制刷新:完全抛弃缓存机制,去服务器读取最新文档,向服务器发送的header如下

XML/HTML代码

复制代码 代码如下:
Cache-Control: no-cache

2 调试工具

查看浏览器和服务器交互比较好的工具是httpwatch pro,现在的版本4.1,支持ie7

还有别的代理抓包工具可以分析,http debugging。没用过,还有tcp抓包工具,2000自带的network。另外还有tcp抓包工具,2000自带的network monitor不过不是专门针对http的比较难用。

MySQL常用函数

没有评论

2010 年 09 月 18 日 at 下午 9:12分类:MySQL

1、mysql_connect()-建立数据库连接
格式:
resource mysql_connect([string hostname [:port] [:/path/to/socket] [, string username] [, string password]])
例:
$conn = @mysql_connect(“localhost”, “username”, “password”) or die(“不能连接到Mysql Server”);
说明:使用该连接必须显示的关闭连接

2、mysql_pconnect()-建立数据库连接
格式:
resource mysql_pconnect([string hostname [:port] [:/path/to/socket] [, string username] [, string password]])
例:
$conn = @mysql_pconnect(“localhost”, “username”, “password”) or dir(“不能连接到Mysql Server”);
说明:使用该连接函数不需要显示的关闭连接,它相当于使用了连接池

3、mysql_close()-关闭数据库连接
例:
$conn = @mysql_connect(“localhost”, “username”, “password”) or die(“不能连接到Mysql Server”);
@mysql_select_db(“MyDatabase”) or die(“不能选择这个数据库,或数据库不存在”);
echo “你已经连接到MyDatabase数据库”;
mysql_close();

4、mysql_select_db()-选择数据库
格式:
boolean mysql_select_db(string db_name [, resource link_id])
例:
$conn = @mysql_connect(“localhost”, “username”, “password”) or die(“不能连接到Mysql Server”);
@mysql_select_db(“MyDatabase”) or die(“不能选择这个数据库,或数据库不存在”);

5、mysql_query()-查询MySQL
格式:
resource mysql_query (string query, [resource link_id])
例:
$linkId = @mysql_connect(“localhost”, “username”, “password”) or die(“不能连接到Mysql Server”);
@mysql_select_db(“MyDatabase”) or die(“不能选择这个数据库,或者数据库不存在”);
$query = “select * from MyTable”;
$result = mysql_query($query);
mysql_close();
说明:若SQL查询执行成功,则返回资源标识符,失败时返回FALSE。若执行更新成功,则返回TRUE,否则返回FALSE

6、mysql_db_query()-查询MySQL
格式:
resource mysql_db_query(string database, string query [, resource link_id])
例:
$linkId = @mysql_connect(“localhost”, “username”, “password”) or die(“不能连接到MysqlServer”);
$query = “select * from MyTable”;
$result = mysql_db_query(“MyDatabase”, $query);
mysql_close();
说明:为了使代码清晰,不推荐使用这个函数调用

7、mysql_result()-获取和显示数据
格式:
mixed mysql_result (resource result_set, int row [, mixed field])
例:
$query = “select id, name from MyTable order by name”;
$result = mysql_query($query);
for($count=0;$count<=mysql_numrows($result);$count++)
{
$c_id = mysql_result($result, 0, “id”);
$c_name = mysql_result($result, 0, “name”);
echo $c_id,$c_name;
}
说明:最简单、也是效率最低的数据获取函数

8、mysql_fetch_row()-获取和显示数据
格式:
array mysql_fetch_row (resource result_set)
例:
$query = “select id, name from MyTable order by name”;
$result = mysql_query($query);
while (list($id, $name) = mysql_fetch_row($result)) {
echo(“Name: $name ($id) <br />”);
}
说明:函数从result_set中获取整个数据行,将值放在一个索引数组中。通常会结使list()函数使用

9、mysql_fetch_array()-获取和显示数据
格式:
array mysql_fetch_array (resource result_set [, int result_type])
例:
$query = “select id, name from MyTable order by name”;
$result = mysql_query($query);
while($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$id = $row["id"];
$name = $row["name"];
echo “Name: $name ($id) <br />”;
}
又例:
$query = “select id, name from MyTable order by name”;
$result = mysql_query($query);
while($row = mysql_fetch_array($result, MYSQL_NUM)) {
$id = $row[0];
$name = $row[1];
echo “Name: $name ($id) <br />”;
}
说明:
result_type的值有:
MYSQL_ASSOC: 字段名表示键,字段内容为值
MYSQL_NUM: 数值索引数组,操作与mysql_fetch_ros()函数一样
MYSQL_BOTH: 即作为关联数组又作为数值索引数组返回。result_type的默认值。

10、mysql_fetch_assoc()-获取和显示数据
格式:
array mysql_fetch_assoc (resource result_set)
相当于调用 mysql_fetch_array(resource, MYSQL_ASSOC);

11、mysql_fetch_object()-获取和显示数据
格式:
object mysql_fetch_object(resource result_set)
例:
$query = “select id, name from MyTable order by name”;
while ($row = mysql_fetch_object($result)) {
$id = $row->id;
$name = $row->name;
echo “Name: $name ($id) <br />”;
}
说明:返回一个对象,在操作上与mysql_fetch_array()相同

12、mysql_num_rows()-所选择的记录的个数
格式:
int mysql_num_rows(resource result_set)
例:
query = “select id, name from MyTable where id > 65″;
$result = mysql_query($query);
echo “有”.mysql_num_rows($result).”条记录的ID大于65″;
说明:只在确定select查询所获取的记录数时才有用。

13、mysql_affected_rows()-受Insert,update,delete影响的记录的个数
格式:
int mysql_affected_rows([resource link_id])
例:
$query = “update MyTable set name=’CheneyFu’ where id>=5″;
$result = mysql_query($query);
echo “ID大于等于5的名称被更新了的记录数:”.mysql_affected_rows();
说明:该函数获取受INSERT,UPDATE或DELETE更新语句影响的行数

14、mysql_list_dbs()-获取数据库列表信息
格式:
resource mysql_list_dbs([resource link_id])
例:
mysql_connect(“localhost”, “username”, “password”);
$dbs = mysql_list_dbs();
echo “Databases: <br />”;
while (list($db) = mysql_fetch_rows($dbs)) {
echo “$db <br />”;
}
说明:显示所有数据库名称

15、mysql_db_name()-获取数据库名
格式:
string mysql_db_name(resource result_set, integer index)
说明:该函数获取在mysql_list_dbs()所返回result_set中位于指定index索引的数据库名

16、mysql_list_tables()-获取数据库表列表
格式:
resource mysql_list_tables(string database [, resource link_id])
例:
mysql_connect(“localhost”, “username”, “password”);
$tables = mysql_list_tables(“MyDatabase”);
while (list($table) = mysql_fetch_row($tables)) {
echo “$table <br />”;
}
说明:该函数获取database中所有表的表名

17、mysql_tablename()-获取某个数据库表名
格式:
string mysql_tablename(resource result_set, integer index)
例:
mysql_connect(“localhost”, “username”, “password”);
$tables = mysql_list_tables(“MyDatabase”);
$count = -1;
while (++$count < mysql_numrows($tables)) {
echo mysql_tablename($tables, $count).”<br />”;
}
说明:该函数获取mysql_list_tables()所返回result_set中位于指定index索引的表名

18、mysql_fetch_field()-获取字段信息
格式:
object mysql_fetch_field(resource result [, int field_offset])
例:
mysql_connect(“localhost”, “username”, “password”);
mysql_select_db(“MyDatabase”);
$query = “select * from MyTable”;
$result = mysql_query($query);
$counts = mysql_num_fields($result);
for($count = 0; $count < $counts; $count++) {
$field = mysql_fetch_field($result, $count);
echo “<p>$field->name $field->type ($field->max_length) </p>”;
}
说明:
返回的对象共有12个对象属性:
name: 字段名
table: 字段所在的表
max_length:字段的最大长度
not_null: 如果字段不能为null,则为1,否则0
primary_key: 如果字段为主键,则为1,否则0
unique_key: 如果字段是唯一键,则为1, 否则0
multiple_key: 如果字段为非唯一,则为1,否则0
numeric: 如果字段为数值则为1,否则0
blob: 如果字段为BLOB则为1,否则为0
type: 字段的数据类型
unsigned: 如果字段为无符号数则为1,否则为0
zerofill: 如果字段为“零填充”则为1, 否则为0

19、mysql_num_fields()-获取查询的字段个数
格式:
integer mysql_num_fields(resource result_set)
例:
$query = “select id,name from MyTable order by name”;
$result = mysql_query($query);
echo “这个查询的字段数是:”.mysql_num_fields($result).”<br />”;

20、mysql_list_fields()-获取指定表的所有字段的字段名
格式:
resource mysql_list_fields (string database_name, string table_name [, resource link_id])
例:
$fields =mysql_list_fields(“MyDatabase”, “MyTable”);
echo “数据库MyDatabase中表MyTable的字段数: “.mysql_num_fields($fields).”<br />”;

21、mysql_field_flags()-获取指定的字段选项
格式:
string mysql_field_flags (resource result_set, integer field_offset)
例:
$query = “select id, name from MyTable order by name”;
$result = mysql_query($query);
$row=mysql_fetch_wor($row);

22、mysql_field_len()-获取指定的字段的最大长度
格式:
integer mysql_field_len (resource result_set, integer field_offset)
例:
$query = “select name from MyTable”;
$result = mysql_query($query);
$row = mysql_fetch_row($result);
echo mysql_field_len($result, 0).”<br />”;
说明:
如果mysql_field_len($reseult, 0) = 16777215
那么numer_format(mysql_field_len($result))等于16,777,215

23、mysql_field_name()-获取字段名
格式:
string mysql_field_name (resource result_set, int field_offset)
例:
$query = “select id as PKID, name from MyTable order by name”;
$result = mysql_query($query);
$row = mysql_fetch_row($result);
echo mysql_field_name($result, 0); // Result: PKID

24、mysql_field_type()-获取字段类型
格式:
string mysql_field_type (resource result_set, int field_offset)
例:
$query = “select id, name from MyTable order by name”;
$result = mysql_query($query);
$row = mysql_fetch_row($result);
echo mysql_field_type($result, 0); // Result: int

25、mysql_field_table()-获取字段所在表名
格式:
string mysql_field_table (resource result_set, int field_offset)
例:
$query = “select id as PKID, name from MyTable order by name”;
$result = mysql_query($query);
$row = mysql_fetch_row($result);
echo mysql_field_table($result, 0); // Result: MyTable