<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>风雪之隅 &#187; 转载</title>
	<atom:link href="http://www.laruence.com/category/%e8%bd%ac%e8%bd%bd/feed" rel="self" type="application/rss+xml" />
	<link>http://www.laruence.com</link>
	<description>PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 - 左手代码 右手诗</description>
	<lastBuildDate>Wed, 08 Feb 2012 05:12:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>PHP的历史</title>
		<link>http://www.laruence.com/2012/01/11/2482.html</link>
		<comments>http://www.laruence.com/2012/01/11/2482.html#comments</comments>
		<pubDate>Wed, 11 Jan 2012 03:14:30 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP 3.0]]></category>
		<category><![CDATA[PHP 4]]></category>
		<category><![CDATA[PHP/FI]]></category>
		<category><![CDATA[历史]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2482</guid>
		<description><![CDATA[了解下PHP的历史, 有助于更加深刻的了解PHP发展到今天的轨迹,  下面的文字都是从<a href="http://www.php.net/manual/zh/history.php">» PHP手册</a>中转载过来的.

PHP 在过去的几年里走过了漫长的道路。成长为处理 web 的最卓越的语言并非易事。如果对 PHP 如何发展到今天很感兴趣，那么请继续读下去吧。以前的 PHP 发行版可以在 <a herf="http://museum.php.net/">» PHP 博物馆</a>找到。]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2012/01/11/2482.html"  title="Permanet Link to PHP的历史" >http://www.laruence.com/2012/01/11/2482.html</a></li>
<li>文章转自: <a href="http://www.php.net/manual/zh/history.php" >PHP 及其相关工程的历史</a></li>
</ul></div>
<p>了解下PHP的历史, 有助于更加深刻的了解PHP发展到今天的轨迹,  下面的文字都是从<a href="http://www.php.net/manual/zh/history.php" >» PHP手册</a>中转载过来的.</p>
<p>PHP 在过去的几年里走过了漫长的道路。成长为处理 web 的最卓越的语言并非易事。如果对 PHP 如何发展到今天很感兴趣，那么请继续读下去吧。以前的 PHP 发行版可以在 <a herf="http://museum.php.net/" >» PHP 博物馆</a>找到。</p>
<h3>PHP/FI</h3>
<p>PHP 继承自一个老的工程，名叫 PHP/FI。PHP/FI 在 1995 年由 Rasmus Lerdorf 创建，最初只是一套简单的 Perl 脚本，用来跟踪访问他主页的人们的信息。它给这一套脚本取名为“Personal Home Page Tools”。随着更多功能需求的增加，Rasmus 写了一个更大的 C 语言的实现，它可以访问数据库，可以让用户开发简单的动态 Web 程序。Rasmus » 发布了 PHP/FI 的源代码，以便每个人都可以使用它，同时大家也可以修正它的 Bug 并且改进它的源代码。</p>
<p>PHP/FI，一个专为个人主页／表单提供解释程序的程序，已经包含了今天 PHP 的一些基本功能。它有着 Perl 样式的变量，自动解释表单变量，并可以嵌入 HTML。语法本身与 Perl 很相似，但是它很有限，很简单，还稍微有些不协调。</p>
<p>到1997年，PHP/FI 2.0，也就是它的 C 语言实现的第二版在全世界已经有几千个用户（估计）和大约 50,000 个域名安装，大约是 Internet 所有域名的 1%。但是那时只有几个人在为该工程撰写少量当代码，它仍然只是一个人的工程。</p>
<p>PHP/FI 2.0 在经历了数个 beta 版本的发布后于 1997 年 11 月发布了官方正式版本。不久，PHP 3.0 的第一个 alpha 版本的发布，PHP 从此走向了成功。</p>
<h3>PHP 3</h3>
<p>PHP 3.0 是类似于当今 PHP 语法结构的第一个版本。Andi Gutmans 和 Zeev Suraski 在为一所大学的项目中开发电子商务程序时发现 PHP/FI 2.0 功能明显不足，于是他们重写了代码。这就是 PHP 3.0。经过Andi，Rasmus 和 Zeev 一系列的努力，考虑到 PHP/FI 已存在的用户群，他们决定联合发布 PHP 3.0 作为 PHP/FI 2.0 的官方后继版本。而 PHP/FI 2.0 的进一步开发几乎终止了。</p>
<p>PHP 3.0 的一个最强大的功能是它的可扩展性。除了给最终用户提供数据库、协议和 API 的基础结构，它的可扩展性还吸引了大量的开发人员加入并提交新的模块。后来证实，这是 PHP 3.0 取得巨大成功的关键。PHP 3.0 中的其它关键功能包括面向对象的支持和更强大和协调的语法结构。</p>
<p>这个全新的语言伴随着一个新的名称发布。它从 PHP/FI 2.0 的名称中移去了暗含“本语言只限于个人使用”的部分。它被命名为简单的缩写“PHP”。这是一种递归的缩写，它的全称是——PHP: Hypertext Preprocessor。</p>
<p>1998 年末，PHP 的安装人数几近 10,000，有大约 100,000 个网站报告他们使用了 PHP。在 PHP 3.0 的顶峰，Internet 上 10% 的 web 服务器上都安装了它。</p>
<p>约九个月的公开测试后，官方于 1998 年 6 月正式发布 PHP 3.0。</p>
<h3>PHP 4</h3>
<p>1998 年的冬天，PHP 3.0 官方发布不久，Andi Gutmans 和 Zeev Suraski 开始重新编写 PHP 代码。设计目标是增强复杂程序运行时的性能和 PHP 自身代码的模块性。PHP 3.0 的新功能和广泛的第三方数据库、API的支持使得这样程序的编写成为可能，但是 PHP 3.0 没有高效处理如此复杂程序的能力。</p>
<p>新的被称为“Zend Engine”（这是 Zeev 和 Andi 的缩写）的引擎，成功的实现了设计目标，并在 1999 年中期首次引入 PHP。基于该引擎并结合了更多新功能的 PHP 4.0，在 PHP 3.0 发布两年后，于2000年5月发布了官方正式版本。除了更高的性能以外，PHP 4.0 还包含了其它一些关键功能，比如：支持更多的 web 服务器；HTTP Sessions 支持；输出缓冲；更安全的处理用户输入的方法；一些新的语言结构。</p>
<p>今天，已经有 10,000 名开发人员（估计）和几百万网站报告已安装了 PHP，占整个 Internet 域名的 20%。</p>
<p>PHP 的开发小组有很多优秀的开发人员，同时还有大量的优秀人才在进行 PHP 相关工程的开发工作，如 PEAR 和 PHP 文档的工程。</p>
<h3>PHP 5</h3>
<p>PHP 5 在长时间的开发及多个预发布版本后，于 2004 年 7 月发布正式版本。它的核心是 Zend 引擎 2 代，引入了新的对象模型和大量新功能。</p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2012/01/11/2482.html" >2012/01/11</a>, <a href="http://hi.baidu.com/higkoo"  rel="external nofollow"  class="url" >higkoo</a> writes: 好事多磨，愿PHP越来越好，越来越强！</li><li><a href="http://www.laruence.com/2012/01/11/2482.html" >2012/01/11</a>, <a href="http://deloz.net"  rel="external nofollow"  class="url" >Deloz</a> writes: C是很多语言的基础呀.</li><li><a href="http://www.laruence.com/2012/01/11/2482.html" >2012/01/11</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</a> writes: 总是能多些思考，感谢。</li><li><a href="http://www.laruence.com/2012/01/11/2482.html" >2012/01/12</a>, <a href="http://blog.netoearth.com/html/201201/php%e7%9a%84%e5%8e%86%e5%8f%b2.htm"  rel="external nofollow"  class="url" >PHP的历史</a> writes: [...] 本文地址: http://www.laruence.com/2012/01/11/2482.html [...]</li><li><a href="http://www.laruence.com/2012/01/11/2482.html" >2012/01/13</a>, harveyzh writes: 为什么创造php的作者 Rasmus Lerdorf 离开了？</li><li><a href="http://www.laruence.com/2012/01/11/2482.html" >2012/01/17</a>, <a href="http://gnroed@gmail.com"  rel="external nofollow"  class="url" >nroe</a> writes: 我们在更新到　５.３.９　版本后发现，出现很多　“no buffer space available”　的错误提示，导致　TCP/IP SOCKET　无法创建，服务无法正常运行。
请问下　5.3.9　在创建　SOCKET　的是否是不是加大了缓冲区？</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/09/19/2148.html"  title="PHP的版本发布历程" >PHP的版本发布历程</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li><li><a href="http://www.laruence.com/2011/12/29/2412.html"  title="通过构造Hash冲突实现各种语言的拒绝服务攻击" >通过构造Hash冲突实现各种语言的拒绝服务攻击</a></li><li><a href="http://www.laruence.com/2011/12/06/2381.html"  title="更简单的重现PHP Core的调用栈" >更简单的重现PHP Core的调用栈</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/01/11/2482.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>2012年1月全球www网站技术报告</title>
		<link>http://www.laruence.com/2012/01/07/2453.html</link>
		<comments>http://www.laruence.com/2012/01/07/2453.html#comments</comments>
		<pubDate>Sat, 07 Jan 2012 09:21:15 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[排行]]></category>
		<category><![CDATA[统计]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2453</guid>
		<description><![CDATA[ <a href="http://w3techs.com/">W3Techs</a>在2012年1月7日, 发出最新的"全球www网站技术报告".

    该统计基于对全球Alexa排名前100W的www网站做分析而得出.

    统计报告(<a href="http://w3techs.com/technologies/overview/programming_language/all">Usage of server-side programming languages for websites</a>)显示, 相比2011年12月, 使用PHP构建的前100W名中的网站,又增长了约0.1%(30个), PHP占据的份额增长至77.3%, 依旧排名第一.]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2012/01/07/2453.html"  title="Permanet Link to 2012年1月全球www网站技术报告" >http://www.laruence.com/2012/01/07/2453.html</a></li>
<li>文章转自: <a href="http://w3techs.com/technologies/overview/programming_language/all" >Usage of server-side programming languages for websites</a></li>
</ul></div>
<p>
    <a href="http://w3techs.com/" >W3Techs</a>在2012年1月7日, 发出最新的&#8221;全球www网站技术报告&#8221;.</p>
<p>    该统计基于对全球Alexa排名前100W的www网站做分析而得出.</p>
<p>    统计报告(<a href="http://w3techs.com/technologies/overview/programming_language/all" >Usage of server-side programming languages for websites</a>)显示, 相比2011年12月, 使用PHP构建的前100W名中的网站,又增长了约0.1%(30个), PHP占据的份额增长至77.3%, 依旧排名第一.<br/>
    <div id="attachment_2454"  class="wp-caption aligncenter"  style="width: 534px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/W3techs统计.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/W3techs统计.png"  alt=""  title="W3techs统计"  width="524"  height="244"  class="size-full wp-image-2454" /></a><p class="wp-caption-text" >W3Techs全球www技术统计报告2012年1月</p></div></p>
<p>    下图显示了1年来的各语言的趋势(来自:<a href="http://w3techs.com/technologies/history_overview/programming_language" >Historical trends in the usage of server-side programming languages for websites</a>):<br/>
 <div id="attachment_2456"  class="wp-caption aligncenter"  style="width: 310px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/www技术趋势1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/www技术趋势1-300x71.png"  alt=""  title="www技术趋势"  width="300"  height="71"  class="size-medium wp-image-2456" /></a><p class="wp-caption-text" >历史发展趋势</p></div></p>
<p>    而, 下图是使用的PHP版本统计:<br/>
<div id="attachment_2457"  class="wp-caption aligncenter"  style="width: 449px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/PHP版本.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/PHP版本.png"  alt=""  title="PHP版本"  width="439"  height="146"  class="size-full wp-image-2457" /></a><p class="wp-caption-text" >PHP版本对比</p></div></p>
<p>    可见, 已经全面进入PHP5的时代了,但使用PHP4的网站还是有很大的数量.  </p>
<p>    上面提到的是www网站的服务端编程语言的对比, 而对于Client端的编程语言, 依旧还是Javascript的天下, 占到了90%以上:<br/>
     <div id="attachment_2463"  class="wp-caption aligncenter"  style="width: 399px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/未命名图片.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/未命名图片.png"  alt=""  title="Client端编程语言"  width="389"  height="147"  class="size-full wp-image-2463" /></a><p class="wp-caption-text" >Client端编程语言</p></div></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/07</a>, <a href="http://www.xingdonghai.cn"  rel="external nofollow"  class="url" >伴夜</a> writes: 支持PHP</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/07</a>, <a href="http://www.cnxct.com"  rel="external nofollow"  class="url" >CFC4N</a> writes: 1,perl居然比python多，意料之外(我见识短)。
2,ASP.NET递减，JAVA缓慢增长。
3,ColdFusion居然出现了，而且，排第四，惊讶！(我见识短)。</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/08</a>, dryangkun writes: Hypertext Preprocessor从名字上就能看出PHP的定位，加油,PHP...</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/08</a>, <a href="http://www.hostsir.com"  rel="external nofollow"  class="url" >域名注册</a> writes: asp.net的上升趋势不能忽视，包含asp吗？</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/08</a>, <a href="http://www.tanglei.name"  rel="external nofollow"  class="url" >tanglei</a> writes: php用于快速迭代方面实在有优势。不过能否知道有多少在用php的面向对象编程呢?所在公司用php开发没有利用其OO方面的特性。</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/09</a>, nardoo writes: 用OO方面的特性的公司比较少吧， 受限于公司的历史代码，重构也比较麻烦。</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/09</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</a> writes: PHP和JS必须要双精！双精了以后，就不愁以后没前途了。</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/09</a>, <a href="http://blog.iterse.com"  rel="external nofollow"  class="url" >Iterse's blog</a> writes: 支持下！</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/15</a>, cers writes: 各种语言的设计初衷和目的不同，PHP就是为Web而生的，其它的语言则不是</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/01/17</a>, <a href="http://litefeel.com"  rel="external nofollow"  class="url" >lite3</a> writes: 虽然我是做AS的,但是对于网站,前端还是建议用HTML,JS, Flash要做游戏的</li><li><a href="http://www.laruence.com/2012/01/07/2453.html" >2012/02/03</a>, <a href="http://www.hihoku.com"  rel="external nofollow"  class="url" >蚂蚁</a> writes: 哈哈 python 居然有下降的趋势，ColdFusion 搞不懂为什么会排在这里</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/12/29/2412.html"  title="通过构造Hash冲突实现各种语言的拒绝服务攻击" >通过构造Hash冲突实现各种语言的拒绝服务攻击</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li><li><a href="http://www.laruence.com/2011/12/06/2381.html"  title="更简单的重现PHP Core的调用栈" >更简单的重现PHP Core的调用栈</a></li><li><a href="http://www.laruence.com/2011/11/18/2305.html"  title="GBK编码PHP脚本导致语法错误(Zend Multibyte)" >GBK编码PHP脚本导致语法错误(Zend Multibyte)</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/01/07/2453.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>PHP数组的Hash冲突实例</title>
		<link>http://www.laruence.com/2011/12/30/2435.html</link>
		<comments>http://www.laruence.com/2011/12/30/2435.html#comments</comments>
		<pubDate>Fri, 30 Dec 2011 06:30:46 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[hash]]></category>
		<category><![CDATA[Hash collision]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[性能]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2435</guid>
		<description><![CDATA[   上一篇文章, 我介绍了一个<a href="http://www.laruence.com/2011/12/29/2412.html">利用Hash冲突(碰撞)来对各种语言(包括,PHP, Java, Ruby等等)实施拒绝服务攻击的可能</a>,  但是没有给出实例,  文章发出后, @Ferrari同学给出了一个另外一篇文章<a href="http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html">Supercolliding a PHP array</a>, 文章中作者介绍了一种基于PHP的冲突实例, 以及带来的性能恶化对比. 我就借花献佛, 翻译给大家看看.

    你知道不知道, 插入65536个经过构造的键值的元素到PHP数组, 会需要耗时30秒以上?  而一般的这个过程仅仅需要0.1秒..]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/12/30/2435.html"  title="Permanet Link to PHP数组的Hash冲突实例" >http://www.laruence.com/2011/12/30/2435.html</a></li>
<li>文章转自: <a href="http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html" >Supercolliding a PHP array</a></li>
</ul></div>
<p>
    上一篇文章, 我介绍了一个<a href="http://www.laruence.com/2011/12/29/2412.html" >利用Hash冲突(碰撞)来对各种语言(包括,PHP, Java, Ruby等等)实施拒绝服务攻击的可能</a>,  但是没有给出实例,  文章发出后, @Ferrari同学给出了一个另外一篇文章<a href="http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html" >Supercolliding a PHP array</a>, 文章中作者介绍了一种基于PHP的冲突实例, 以及带来的性能恶化对比. 我就借花献佛, 翻译给大家看看.</p>
<p>    你知道不知道, 插入65536个经过构造的键值的元素到PHP数组, 会需要耗时30秒以上?  而一般的这个过程仅仅需要0.1秒..</p>
<p>    请看如下的例子:</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
$size = pow(2, 16); 

$startTime = microtime(true);
$array = array();
for ($key = 0, $maxKey = ($size - 1) * $size; $key &lt;= $maxKey; $key += $size) {
    $array[$key] = 0;
}
$endTime = microtime(true);
echo '插入 ', $size, ' 个恶意的元素需要 ', $endTime - $startTime, ' 秒', &quot;\n&quot;;

$startTime = microtime(true);
$array = array();
for ($key = 0, $maxKey = $size - 1; $key &lt;= $maxKey; ++$key) {
    $array[$key] = 0;
}
$endTime = microtime(true);
echo '插入 ', $size, ' 个普通元素需要 ', $endTime - $startTime, ' 秒', &quot;\n&quot;;
</pre>
<p>上面的例子, 在我的机器上的执行结果如下:</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
插入 65536 个恶意的元素需要 43.1438360214 秒
插入 65536 个普通元素需要 0.0210378170013 秒
</pre>
<p>这个差别是不是很夸张?!</p>
<p>我在<a href="http://www.laruence.com/2011/12/29/2412.html" >上一篇文章中</a>介绍过,  经过特殊构造的键值,  使得PHP每一次插入都会造成Hash冲突, 从而使得PHP中array的底层Hash表退化成链表:<br/>
<div id="attachment_2415"  class="wp-caption aligncenter"  style="width: 618px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/Untitled3.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/Untitled3.png"  alt=""  title="Hash collision"  width="608"  height="223"  class="size-full wp-image-2415" /></a><p class="wp-caption-text" >Hash collision</p></div><br/>
这样在每次插入的时候PHP都需要遍历一遍这个链表, 大家可以想象,  第一次插入, 需要遍历0个元素, 第二次是1个, 第三次是3个, 第65536个是65535个, 那么总共就需要65534*65535/2=2147385345次遍历&#8230;.</p>
<p>那么, 这个键值是怎么构造的呢?</p>
<p>在PHP中,如果键值是数字, 那么Hash的时候就是数字本身,  一般的时候都是, index &#038; tableMask.  而tableMask是用来保证数字索引不会超出数组可容纳的元素个数值, 也就是数组个数-1.</p>
<p>PHP的Hashtable的大小都是2的指数, 比如如果你存入10个元素的数组, 那么数组实际大小是16, 如果存入20个, 则实际大小为32,   而63个话, 实际大小为64.  当你的存入的元素个数大于了数组目前的最多元素个数的时候, PHP会对这个数组进行扩容, 并且从新Hash.</p>
<p>现在,  我们假设要存入64个元素(中间可能会经过扩容, 但是我们只需要知道, 最后的数组大小是64, 并且对应的tableMask为63:0111111),  那么如果第一次我们存入的元素的键值为0,  则hash后的值为0,  第二次我们存入64, hash(1000000 &#038; 0111111)的值也为0, 第三次我们用128, 第四次用192&#8230; 就可以使得底层的PHP数组把所有的元素都Hash到0号bucket上, 从而使得Hash表退化成链表了.</p>
<p>当然, 如果键值是字符串的话, 就稍微比较麻烦一些了, 但是PHP的<a href="http://www.laruence.com/2009/07/23/994.html" >Hash算法</a>是开源的, 已知的, 所以有心人也可以做到&#8230;<br/>
<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, <a href="http://kimbs.cn"  rel="external nofollow"  class="url" >kim</a> writes: 沙发！
简单地说就是，通过构造一个 url ，或者一个 form ，参数的 key 就按这么 $key += $size 计算，那么就能拖慢所有使用存在此缺陷的 server ~，oh my god.</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, mahone writes: 灰常不错，受教了。。。</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, mahone writes: 刚测试了下，发现个问题，请教下
在我本地虚拟机（32位ubuntu系统，512m内存，1核cpu，2.66GHz）上跑上面的程序：
插入 65536 个恶意的元素需要 90.800883054733 秒
插入 65536 个普通元素需要 0.026834011077881 秒
服务器（64位系统，2g内存，4核1.60GHz）上跑：
插入 65536 个恶意的元素需要 190.03647112846 秒
插入 65536 个普通元素需要 0.027021884918213 秒

这个差距是因为cpu频率的关系？php能利用多核的优势么？还是因为系统是32位或者64位的关系？</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, <a href="http://www.laruence.com/2011/12/30/2440.html"  rel="external nofollow"  class="url" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch | 风雪之隅</a> writes: [...] PHP数组的Hash冲突实例  ), 这个攻击方法危害很高, 攻击成本也很小. [...]</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, <a href="http://hjin.me"  rel="external nofollow"  class="url" >HJin_me</a> writes: 鸟哥，你的半官方补丁能发布出来么～～对很多人来说，非稳定版本的不敢用啊。</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, <a href="http://blog.biaojita.com"  rel="external nofollow"  class="url" >dk</a> writes: 控制一下GPC三个超全局变量的解析时间是否就解决了潜在的DDOS攻击呢？</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/30</a>, <a href="http://www.xingdonghai.cn/a-new-supercolliding-with-array-of-php/"  rel="external nofollow"  class="url" >关于最近PHP的Array爆出的冲突问题 | 东海博客</a> writes: [...] 详细内容：http://www.laruence.com/2011/12/30/2435.html [...]</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/31</a>, <a href="http://blog.csdn.net/linvo"  rel="external nofollow"  class="url" >linvo</a> writes: 请教鸟哥，有一点我还是不太明白，$size=pow(2, n)中n取值的缘由？
我把代码做了一些修改后测试发现，当n取值为14~18的时候，效果最好。大于或小于的话，速度都会明显变快。</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2011/12/31</a>, wow writes: [root@WangXJ php_test]# time  php f.php 
插入 65536 个普通元素需要  0.053505897521973 sec

real	0m0.086s
user	0m0.080s
sys	0m0.004s

大神 我想请教下 为什么time 命令统计的时间real time会大于php自己统计的时间呢</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2012/01/06</a>, a writes: 请问，怎么用这个BUG攻击你的blog？挺起来好象这BUG很厉害的样子。</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2012/01/07</a>, <a href="http://blog.jobbole.com/11516/"  rel="external nofollow"  class="url" >PHP哈希表碰撞攻击原理 - 博客 - 伯乐在线</a> writes: [...] [4] PHP数组的Hash冲突实例 [...]</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2012/01/11</a>, <a href="http://ok"  rel="external nofollow"  class="url" >jimmyyem</a> writes: 看了好久，为了一些人才看明白，很受教</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/07/23/994.html"  rel="bookmark"  title="Permanent Link: PHP中的Hash算法" >PHP中的Hash算法</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/10/15/1131.html"  title="提升PHP性能之改变Zend引擎分发方式" >提升PHP性能之改变Zend引擎分发方式</a></li><li><a href="http://www.laruence.com/2009/07/23/994.html"  title="PHP中的Hash算法" >PHP中的Hash算法</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/29/2412.html"  title="通过构造Hash冲突实现各种语言的拒绝服务攻击" >通过构造Hash冲突实现各种语言的拒绝服务攻击</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/30/2435.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Yaf的性能对比测试</title>
		<link>http://www.laruence.com/2011/11/05/2262.html</link>
		<comments>http://www.laruence.com/2011/11/05/2262.html#comments</comments>
		<pubDate>Sat, 05 Nov 2011 02:10:49 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[Ci]]></category>
		<category><![CDATA[Yaf]]></category>
		<category><![CDATA[Yii]]></category>
		<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[性能测试]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2262</guid>
		<description><![CDATA[ 从Yaf诞生以来, 我就没把它与其他框架的性能对比测试放出来,  原因呢, 也很简单, 我懒,  没对比过(只是和原生的PHP做了简单的对比).

   最近, 关注Yaf的人越来越多,  今天从访问来源发现了这个页面<a href="http://www.reddit.com/r/PHP/comments/m0akq/the_yet_another_framework_yaf_php_extension_for/">reddit.com</a>,  继而发现了<a href="http://www.ruilog.com/">Eryx</a>朋友,  做的一份<a href="https://github.com/eryx/labs/tree/master/php-framework-benchmark/result-20110701">性能对比测试</a>,  我就借花谢佛,  转载了过来.

   测试机器:
<coolcode lang="bash" linenum="off">
* Hardware

    CPU: Intel Core i5 750 (2.67GHz x4)
    RAM: 4GB

* Software
Debian 6.0.2 x86_64 (2.6.32-5-amd64)

apache 2.2.16
    mpm-prefork
    mod-php5

php 5.3.6
    php-apc 3.1.3p1
</coolcode>]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/11/05/2262.html"  title="Permanet Link to Yaf的性能对比测试" >http://www.laruence.com/2011/11/05/2262.html</a></li>
<li>文章转自: <a href="https://github.com/eryx/labs/blob/master/php-framework-benchmark/result-20110701" >https://github.com/eryx/labs/blob/master/php-framework-benchmark/result-20110701</a></li>
</ul></div>
<p>
   从Yaf诞生以来, 我就没把它与其他框架的性能对比测试放出来,  原因呢, 也很简单, 我懒,  没对比过(只是和原生的PHP做了简单的对比).</p>
<p>   最近, 关注Yaf的人越来越多,  今天从访问来源发现了这个页面<a href="http://www.reddit.com/r/PHP/comments/m0akq/the_yet_another_framework_yaf_php_extension_for/" >reddit.com</a>,  继而发现了<a href="http://www.ruilog.com/" >Eryx</a>朋友,  做的一份<a href="https://github.com/eryx/labs/tree/master/php-framework-benchmark/result-20110701" >性能对比测试</a>,  我就借花谢佛,  转载了过来.</p>
<p>  <b>后记(2011-12-02补充), Yaf 2.1做了一些性能优化的升级, 基于Yaf 2.1的性能测试报告可以参见: <a href="http://www.laruence.com/2011/12/02/2333.html" >Yaf 2.1性能测试</a></b></p>
<p>  <b>Postscript(added at 2011-12-02), Yaf 2.1 did a lot of work to improve performance and reduce memory usage, a new bechmark could be found at  <a href="http://www.laruence.com/2011/12/02/2333.html" >Yaf 2.1 Benchmark</a></b></p>
<p>   测试机器:</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
* Hardware

    CPU: Intel Core i5 750 (2.67GHz x4)
    RAM: 4GB

* Software
Debian 6.0.2 x86_64 (2.6.32-5-amd64)

apache 2.2.16
    mpm-prefork
    mod-php5

php 5.3.6
    php-apc 3.1.3p1
</pre>
<p>   <a href="http://laruence-wordpress.stor.sinaapp.com/uploads/ab1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/ab1.png"  alt=""  title="ab1"  width="680"  height="500"  class="aligncenter size-full wp-image-2270" /></a>  <a href="http://laruence-wordpress.stor.sinaapp.com/uploads/ab2.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/ab2.png"  alt=""  title="ab2"  width="680"  height="500"  class="aligncenter size-full wp-image-2271" /></a>  <a href="http://laruence-wordpress.stor.sinaapp.com/uploads/funs.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/funs.png"  alt=""  title="funs"  width="680"  height="500"  class="aligncenter size-full wp-image-2263" /></a>  <a href="http://laruence-wordpress.stor.sinaapp.com/uploads/memuse.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/memuse.png"  alt=""  title="memuse"  width="680"  height="500"  class="aligncenter size-full wp-image-2269" /></a>  <a href="http://laruence-wordpress.stor.sinaapp.com/uploads/time.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/time.png"  alt=""  title="time"  width="680"  height="500"  class="aligncenter size-full wp-image-2272" /></a></p>
<p>  看时间戳, 这个应该是在Yaf 2.1之前做的测试,  而Yaf2.1还做了一些性能优化, 数据应该还会更好看那么一点,  <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> </p>
<p>  后记(2011-11-25补充): </p>
<blockquote><p>
Eryx | 21 Nov 2011 16:24 edit<br/>
很惊喜，这竟然是我的测试 </p>
<p>上面有提到测试用例，可以参考测试汇总:</p>
<p>http://www.ruilog.com/blog/view/5271.html</p>
<p>刚刚下载了最新的 yaf 2.1.3，相比 2.0.x 版本, 在 “ab -c 100 -n 30000″ 下的并发已经从 5331 提高到 6800 左右！ （软硬件环境仍然相同）
</p></blockquote>
<p><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/05</a>, <a href="http://66beta.com"  rel="external nofollow"  class="url" >66</a> writes: 最近在学Yii，原来Yii跟CI还是差一点的，ZF太恐怖了，但是感觉ZF的组织架构是最简单的，就是太臃肿了</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/05</a>, 大草原 writes: 抽点时间来整yaf社区支持吧！</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/06</a>, <a href="http://www.magentochina.org"  rel="external nofollow"  class="url" >Magento中文</a> writes: zend framework太让人吃惊了...我一直用他.有空再看看你的yaf</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/06</a>, <a href="http://www.magentochina.org"  rel="external nofollow"  class="url" >Magento中文</a> writes: 其实这个报告还不完整..
 应该给出每个框架跑的代码..
而且只是在apache下面跑了..我想知道各种框架在zend server(虽然还是apache)和nginx下的速度..</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/06</a>, <a href="http://blog.cosnis.com"  rel="external nofollow"  class="url" >cosnis</a> writes: 不支持php3.8  淡定的飘过</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/07</a>, <a href="http://liruqi.tumblr.com"  rel="external nofollow"  class="url" >liruqi</a> writes: MicroMVC 的数据也挺不错啊~</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/09</a>, helloyou writes: 你得把手册翻译个英文版了...省得老外兄弟们用google翻译</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/09</a>, <a href="http://www.initphp.com"  rel="external nofollow"  class="url" >zhuli</a> writes: 每天来拜一拜，PHP写得顺畅点，哈哈哈</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/21</a>, <a href="http://www.ruilog.com"  rel="external nofollow"  class="url" >Eryx</a> writes: 很惊喜，这竟然是我的测试 :)

上面有提到测试用例，可以参考测试汇总:
http://www.ruilog.com/blog/view/5271.html

刚刚下载了最新的 yaf 2.1.3，相比 2.0.x 版本, 在 "ab -c 100 -n 30000" 下的并发已经从 5331 提高到 6800 左右！ （软硬件环境仍然相同）</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/24</a>, skyblue writes: MicroMVC的rps比yaf都高?
这是什么道理?</li><li><a href="http://www.laruence.com/2011/11/05/2262.html" >2011/11/25</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @Eryx 你能再重新弄个2.1的测试对比图么?  嘿嘿, 多谢多谢</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/12/02/2333.html"  title="Yaf 2.1性能测试(Yaf 2.1 Benchmark)" >Yaf 2.1性能测试(Yaf 2.1 Benchmark)</a></li><li><a href="http://www.laruence.com/2011/06/28/2088.html"  title="在Windows下编译Yaf" >在Windows下编译Yaf</a></li><li><a href="http://www.laruence.com/2011/06/26/2083.html"  title="Yaf已提交到PECL" >Yaf已提交到PECL</a></li><li><a href="http://www.laruence.com/2011/05/31/2025.html"  title="在中国PHP技术高峰论坛(2011)上演讲的PPT" >在中国PHP技术高峰论坛(2011)上演讲的PPT</a></li><li><a href="http://www.laruence.com/2011/05/12/2009.html"  title="Yaf-A PHP Framework Extension" >Yaf-A PHP Framework Extension</a></li><li><a href="http://www.laruence.com/2010/10/12/1763.html"  title="PHP的命名空间的实现" >PHP的命名空间的实现</a></li><li><a href="http://www.laruence.com/2010/09/04/1736.html"  title="Yaf-一个PHP扩展实现的PHP框架" >Yaf-一个PHP扩展实现的PHP框架</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/11/05/2262.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>JsonSerializable接口</title>
		<link>http://www.laruence.com/2011/10/10/2204.html</link>
		<comments>http://www.laruence.com/2011/10/10/2204.html#comments</comments>
		<pubDate>Mon, 10 Oct 2011 03:16:23 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[JsonSerializable]]></category>
		<category><![CDATA[jsonSerialize]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[php5.4]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2204</guid>
		<description><![CDATA[    昨天funlake提醒了我, 应该把一些PHP的新动向传播一下. 
<blockquote>
恭喜候鸟加入了pdt,有什么新进展别忘了给咱cn phper通报一下呀。
</blockquote>

  今天我来为大家介绍一下5.4中对Json做的一个改进.]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/10/10/2204.html"  title="Permanet Link to JsonSerializable接口" >http://www.laruence.com/2011/10/10/2204.html</a></li>
<li>转载文章</li>
</ul></div>
<p>
    昨天funlake提醒了我, 应该把一些PHP的新动向传播一下. </p>
<blockquote><p>
恭喜候鸟加入了pdt,有什么新进展别忘了给咱cn phper通报一下呀。
</p></blockquote>
<p>  那么, 今天为大家介绍一下5.4中对Json做的一个改进.</p>
<p>  Json是Ajax应用中最为通用的数据传输格式(协议),  主流的编程语言都带有对Json的支持,  在PHP中, 有json_encode/json_decode, 可以很方便的构造Json数据格式.</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
echo json_encode(array(1,2,3,4));
?&gt;

//[1,2,3,4]
</pre>
<p> 也可以Json化一个对象:</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
$o = new stdclass;
$o-&gt;a = 42;
echo json_encode($o);
?&gt;

//{&quot;a&quot;:42}
</pre>
<p>  但这样就有个问题,  现实生活中的对象是很复杂的, Json的这种默认只对属性做操作的做法有的时候是不能解决问题的, 比如我们希望通过私有成员来做一些计算得到最后的Json化数据, 又或者我们希望用一个字符串来代替一个object.</p>
<p>  在以前, 那你只能自己拼凑Json串了.  不过感谢Sara, 在5.4中,  Json新增了一个JsonSerializable接口,  任何实现了这个接口的类, 需要定义一个jsonSerialize()方法, 这个方法会在对这个类的对象做Json化的时候被调用, 这个时候你就可以在这个方法内 , 随意调整最终的Json化的结果:</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
class JsonTest implements JsonSerializable {
    private $a, $b;

    public function __construct($a, $b) {
        $this-&gt;a = $a;
        $this-&gt;b = $b;
    }

    public function jsonSerialize() {
        return $this-&gt;a + $this-&gt;b;
    }
}

echo json_encode(new JsonTest(23, 42));
?&gt;

//65
</pre>
<p> 下面是个稍微复杂点的例子:</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
$data = array(
    new stdClass();
    new JsonTest(1,2),
    new JsonTest(3,4),
    array(5,6)
);
echo json_encode($data);
?&gt;

//[{},3,7,[5,6]]
</pre>
<p>   最后提醒一下, PHP 5.4还处于开发阶段,  在最终release之前, 这些特性都可能被调整或者更改.  如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>   谢谢</p>
<p>   PS: 这个特性最初由Johannes在他自己的blog中介绍: <a href="http://schlueters.de/blog/archives/135-Jason,-let-me-help-you!.html" >http://schlueters.de/blog/archives/135-Jason,-let-me-help-you!.html</a><br/>
   <script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/10/10/2204.html" >2011/10/10</a>, wclssdn writes: 感觉也不是很有用. 既然encode的时候写了对象. 那干嘛不直接调用对象的一个方法呢?比如就叫_jsonSerialize...</li><li><a href="http://www.laruence.com/2011/10/10/2204.html" >2011/10/10</a>, wynn writes: 定义标准化interface的意义远超过单纯的实现某个功能。

比如说原本某处有段代码是：
$o = new myClass();
/* do something */
echo json_encode($o);
后来因为某种原因，myClass的某个属性被移除，改为计算得出，那么只要改一改myClass的定义，实现JsonSerializable接口，并实现jsonSerialize方法即可，其他地方都不需要变动。

如果用自定义某个方法的方式来实现同样的功能（比如就叫_jsonSerialize），那么在初期就要给所有需要被json化的对象定义此方法（具体内容很可能就是简单的 return $this;），平白增加了复杂度，降低了效率。

所有开发人员都遵循一样的标准，也会让程序的沟通维护更加简单。</li><li><a href="http://www.laruence.com/2011/10/10/2204.html" >2012/01/21</a>, <a href="http://fwso.cn/php/php5-4%e6%96%b0%e7%89%b9%e6%80%a7%e5%b0%8f%e7%bb%93/"  rel="external nofollow"  class="url" >PHP5.4新特性小结 | 实践.最佳 - 行.思.悟</a> writes: [...] 参考：http://www.laruence.com/2011/10/10/2204.html [...]</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/10/10/2239.html"  rel="bookmark"  title="Permanent Link: 让Json更懂中文(JSON_UNESCAPED_UNICODE)" >让Json更懂中文(JSON_UNESCAPED_UNICODE)</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/07/14/2115.html"  title="Zend引擎的优化" >Zend引擎的优化</a></li><li><a href="http://www.laruence.com/2011/12/06/2381.html"  title="更简单的重现PHP Core的调用栈" >更简单的重现PHP Core的调用栈</a></li><li><a href="http://www.laruence.com/2011/09/23/2171.html"  title="我对PHP5.4的一个改进" >我对PHP5.4的一个改进</a></li><li><a href="http://www.laruence.com/2010/02/02/1272.html"  title="注意PHP5.2.11之后的json_decode" >注意PHP5.2.11之后的json_decode</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/10/10/2204.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>和一朋友对话有感</title>
		<link>http://www.laruence.com/2011/09/30/2187.html</link>
		<comments>http://www.laruence.com/2011/09/30/2187.html#comments</comments>
		<pubDate>Fri, 30 Sep 2011 06:34:10 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2187</guid>
		<description><![CDATA[和一个朋友的对话,  他谈到了一些想法, 我觉得有必要和大家分享一下. ]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/09/30/2187.html"  title="Permanet Link to 和一朋友对话有感" >http://www.laruence.com/2011/09/30/2187.html</a></li>
<li>转载文章</li>
</ul></div>
<p>  朋友:  你知道你的 nginx+php  pathinfo的问题的那文章, 我看了多少遍吗？ </p>
<p>  我:  &#8230;..  看了多少遍&#8230;</p>
<p>  朋友:   从去年这个问题出现，到我写那个运维开发安全的PPT，我看了不少于50遍吧。</p>
<p>  我:　&#8230;..　　你看那么多遍干啥,,,.</p>
<p>  朋友：不是看一遍就能读懂的。</p>
<p>  我:　　是我写的不明白? -_#　　汗,,你看吧, 我就说我不能写东西..</p>
<p>  朋友： 不是。 前置知识需求太多。</p>
<p>  我:   哦, 呵呵. 那对你有好处啊, 嘿嘿</p>
<p>  朋友:  CGI规范我读了好几遍(PATH_INFO QUERY_STRING这几个章节)。  我最近看了《暗时间》，里面提到几点。我觉得有共鸣: <b>别人写的文章，初次看了，觉得“哦，原来是这么回事”。当有这种感慨的时候，一般就是根本没有真正读懂这文章。</b></p>
<p>  我:   en,搞技术的, 还是要多多追根究底下;)</p>
<p>  朋友:   <b>当后来直到自己真正动手去做这些相关问题的时候，回头再认真看这文章时，才有更深入的理解，发现更多当初压根没在意的术语，关键词。 再去搜这些术语、关键词的资料，熟悉这些之后，再回头看这文章，才有真正的初步了解。 直到对这文章有自己的看法，那才是真正的读懂了。</b></p>
<p>  我:  恩,   这是很好的品质</p>
<p>  朋友:  对再权威的人的文章，能产生质疑了，那才真正的读这文章了。 虽然我还不能对你的文章产生质疑目前。 哈哈。</p>
<p>  我: 对的. 没有永恒的真理,  你说的很有道理, 我忍不住要分享下</p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/09/30/2187.html" >2011/09/30</a>, <a href="http://walu.sinaapp.com"  rel="external nofollow"  class="url" >walu</a> writes: 这篇文章比技术文章还有价值。如果说鸟哥以前在授人以鱼，现在则开始授人以渔了。</li><li><a href="http://www.laruence.com/2011/09/30/2187.html" >2011/09/30</a>, ourac writes: 是不是CFC4N？</li><li><a href="http://www.laruence.com/2011/09/30/2187.html" >2011/10/05</a>, <a href="http://hi.baidu.com/u2solu"  rel="external nofollow"  class="url" >solu</a> writes: 对呀，读技术文章真的不容易。当发现一种陌生的技术或者一个陌生的术语就必须追查一下，然后就越来越远越来越远，至于最后去了多远，这个嘛就要看每个人的积累和水平了。反正我常常去到很遥远的地方，呵呵，很多知识没掌握!</li><li><a href="http://www.laruence.com/2011/09/30/2187.html" >2011/10/07</a>, <a href="http://www.fising.cn"  rel="external nofollow"  class="url" >fising</a> writes: 说的很有道理啊。不知道我不知道，知道我不知道，知道我知道，不知道我知道。</li><li><a href="http://www.laruence.com/2011/09/30/2187.html" >2011/10/08</a>, localtest writes: 对作者的谈话有同感，另外对评论“当发现一种陌生的技术或者一个陌生的术语就必须追查一下，然后就越来越远越来越远，至于最后去了多远，这个嘛就要看每个人的积累和水平了”也很有同感！</li><li><a href="http://www.laruence.com/2011/09/30/2187.html" >2011/10/20</a>, <a href="http://www.di15.com/"  rel="external nofollow"  class="url" >十五博客</a> writes: 读文章，直到自己心中有数，甚至是自己能写出来，那样才算真正读懂了。读别人技术文章是给自己用的，重在是否读懂而非读多少遍。</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/07/16/2123.html"  title="浏览器多tab打开同一URL串行化的问题" >浏览器多tab打开同一URL串行化的问题</a></li><li><a href="http://www.laruence.com/2012/01/24/2494.html"  title="大家新年好~" >大家新年好~</a></li><li><a href="http://www.laruence.com/2008/07/16/227.html"  title=" MySQL也真是让人郁闷(关于子查询中使用limit)" > MySQL也真是让人郁闷(关于子查询中使用limit)</a></li><li><a href="http://www.laruence.com/2010/03/05/1332.html"  title="浏览器缓存机制" >浏览器缓存机制</a></li><li><a href="http://www.laruence.com/2010/08/03/1697.html"  title="深入理解PHP原理之异常机制" >深入理解PHP原理之异常机制</a></li><li><a href="http://www.laruence.com/2008/08/11/147.html"  title="深入浅出PHP(Exploring PHP)" >深入浅出PHP(Exploring PHP)</a></li><li><a href="http://www.laruence.com/2008/04/16/19.html"  title="编写提供对象给PHP使用的Module" >编写提供对象给PHP使用的Module</a></li><li><a href="http://www.laruence.com/2008/04/21/101.html"  title="关于PHP你可能不知道的－PHP的事件驱动化设计" >关于PHP你可能不知道的－PHP的事件驱动化设计</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2008/11/11/606.html"  title="图解aclocal、autoconf、automake、autoheader、configure" >图解aclocal、autoconf、automake、autoheader、configure</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/09/30/2187.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>PHP RFC: 让PHP的foreach支持list</title>
		<link>http://www.laruence.com/2011/07/13/2110.html</link>
		<comments>http://www.laruence.com/2011/07/13/2110.html#comments</comments>
		<pubDate>Wed, 13 Jul 2011 05:30:10 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[foreach list]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP语法分析]]></category>
		<category><![CDATA[zend vm]]></category>
		<category><![CDATA[扩展PHP]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2110</guid>
		<description><![CDATA[上个月,  终于算加入了PHP developer team,  一直以来最大的障碍就是语言,  现在想起来, 当年真应该更加认真努力的去学习英语.
    
    得到的第一个任务是: 解决一个feature request,   请求在<a href="https://bugs.php.net/bug.php?id=10203">allow foreach($array as list($a,$b)</a>

    大意是说,  希望PHP能支持如下语法:
<coolcode lang="php" linenum="off">
<?php
foreach (array(array(24,2333), array(31,4666)) as $k => list($a, $b)) {
    printf("key:%s, a=>%s, b=>%s\n", $k, $a, $b);
}
/** output:
key:0, a=>24, b=>2333
key:1, a=>31, b=>4666
*/
</coolcode>

      实现这个功能,  入手点就是去改写PHP的语法分析逻辑,  具体的实现我会再后面附上对PHP5.4的patch.]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/07/13/2110.html"  title="Permanet Link to PHP RFC: 让PHP的foreach支持list" >http://www.laruence.com/2011/07/13/2110.html</a></li>
<li>转载文章</li>
</ul></div>
<p>    上个月,  终于算加入了PHP developer team,  一直以来最大的障碍就是语言,  现在想起来, 当年真应该更加认真努力的去学习英语.</p>
<p>    得到的第一个任务是: 解决一个feature request,   请求在<a href="https://bugs.php.net/bug.php?id=10203" >allow foreach($array as list($a,$b)</a></p>
<p>    大意是说,  希望PHP能支持如下语法:</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
foreach (array(array(24,2333), array(31,4666)) as $k =&gt; list($a, $b)) {
    printf(&quot;key:%s, a=&gt;%s, b=&gt;%s\n&quot;, $k, $a, $b);
}
/** output:
key:0, a=&gt;24, b=&gt;2333
key:1, a=&gt;31, b=&gt;4666
*/
</pre>
<p>      实现这个功能,  入手点就是去改写PHP的语法分析逻辑, 具体的实现我会再后面附上对PHP5.4的patch, 有兴趣的同学, 还可以参看我之前的一篇文章<a href="http://www.laruence.com/2010/07/16/1648.html" >定制自己的PHP语法-在PHP中实现unless</a>.</p>
<p>      不过在后来的PHP 5.4要包含的新特性的投票中,  目前的情况是9赞成, 19反对,  看起来, 5.4中是不会包含这个特性了.</p>
<p>      只能希望在下一次的大版本升级中加入了.</p>
<p>      我就先把RFC和Patch放出来, 让对PHP语法分析这部分有兴趣的同学参考.</p>
<p>      RFC: <a href="https://wiki.php.net/rfc/foreachlist" >https://wiki.php.net/rfc/foreachlist</a></p>
<p>      Patch for PHP5.4: <a href="http://www.laruence.com/php-dev/php-5.4.0svn-add-foreach-list-with-slient-support.patch" >http://www.laruence.com/php-dev/php-5.4.0svn-add-foreach-list-with-slient-support.patch</a></p>
<p>      另外, 要说一下, 从PHP5.4开始, 语法分析这块的变化很大, 基本的数据结构都有很大的变化, 对于想从事PHP语言引擎学习的同学来说,  一定要注意.<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/07/13/2110.html" >2011/07/13</a>, <a href="http://www.shaukei.com"  rel="external nofollow"  class="url" >大草原</a> writes: 5.4。。。</li><li><a href="http://www.laruence.com/2011/07/13/2110.html" >2011/07/15</a>, <a href="http://hi.baidu.com/u2solu"  rel="external nofollow"  class="url" >solu</a> writes: 现在5.3的应用都还没普及吧！</li><li><a href="http://www.laruence.com/2011/07/13/2110.html" >2011/09/22</a>, <a href="http://www.ruchee.com"  rel="external nofollow"  class="url" >Ruchee</a> writes: 博主，你好

请问本文那段源代码是用的什么字体？我很喜欢，望告知^-^</li><li><a href="http://www.laruence.com/2011/07/13/2110.html" >2011/09/23</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @Ruchee 诶, 你可以通过firebug看下具体到你的browser是什么字体 :)</li><li><a href="http://www.laruence.com/2011/07/13/2110.html" >2011/10/09</a>, funlake writes: 恭喜候鸟大仙加入了pdt,有什么新进展别忘了给咱cn phper通报一下呀。</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/07/14/2115.html"  title="Zend引擎的优化" >Zend引擎的优化</a></li><li><a href="http://www.laruence.com/2009/04/28/719.html"  title="用C/C++扩展你的PHP" >用C/C++扩展你的PHP</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/07/13/2110.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>在Windows下编译Yaf</title>
		<link>http://www.laruence.com/2011/06/28/2088.html</link>
		<comments>http://www.laruence.com/2011/06/28/2088.html#comments</comments>
		<pubDate>Tue, 28 Jun 2011 05:37:15 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[vs9]]></category>
		<category><![CDATA[windows]]></category>
		<category><![CDATA[Yaf]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2088</guid>
		<description><![CDATA[昨天<a href="http://weibo.com/2056428223" target="_blank">大草原</a>同学完成了在VS9下编译PHP-5.2.15和Yaf, 转发给我相关步骤描述.

其实本质上在win32和Linux下编译没什么区别, 都是只要正确设置CFLAGS和LDFLAGS就可以了, 但微软老喜欢搞成配置, 各种各样的配置项, 搞得人郁闷的不行.

特转载于此, 供大家参考.]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/06/28/2088.html"  title="Permanet Link to 在Windows下编译Yaf" >http://www.laruence.com/2011/06/28/2088.html</a></li>
<li>转载文章</li>
</ul></div>
<p>昨天<a href="http://weibo.com/2056428223"  target="_blank" >大草原</a>同学完成了在VS9下编译PHP-5.2.15和Yaf, 转发给我相关步骤描述.</p>
<p>其实本质上在win32和Linux下编译没什么区别, 都是只要正确设置CFLAGS和LDFLAGS就可以了, 但微软老喜欢搞成配置, 各种各样的配置项, 搞得人郁闷的不行.</p>
<p>特转载于此, 供大家参考.</p>
<p>由于php5.2与php5.3编译不同，本文讲述用vs9环境在php5.2下编译yaf框架。</p>
<p>准备好相关文件</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
1.Php源代码 http://cn.php.net/get/php-5.2.17.tar.gz/from/this/mirror
2.Php win32文件http://windows.php.net/downloads/releases/php-5.2.17-Win32-VC6-x86.zip
3.Yaf源代码 http://pecl.php.net/get/yaf-2.0.1.tgz
</pre>
<p>将下载好的文件解压，把yaf文件夹移动到php-source/ext/目录下</p>
<p>vs编译环境设置：</p>
<p>菜单：工具->选项->项目和解决方案->VC目录, 包含php源文件中的:</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
1.根目录
2.Main目录
3.Zend目录
4.TSRM目录
</pre>
<p>库文件：<br/>
包含php win32文件中的</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
1.dev目录
</pre>
<p>然后用vs打开yaf.dsp，选择全部转换</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
1.选择Release_TS编译方案
2.打开工程属性，删除预处理定义中的 宏：LIBZEND_EXPORTS[1]和ZEND_DEBUG=1删除
3.删除附加依赖项的php5ts_debug.lib
4.MFC的使用选择“在共享dll中使用mfc”
</pre>
<p>然后选择Release_TS进行编译<br/>
警告可以忽略不理<br/>
可能遇到的问题：</p>
<p>1.	C:\Program Files\Microsoft Visual Studio 9.0\VC\include\sys/stat.inl(44) : error C2466: 不能分配常量大小为0 的数组<br/>
解决方法：</p>
<p>在vc的 c:\program files\microsoft visual studio 8\vc\include\malloc.h 文件中找到：</p>
<pre name="code"  class="sh_c"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
#define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr) ]
</pre>
<p>将这一行改为：</p>
<pre name="code"  class="sh_c"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
#ifdef PHP_WIN32
#define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr)?(expr):1 ]
#else
#define _STATIC_ASSERT(expr) typedef char __static_assert_t[ (expr) ]
#endif
</pre>
<p>2.	如果遇到2019连接错误，那么通常是没有删除预处理定义中的宏LIBZEND_EXPORTS，如果还是有少量（1或者2个）2019连接错误，那么是系统找不到lib，多数情况是没有把yaf.vcproject里面节点Release_TS里的Debug_TS替换成Release_TS。</p>
<p>编译出来的dll位于php-source/Release_TS目录下。</p>
<p>完成后，把生成的dll复制到php.ini指定的ext目录下</p>
<p>新增一行：extension=php_yaf.dll</p>
<p>OK,编译完成.</p>
<p>[1] : 转载说明, 如果定义了LIBZEND_EXPORTS, 那么Yaf包含的PHP头文件中的ZEND_API就会被申明为 __declspec(dllexport), 导致无法在链接的时候无法解析符号.<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_c.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_c.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/06/28/2088.html" >2011/06/29</a>, smices writes: 造福人类的好事呀...
http://code.google.com/p/yafphp/downloads/list
只是这里的DLL就是TS的... 没NTS的..</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/12/02/2333.html"  title="Yaf 2.1性能测试(Yaf 2.1 Benchmark)" >Yaf 2.1性能测试(Yaf 2.1 Benchmark)</a></li><li><a href="http://www.laruence.com/2011/11/05/2262.html"  title="Yaf的性能对比测试" >Yaf的性能对比测试</a></li><li><a href="http://www.laruence.com/2011/06/26/2083.html"  title="Yaf已提交到PECL" >Yaf已提交到PECL</a></li><li><a href="http://www.laruence.com/2011/05/31/2025.html"  title="在中国PHP技术高峰论坛(2011)上演讲的PPT" >在中国PHP技术高峰论坛(2011)上演讲的PPT</a></li><li><a href="http://www.laruence.com/2011/05/12/2009.html"  title="Yaf-A PHP Framework Extension" >Yaf-A PHP Framework Extension</a></li><li><a href="http://www.laruence.com/2010/10/12/1763.html"  title="PHP的命名空间的实现" >PHP的命名空间的实现</a></li><li><a href="http://www.laruence.com/2010/09/04/1736.html"  title="Yaf-一个PHP扩展实现的PHP框架" >Yaf-一个PHP扩展实现的PHP框架</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/06/28/2088.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>使用fastcgi_finish_request提高页面响应速度</title>
		<link>http://www.laruence.com/2011/04/13/1991.html</link>
		<comments>http://www.laruence.com/2011/04/13/1991.html#comments</comments>
		<pubDate>Wed, 13 Apr 2011 12:26:43 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[fastcgi_finish_request]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1991</guid>
		<description><![CDATA[当PHP运行在FastCGI模式时，PHP FPM提供了一个名为fastcgi_finish_request的方法。按照文档上的说法，此方法可以提高请求的处理速度，如果有些处理可以在页面生成完后再进行，就可以使用这个方法。]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2011/04/13/1991.html"  title="Permanet Link to 使用fastcgi_finish_request提高页面响应速度" >http://www.laruence.com/2011/04/13/1991.html</a></li>
<li>文章转自: <a href="http://huoding.com/2011/04/12/63" >火丁笔记</a></li>
</ul></div>
<p>当PHP运行在FastCGI模式时,PHP FPM提供了一个名为fastcgi_finish_request的方法.按照文档上的说法,此方法可以提高请求的处理速度,如果有些处理可以在页面生成完后再进行,就可以使用这个方法.</p>
<p>听起来可能有些茫然,我们通过几个例子来说明一下：</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php

echo '例子：';
fastcgi_finish_request(); /* 响应完成, 关闭连接 */

/* 记录日志 */
file_put_contents('log.txt', '生存还是毁灭,这是个问题.');
?&gt;
</pre>
<p>通过浏览器访问此脚本, 结果发现并没有输出相应的字符串,但却生成了相应的文件.由此说明在调用fastcgi_finish_request后,客户端响应就已经结束,但与此同时服务端脚本却继续运行！</p>
<p>合理利用这个特性可以大大提升用户体验,趁热打铁再来一个例子：</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php

echo '例子：';

file_put_contents('log.txt', date('Y-m-d H:i:s') . &quot; 上传视频\n&quot;, FILE_APPEND);

fastcgi_finish_request();

sleep(1);
file_put_contents('log.txt', date('Y-m-d H:i:s') . &quot; 转换格式\n&quot;, FILE_APPEND);

sleep(1);
file_put_contents('log.txt', date('Y-m-d H:i:s') . &quot; 提取图片\n&quot;, FILE_APPEND);

?&gt;
</pre>
<p>代码里用sleep模拟一些耗时的操作,浏览时没有被堵塞,程序却都执行了,具体看日志.</p>
<p>末了给您提个醒,Yahoo在Best Practices for Speeding Up Your Web Site中提到了Flush the Buffer Early,也就是利用PHP中的flush方法把内容尽快发到客户端去,它和本文介绍的fastcgi_finish_request有些许的类似.</p>
<p><b>转载附言</b>:  我看了下这个方法,  在调用的时候, 会发送响应, 关闭连接. 但是不会结束PHP的运行.  相比调用flush, 或者我之前介绍的<a href="http://www.laruence.com/2011/02/13/1870.html" >加速你的Echo</a>来说,  这个方法能更加干脆一些.</p>
<p>另外, 从代码的可移植性讲的话,  可以在代码中附上如下代码:</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
if (!function_exists(&quot;fastcgi_finish_request&quot;)) {
      function fastcgi_finish_request()  {
      }
}
</pre>
<p>不会造成代码部署在非fpm环境下造成问题.<br/>
<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/13</a>, <a href="http://www.cnxct.com/"  rel="external nofollow"  class="url" >CFC4N</a> writes: 这确实是太好了，这个优点可以用于那些长时间执行的代码转为"后台执行"。类似制造了一个“任务中间层”去执行这些耗时的操作，比如用户找回密码的时候，可以直接返回找回成功，后台连接SMTP发送邮件，连接SMTP所耗时完全不需要用户等待返回，可先告诉用户已经完成，提高用户体验。</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/13</a>, <a href="http://www.rabbitlog.net"  rel="external nofollow"  class="url" >ryan</a> writes: 嗯，尽量早的flush，我也觉得很好，facebook的pagelet模式我已经开始用了，感觉不错~~~</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/14</a>, 怪物宝 writes: 很不错啊，受教</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/15</a>, <a href="http://www.seo4it.com/archives/php_fastcgi_fastcgi_finish_request_response_speed"  rel="external nofollow"  class="url" >PHP在FastCGI模式时用fastcgi_finish_request提高页面响应速度 | SEO 4 IT - Website Creater</a> writes: [...] 2011/04/13, ryan writes: 嗯，尽量早的flush，我也觉得很好，facebook的pagelet模式我已经开始用了，感觉不错~~~ [...]</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/21</a>, wintng writes: 这样一下,像登录的话,可能涉及很多复杂的东西可以我们可以放在"伪后台执行(fastcgi_finish_request)",
但是如果数量多的话, 就会出现超时的现象, 可以在头部加入set_time_limit(0);</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/22</a>, winting writes: 那如何知道程序执行完?</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/23</a>, fy writes: @CFC4N 你的这个例子应该使用异步处理来完成：）
这步应该做异步队列的插入，而不是连接smtp。。。</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/04/25</a>, <a href="http://www.jymoz.com"  rel="external nofollow"  class="url" >lotte</a> writes: 很不错的学习资料，能在自己网站上尝试。或许能少走不少歪路。</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/05/02</a>, <a href="http://blog.thinkinlamp.com/?p=723"  rel="external nofollow"  class="url" >Thinking In LAMP Blog &raquo; Blog Archive &raquo; PHP每月通讯（2011年5月）</a> writes: [...] http://www.laruence.com/2011/04/13/1991.html 　　使用fastcgi_finish_request提高页面响应速度 [...]</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/05/09</a>, htf writes: 不错啊，很有帮助，不过Mod_php不能使用。
fastcgi_finish_request之后的代码，虽然不占Web服务器时间，快速响应。后边的代码还是要占用fastcgi进程的时间。可以用异步事件模式。将请求插入到高速消息队列中，然后在守护进程中完成。
http://www.swoole.com/news/55.html</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/06/08</a>, <a href="http://blog.nroed.com"  rel="external nofollow"  class="url" >nroe</a> writes: 为啥不用 public function __destruct() ？</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/06/10</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @nroe 用__destruct干啥呢?</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/07/04</a>, <a href="http://xiesiqi.com/php5-4%e7%9a%84%e6%96%b0%e7%89%b9%e6%80%a7/"  rel="external nofollow"  class="url" >PHP5.4的新特性 &mdash; 见贤思齐</a> writes: [...] 使用fastcgi_finish_request提高页面响应速度 [...]</li><li><a href="http://www.laruence.com/2011/04/13/1991.html" >2011/09/07</a>, <a href="http://warpigallen.sinaapp.com/?p=57"  rel="external nofollow"  class="url" >warpig&#039;s blog &raquo; 【转】使用fastcgi_finish_request提高页面响应速度</a> writes: [...] 本文地址: http://www.laruence.com/2011/04/13/1991.html [...]</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2008/09/23/539.html"  title="使用PHP Embed SAPI实现Opcodes查看器" >使用PHP Embed SAPI实现Opcodes查看器</a></li><li><a href="http://www.laruence.com/2009/02/21/662.html"  title="PHP字符串比较" >PHP字符串比较</a></li><li><a href="http://www.laruence.com/2008/08/12/164.html"  title="深入理解PHP原理之函数(Introspecting PHP Function)" >深入理解PHP原理之函数(Introspecting PHP Function)</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2009/06/01/905.html"  title="开心网偷菜外挂" >开心网偷菜外挂</a></li><li><a href="http://www.laruence.com/2007/12/16/308.html"  title="PHP:Header" >PHP:Header</a></li><li><a href="http://www.laruence.com/2011/06/28/2088.html"  title="在Windows下编译Yaf" >在Windows下编译Yaf</a></li><li><a href="http://www.laruence.com/2009/04/07/670.html"  title="如何写出最快的循环" >如何写出最快的循环</a></li><li><a href="http://www.laruence.com/2011/02/13/1870.html"  title="加速PHP的ECHO" >加速PHP的ECHO</a></li><li><a href="http://www.laruence.com/2009/11/13/1138.html"  title="Nginx(PHP/fastcgi)的PATH_INFO问题 " >Nginx(PHP/fastcgi)的PATH_INFO问题 </a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/04/13/1991.html/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>PFA &#8211; PHP for Android</title>
		<link>http://www.laruence.com/2010/11/03/1794.html</link>
		<comments>http://www.laruence.com/2010/11/03/1794.html#comments</comments>
		<pubDate>Wed, 03 Nov 2010 09:06:27 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1794</guid>
		<description><![CDATA[使用PHP在Android上做应用的PPT
有兴趣的可以看看]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/11/03/1794.html"  title="Permanet Link to PFA &#8211; PHP for Android" >http://www.laruence.com/2010/11/03/1794.html</a></li>
<li>转载文章</li>
</ul></div>
<p>使用PHP在Android上做应用:</p>
<div id="__ss_5623777"  style="width: 425px;" ><strong><a title="Phpforandroid en"  href="http://www.slideshare.net/ivmos/phpforandroid-en" >Phpforandroid en</a></strong><object id="__sse5623777"  classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"  width="425"  height="355"  codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" ><param name="allowFullScreen"  value="true" /><param name="allowScriptAccess"  value="always" /><param name="src"  value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=phpforandroiden-101031114048-phpapp01&amp;stripped_title=phpforandroid-en&amp;userName=ivmos" /><param name="name"  value="__sse5623777" /><param name="allowfullscreen"  value="true" /><embed id="__sse5623777"  type="application/x-shockwave-flash"  width="425"  height="355"  src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=phpforandroiden-101031114048-phpapp01&amp;stripped_title=phpforandroid-en&amp;userName=ivmos"  name="__sse5623777"  allowscriptaccess="always"  allowfullscreen="true" ></embed></object></p>
<div style="padding: 5px 0 12px;" >View more <a href="http://www.slideshare.net/" >presentations</a> from <a href="http://www.slideshare.net/ivmos" >ivmos</a>.</div>
</div>
<p>项目主页: <a href="http://www.phpforandroid.net/"  target="_blank" >http://www.phpforandroid.net</a></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2010/11/04</a>, <a href="http://bbayou.blogbus.com/"  rel="external nofollow"  class="url" >额额额</a> writes: 问题的关键是，这些PHP程序貌似不能打包为可安装的apk文件呢。。</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2010/11/04</a>, <a href="http://www.cnxct.com"  rel="external nofollow"  class="url" >CFC4N</a> writes: 我晕，这也行？PHP都能做手机上的应用程序开发了？好像仅是用php解释器处理程序，返回json数据格式，然后交给手机系统的吗？</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2010/11/04</a>, <a href="http://www.9enjoy.com"  rel="external nofollow"  class="url" >enjoy</a> writes: 不知道这个能不能打包成apk文件？</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2010/11/08</a>, knight writes: 暂时只好拿来自娱自乐了...</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2010/12/07</a>, <a href="http://www.0990.us/blog"  rel="external nofollow"  class="url" >zerofire</a> writes: 估计把PHP当万能的了,另外Anti-spam word生成的验证码字体不同啊，某些很难辨认~</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2010/12/09</a>, xi writes: 这个例子表示，手机可以当移动服务器用。</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2011/01/20</a>, <a href="http://blog.icodeu.com"  rel="external nofollow"  class="url" >php</a> writes: 对效率很是担忧</li><li><a href="http://www.laruence.com/2010/11/03/1794.html" >2011/10/08</a>, wdxt206 writes: 这个项目有新进展吗？</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/03/04/1894.html"  title="深入理解PHP内存管理之谁动了我的内存" >深入理解PHP内存管理之谁动了我的内存</a></li><li><a href="http://www.laruence.com/2010/05/24/1526.html"  title="BTwitter(Twitter In Bash)" >BTwitter(Twitter In Bash)</a></li><li><a href="http://www.laruence.com/2009/11/18/1154.html"  title="automake,autoconf使用详解" >automake,autoconf使用详解</a></li><li><a href="http://www.laruence.com/2009/07/13/976.html"  title="PHP Session的一个警告" >PHP Session的一个警告</a></li><li><a href="http://www.laruence.com/2011/11/18/2305.html"  title="GBK编码PHP脚本导致语法错误(Zend Multibyte)" >GBK编码PHP脚本导致语法错误(Zend Multibyte)</a></li><li><a href="http://www.laruence.com/2008/01/05/12.html"  title="深入Mysql字符集设置" >深入Mysql字符集设置</a></li><li><a href="http://www.laruence.com/2008/04/01/116.html"  title="关于调用约定(cdecl、fastcall、stcall、thiscall) 的一点知识" >关于调用约定(cdecl、fastcall、stcall、thiscall) 的一点知识</a></li><li><a href="http://www.laruence.com/2008/04/03/15.html"  title="var_export 与 var_dump的不同" >var_export 与 var_dump的不同</a></li><li><a href="http://www.laruence.com/2009/02/21/662.html"  title="PHP字符串比较" >PHP字符串比较</a></li><li><a href="http://www.laruence.com/2009/08/22/1059.html"  title="字符编码详解(基础)" >字符编码详解(基础)</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/11/03/1794.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>[转载]技术文化和惨淡命运 —— 怀念中国雅虎</title>
		<link>http://www.laruence.com/2010/11/02/1789.html</link>
		<comments>http://www.laruence.com/2010/11/02/1789.html#comments</comments>
		<pubDate>Tue, 02 Nov 2010 05:18:01 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[中国雅虎]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1789</guid>
		<description><![CDATA[很早就想写这么一篇文章了。我离开中国雅虎已经一年有余，在中国雅虎工作的那段时光是我最珍贵的回忆之一，和以前的同事吃饭聊天的时候也经常会怀念一下中国雅虎，怀念得多了，就觉得不如写篇文章好好回顾一下。很多事情虽然已经过去，但有些话不说出来，到底意难平。

转载说明 :我的紫色情结.  --作者是我以前小组的同事]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/11/02/1789.html"  title="Permanet Link to [转载]技术文化和惨淡命运 —— 怀念中国雅虎" >http://www.laruence.com/2010/11/02/1789.html</a></li>
<li>文章转自: <a href="http://www.zhuoqun.net/html/y2010/1535.html"  target="_blank" >Dreamer&#8217;s Blog</a></li>
</ul></div>
<p>转载说明 <strong>:我的紫色情结.  &#8211;作者是我以前小组的同事</strong></p>
<p>很早就想写这么一篇文章了。我离开中国雅虎已经一年有余，在中国雅虎工作的那段时光是我最珍贵的回忆之一，和以前的同事吃饭聊天的时候也经常会怀念一下中国雅虎，怀念得多了，就觉得不如写篇文章好好回顾一下。很多事情虽然已经过去，但有些话不说出来，到底意难平。</p>
<p>从2008年7月份毕业之后加入了中国雅虎，到2009年9月份跟着中国雅虎工程技术部全体人员“被跳槽”到淘宝，我在中国雅虎只呆了一年多的时间。这个时间并不长，甚至可以说短得可怜，所以我或许不是写这篇文章的最佳人选。但是，中国雅虎给我的是人生第一份工作，凭着初生牛犊对社会的好奇心，我对公司的文化、技术、架构、流程包括产品设计等各个方面都有浓厚的兴趣和广泛的了解，从这个方面来说，由我来写这篇文章也是合适的。而且最重要是，我愿意把它们写出来。</p>
<p>在进入正文之前，先开诚布公地声明一下：众所周知，中国雅虎是阿里巴巴的一个子公司，所以文中我也不必遮遮掩掩地用“某电子商务公司”来代替。而且我对阿里巴巴这个公司有意见，不代表我对阿里巴巴的员工有意见，如果伤了某些人的感情，先说声抱歉，请您发扬一下风格，在这里也“拥抱变化”一下。</p>
<p>正文：</p>
<p>我在 2007 年底通过校园招聘拿到了中国雅虎的 offer ，但实际上在我2008年7月份入职的时候，中国雅虎的品牌虽然还在，公司却已经在7月9日和口碑网合并了，改名叫做“雅虎口碑”。尽管这样，到现在为止我还是厚着脸皮说自己原来是雅虎的，因为那里让我着迷和真心喜欢的东西全部都是紫色的，而不是橙色的。</p>
<p>雄厚的技术实力</p>
<p>中国雅虎最好的一个地方就是它和 Yahoo 全球共享同一个技术平台，那是一个有十几年历史的技术平台。Yahoo 的技术文化不如 Google 的工程师文化那么有名，但 Yahoo 在相当长的一段时间内都是互联网的旗帜，吸引了全球大量的技术牛人加入，Yahoo 的技术平台就是他们的知识、经验和心血日积月累的成果。尽管阿里巴巴收购了中国雅虎，但是在技术方面并没有对中国雅虎做出太大的改造（幸好没有改造），所以就工程师来说，每天更多接触到的还是 Yahoo 的东西，而不是阿里巴巴的东西，对我影响最大的也正是这些东西。</p>
<p>一、Linux 和开源文化</p>
<p>之前一个中国雅虎的同事，他是工作了几年之后才来中国雅虎，有一次他说：“雅虎是我见过的最尊重 Linux 的一家公司”。什么叫做尊重 Linux 呢 ？ 不是在服务器上装个 Linux 跑 Apache 就叫做尊重 Linux 。在雅虎很多同事日常都使用 Linux 操作系统办公，即使有一些人使用 Windows, 也都是使用 pietty 或者 Xshell 等工具远程连接到开发机器上使用 VIM 做开发。不只是日常工作，在雅虎全球的技术体系中，产品的上线和发布也都借鉴了 Linux 包管理的方式：所有的产品都会被打成包放在一个专门的服务器上，产品的部署和升级就变成了简单的装包操作，绝对不会出现最后上线的时候文件路径出错等低级问题。Yahoo 的技术平台是深深扎根于 Linux 和开源文化的。</p>
<p>大型互联网公司一般都会使用开源的产品，同时也向社区贡献代码。Google 和 Facebook 经常将自己研发的成熟产品开源，Yahoo 当然也不例外。而且 Yahoo 不仅仅给社区贡献代码，它在设计方面也拥抱了开源文化，将多年研究总结的设计模式库共享了出来。在 Yahoo 内部，很多代码都是存放在 CVS 里面的，并没有限制读的权限，任何员工都可以查看里面的代码，这对于那些小团队内部代码都不敢共享防员工如防贼的公司来说应该是非常不可思议的。另外， Yahoo 的工程师也经常出现在各种技术会议上，分享自己项目的架构、流程和经验。虽然这些更多都是 Yahoo 全球技术团队做的事情，但是对于他们那种开放共享的精神我们是非常认同并且向往的，你会觉得做一个工程师很自豪，而不会觉得自己是民工、做技术没前途。这种认同感和成就感乍看上去没什么，但实际上它决定了你对技术的追求和态度，也会影响你以后在职业上的选择。</p>
<p>二、浓厚的技术氛围</p>
<p>虽然2008年的时候中国雅虎已经被折腾得快不像样了（这点后面细说），不过那个时候还是有浓厚的技术氛围的。让我印象深刻的一件事情是 Google Chrome 浏览器刚发布的时候，大家都立刻下载下来使用，但由于公司内网的一些问题无法打开网页。当我正打算把 Chrome 卸载了的时候，忽然发现公司邮件列表里面已经有人发邮件给出了详细的解决方案。从这件小事可以看出公司大部分工程师都不是那种只知道完成工作的人，而是随时关注新技术和业界动态的人。当时中国雅虎还是有很多牛人没有离开，大家也喜欢在邮件列表里面谈论技术，经常能看到精彩的讨论和解答。最让我兴奋的是，无论我遇到什么技术问题都不用慌张，即使无法 Google 到答案也可以从同事那里获取到帮助，而且大家也愿意回答技术问题，这对于我这样一个基础很差技术又烂的菜鸟来说真是天大的福气。</p>
<p>中国雅虎还有做技术分享的文化，如果有哪位同事想要分享一下最近学习到的技术，就可以自己预订一个会议室然后向所有的工程师发送会议邀请，有时候还会有一系列非常系统的课程，我就参加过长达十几个课时的 UED 培训，完全改变了我对 Web Develop 的认识。很多公司应该都鼓励员工做技术分享，但在中国雅虎几乎每次技术分享都会把会议室坐的满满当当，可见大部分工程师都还是想要不断提高自己的技术能力。直到离开雅虎之后我才明白这种普遍的学习热情有多么难得。我想，业界之所以到处流传着“程序员做到30岁最好转管理”之类的忠告，应该就是因为大部分公司都缺乏这种良好的技术氛围吧。</p>
<p>三、庞大的知识库</p>
<p>入职的前几天，我每天的工作就是看文档，不是类似“PHP技术手册”那种文档，而是一些 Yahoo 内部的工具手册。Yahoo 内部的文档非常齐全和详细，光是 Yinst 这款工具的使用手册就长达几十页。Yahoo 内部是用 Twiki 做知识管理的，这个知识库经过十多年的积累已经非常庞大，从入门到提高，从 PHP 到 C ，从前端到后端……应有尽有，而且几乎 Yahoo 全球所有子公司的技术资料都是开放浏览的，没有任何乱七八糟的权限设置和保密限制。有这么一个宝藏在，再加上好的学习氛围，如果你想要提高自己的能力的话，总是可以提高。当初我想从 PHP 工程师转做 Web Developer 的时候，就先把 Twiki 上 UED 部门的所有资料看了一遍，受益匪浅。</p>
<p>国内大部分互联网公司都是没有太多技术积累的，因为大部分产品的开发都只追求开发速度，并不会特别追求技术上的极致，就更不要提文档这种东西了。也正因为如此，从中国雅虎出来看到其它公司的知识库的时候总有不过瘾的感觉，可能也只有像 Google, 微软和 Facebook 这样的公司才会有像 Yahoo 那样的知识库吧。在和之前一些同事吃饭聊天的时候，大家也总是会怀念那个无所不包完全开放的 Twiki ，好像少了一个忠实的朋友一样。我们由衷地尊敬那些在完成工作之余还愿意总结项目经验并花时间写 Twiki 的工程师们。</p>
<p>四、完善的流程</p>
<p>第一次参与项目开发的时候，我的 Leader 领了一个 MM 过来说：“这位是项目的 QA 负责人”，我当时愣了一下：“呃…… QA 是做什么的？” 尽管在大学里我也在实验室做过一些项目，但那些项目基本上都是我自己负责所有的事情，完全没有分工和流程的概念，所以也不知道 QA 是负责产品测试工作的。进入中国雅虎之后，我才第一次接触到商业产品的开发流程，不过由于那个时候中国雅虎已经半死不活，我也没有受到有关流程的入职培训，以至于在做了好几个项目之后才真正熟悉了完整的流程。</p>
<p>中国雅虎的开发流程沿袭了 Yahoo 的开发流程，乍看之下很平常，对于已经熟悉的工程师来说还显得枯燥，但后来我特别留心了这套流程之后，非常惊奇于它的严谨和高效，所以这里要详细说明一下。Yahoo 的内部生产线分为三个相互独立的环境：开发环境、测试环境和生产环境（即线上环境）。这三个环境虽然独立，但它们的配置都会尽量保持一致，这样就可以保证开发完成的产品不会因为环境不同而出现问题。在开发的时候，我们会在开发环境中搭建虚拟环境，开发完毕之后开发工程师会自己在虚拟环境里面测试，保证没有大的问题，然后就会把所有相关文件打包上传到雅虎全球统一放置产品包的地方。上传完毕之后，就会发邮件通知 QA 部门相关人员，邮件内容里面要写明产品在测试环境的部署步骤：需要安装哪些包、是否需要修改数据库等等。然后 QA 就会开始测试，如果发现 BUG 就会写到 Bugzilla 中，指派给相应的开发工程师，开发工程师就会在开发环境中定位BUG并修正，修正一些BUG之后就会再次打包升级产品的版本，然后QA 会将新的软件包部署到测试环境验证之前的 BUG 并报告新的 BUG 。整个测试过程中可能要发布好多个版本，直到所有 BUG 被修正为止。修正完毕所有的 BUG 之后，开发工程师就会填写上线申请，Ops 看到申请之后就会安排一个时间把产品部署到生产环境。一般来说，生产环境不止会有一台机器，所以 Ops 会先从生产环境摘下一台机器部署，部署完毕之后会告知 QA 和开发工程师，然后 QA 和开发工程师就会修改 Hosts 文件，配置域名指向那台机器进行线上的测试，如果测试没有问题，那么就会把软件包部署到生产环境中所有的机器上，完成上线；否则就进行回滚，取消这次上线，也不会影响到线上的用户。</p>
<p>整个流程大概就是这样，但是要特别注意的是以下几点：1. 开发工程师只能接触开发环境。他所能做的就是在开发环境中开发、改 BUG 和打包上传。如果他去测试环境中修改 BUG，就很有可能忘记修改开发环境中的相应代码，这可能会导致产品测试通过但是上线之后却发现大的问题。 2. 产品“封版”之后就不可以做任何改动，如果有改动，即使只改动了一点所有功能也要重新测试一遍。所有的 BUG 都修改完毕之后的那个版本就会进行“封版”，那就标志着这个产品随时可以准备上线了。如果真的发现了新的 BUG 要修改的话，那么修改之后就需要重新打包重新走一遍完整的测试流程，只有这样才能够保证就算修改代码过程中引入了新的 BUG 也不会被遗漏。 3. 上线手册要详细。开发工程师要详细写明每一个步骤，不只是说明性的文字，还要把具体的安装和修改命令完整地放上去，如果写得好的话，那么 Ops 的同事只需要把上线手册里面的命令逐行复制到服务器上运行就可以完成上线。</p>
<p>这样的流程有什么好处呢？ 首先，它最大地降低了上线风险。因为开发工程师不能接触到测试环境，只能打包让QA测试，所以完整经过测试的产品上线之后基本不会有什么问题，况且上线的时候我们也要先部署到一台机器上进行测试之后才会决定是否上线，即使上线不成功也可以在不影响用户的情况下回滚。中国雅虎的上线极少会出现问题，很多时候我们上线到半夜只是因为那个时间段用户访问量最小，而不是说焦头烂额地忙活几个小时一直到半夜才上线成功。其次，它使得各个部门职责分明。开发工程师和 QA 通过 Bugzilla 沟通，和 Ops 通过上线手册沟通，因为沟通渠道唯一而且清晰，所以就可以完全责任到人，出了问题也很容易定位到具体环节。比如说，如果产品测试通过之后在上线的时候出现了问题，那么基本就可以确定是 Ops 操作失误或者上线手册没有写好。职责分明之后很多事情也变得有条理，大家就可以各司其职、专注本职工作并且合作愉快，开会的时候也可以明确知道需要哪些人参加。</p>
<p>完善、清晰的流程从根本上解决了一些问题，创建了一个非常好的环境，这样我们就可以把心思都放在如何开发和测试上面，而不用担心诸如“如何上线才能不出错”等琐碎的事情。所以尽管中国雅虎的高层那么不靠谱，我工作得还是很开心，因为这个流程保证了管理层再怎么乱开发也不会乱。记得那时候很喜欢改 BUG ，有时候改得兴起会把之前版本遗留的 miss BUG 一并改掉，加班也是颇有兴致，不是很能明白为什么网上大部分程序员讨厌加班讨厌得要死。现在我明白了。</p>
<p>五、自动化工具</p>
<p>工欲善其事，必先利其器。如果没有那么多好用的自动化工具，那么 Yahoo 的流程就不可能如此完善。Yahoo 内部有很多非常好用的工具，而且这些工具都有非常齐全的文档，也可以在 Twiki 上找到不少相关资料。这些工具之所以在 Yahoo 会起到那么大的作用，是因为 Yahoo 全球所有的技术团队都在使用它们，Yahoo 所有的服务器上也是默认安装了这些工具。这些工具就形成了一套全球 Yahoo 工程师通用的话语体系，可以想象它们帮助 Yahoo 节省了多少沟通成本。</p>
<p>由于考虑到服务器的安全问题，Yahoo 的这些工具的使用方法是对外保密的，这里我只简单说一下 Yinst 这款工具的强大。假如要把软件包 example_1_1_0.tar.gz 部署到 a1.yahoo.com ~ a10.yahoo.com ，那么只需要下面这样一行命令：</p>
<p>yinst install example_1_1_0.tar.gz -h a[1-10].yahoo.com</p>
<p>就可以完成整个上线过程。由于好奇的缘故，在上线的时候我比较喜欢跑到 Ops 那边看他们是如何操作的，然后发现其实他们在上线过程中执行的命令很少。因为工具好用，所以产品极少因为 Ops 这个环节出现问题，上线就变成一件比较轻松的事情。</p>
<p>中国雅虎的产品和业务确实不好，搜索不如百度，新闻不如三大门户，“雅虎助手”是人人皆知的流氓软件，邮箱也出过丑闻，而且被 Gmail 和 QQ 邮箱远远抛在后面。中国雅虎最广为人知的也都是这些不光彩的事情，但这里我想让很多人知道，对于一个对技术还有追求的工程师来说，当时的中国雅虎真的是一个很好的工作环境。至少对于我自己来讲，我从 Yahoo 学到了太多太多的好东西，而且这些东西还只是 Yahoo 精华中的一小部分，如果不是阿里巴巴集团战略调整，我一定会在中国雅虎多呆两年。</p>
<p>中国雅虎之死</p>
<p>有个同事曾经说过：中国雅虎就是中国互联网的黄埔军校。虽然别的老牌互联网公司也为行业培养了不少人才，但是没有一个公司像中国雅虎这么悲情。很多中国雅虎的员工离职不是自己想走，而是不得不走，看着原来好好的一个公司变得完全没有前途，只好选择离开。</p>
<p>关注互联网的人应该都知道，在 2005 年的时候，阿里巴巴收购了中国雅虎的全部资产，并享有雅虎品牌及技术在中国的独家使用权。中国雅虎尽管之前也一直水土不服，但被阿里巴巴收购之后悲惨命运才刚刚开始。</p>
<p>关于中国雅虎的折腾史，大家可以去看一下这篇文章，里面说的已经很详细。从网站的变化就可以看出中国雅虎的摇摆不定，在阿里巴巴入主的这 4 年来，中国雅虎就换了 5 任总裁，每位新官上任后都会颁布新的战略，网站也会随之大变脸。“治大国若烹小鲜”，这么简单的道理我相信阿里巴巴的高层不可能不明白，就算大象可以跳舞，中国雅虎的舞姿是不是也太难看了点？由此可见，中国雅虎在阿里巴巴集团内部就是一个鸡肋，一个可有可无的品牌。</p>
<p>有一件事情完全可以说明马云对中国雅虎的态度。约在 2007 年前后，马云对雅虎中国资产进行了大幅度调整。在此期间，雅虎相册宣布关闭，从发出通知到服务关闭，前后不到 20 天。这种缺乏对用户起码的尊重的行为，导致相当一部分中国用户失去了存储其中的照片。而且它引发的用户对雅虎品牌的失望和不信任，对雅虎来说更是难以挽回的损失。大家都知道，“客户第一”一直都是阿里巴巴宣扬的核心价值观，难道雅虎相册的用户就不是客户？到底是马云铁了心要把雅虎品牌搞砸呢还是所谓的价值观只是口号？或者是两者皆有？</p>
<p>这几年中国雅虎的历史就是逐渐被瓜分的历史：搜索团队被调走，于是有了后来的淘宝网搜索引擎；IM 团队被独立出去，于是有了后来的阿里旺旺；挖走了广告搜索团队，于是有了后来的阿里妈妈；口碑网发展得不好，于是中国雅虎和口碑网合并，利用中国雅虎的品牌和技术支持口碑网；最后，中国雅虎的整个工程技术部都注入淘宝，原来的主要业务“雅虎关系”直接关闭并且推荐用户使用淘宝网的“淘江湖”。时至今日，中国雅虎已经气息奄奄，再无回天之力了。</p>
<p>我经常觉得，恩，马总在下一盘很大的棋，我们这些普通员工是不明白的。不然为什么“搞死中国雅虎”这个庞大的项目规划和施行得这么好？还是阿里巴巴一直在用实际行动考验中国雅虎员工的价值观呢？而且颇具讽刺意味的是，尽管马云费尽心思拿到了中国雅虎的搜索资源，最近却又和微软的 Bing 合作推出了 Etao 搜索，当初的那些搜索资源都用来做什么了呢？</p>
<p>还有一点不得不提的是中国雅虎和阿里巴巴之间的文化冲突。阿里巴巴一直都不能算一个真正的互联网公司，它只是以互联网作为工具，大部分业务的进行还是靠线下的销售。阿里巴巴最重视的是销售部门，整体的文化是销售文化，它所取得的成功也都只是商业上的成功，这也就从根本上决定了它不可能像 Google, Yahoo 和 Facebook 等这些真正的互联网公司具有理想主义色彩，也不可能成为优秀工程师向往的地方。马云自己也经常放言说要“超越沃尔玛”，从来没有说过要超越 Google 之类的话，因为根本不在同一个领域，阿里巴巴更像一个传统的商业公司。我并不是说做电子商务的公司就不算互联网公司，同样是做电子商务，Amazon 就是互联网行业的领头羊，它非常重视技术，还是最早提供云计算服务的公司，它就是一家真正的“IT公司”。</p>
<p>而中国雅虎的技术资产全部来自美国 Yahoo ，工程技术部也继承了 Yahoo 的“技术文化”。“技术文化”偏重简单实用、冷静思考和解决问题；而“销售文化”则重视加油鼓劲，更喜欢喊口号，越热闹越好。我承认这两种文化都有它们的合理之处，但是强迫工程师接受那种“销售文化”就会有很多矛盾出现。阿里巴巴内部有时候玩得还比较过火，跳钢管舞倒也算了，但很多时候做游戏会直接让一个同事站到前面，然后轮流问他诸如“第一次用了多长时间”之类的问题。并不是所有人都喜欢这么玩儿的，“贱文化”和“骚文化” 的最大一个弊端就是很容易引起一些人的反感让他们觉得被侮辱，而公司不是经常倡导要对人才各尽其用么？为什么要用这样的文化把一些“思想保守”的人驱逐出去呢？我就听说过一些非常优秀的工程师因为这些东西而坚决不去参加公司的培训和集体活动，中国雅虎的很多人应该也是因为无法适应这种“销售文化”而出走的。</p>
<p>另外，当年和我一起通过校园招聘来到雅虎本来有不少人，在 2008 年 3 月份的时候我们还曾一起在北京参加了一个叫做“集结号”的新人培训。不过在我入职之后发现，有几个人直接被调动到了阿里巴巴在杭州的其它子公司，还有几个做搜索的同学虽然人在北京，签的却不是雅虎，而是什么“阿里巴巴集团搜索事业部”——当时雅虎的搜索部门已经被独立出去了。之后我也和那些最终没有来雅虎的同事聊过，他们都表示很郁闷，表示自己并不是很情愿去其它公司。这件事情让我感到很气愤，明明大家都是冲着中国雅虎来应聘的，为什么在发放 offer 之后又进行调动呢？当然，阿里巴巴肯定是做了一些说服工作让那些同事“自愿”服从调动的，但是那个刚好出现了金融危机工作比较难找，其它公司的招聘也早已结束，而且大家都是初出茅庐的学生，能不服从么？ 那几个同事也实在是太光荣了，刚入职就完美表现了自己“拥抱变化”的价值观，KPI 应该给五分。</p>
<p>不只是新入职的员工，因为中国雅虎的业务变化频繁，平时也经常会出现内部调动，而中国雅虎在北京，调动的话就很有可能需要去杭州，这对于很多已经在北京安家的同事来说并不是一件小事。但不服从调动，就是价值观有问题。五十六种语言，汇成一句话：拥抱变化拥抱变化拥抱——变化。</p>
<p>在写这篇文章的时候，我不断提醒自己：我的目的是要让大家了解一下中国雅虎，千万不要写成针对阿里巴巴的檄文。但真实情况确实是那个样子，很多事情也是人人皆知，无法绕过去不说。相信很多人都还记得中国雅虎首页的那次糟糕的改版，把原来清爽干净的页面改成了屎黄色，据说这是当时的 CEO 金同学坐在设计师旁边亲自指导的结果。如果一个乡镇企业的老板非要外包公司的设计师把网页做成他想要的也罢了，但作为一个缺乏审美能力的 CEO 居然连“把设计的工作交给设计师”的觉悟都没有，实在让人觉得不可思议。就算是一心想要“去雅虎化”，也没有必要这么羞辱设计师们吧？</p>
<p>不知道为什么，有些东西不用每天灌输也深得大家认同，怎么折腾都无法斩草除根。我在雅虎的时候从来没有任何一个人和我们说“你们要热爱雅虎，要以雅虎为荣”之类的话，但是每次公司给员工发放印有雅虎 LOGO 的杯子或者背包的时候，大家总是一哄而上，疯抢干净。在中国雅虎和口碑网合并之后，因为担心以后再也领不到雅虎 LOGO 的笔记本等文具，不少同学都开始申请办公用品留作纪念。由这些事情就可以看出工程师们认同的到底是哪一种文化，大家自然会用脚投票。这些事情甚至让中国雅虎的一些非工程师同事也觉得难以理解。这种生命力强劲的外来文化可能也是阿里巴巴一直不满中国雅虎的原因。</p>
<p>真正的开放应该是同事之间开诚布公、乐于分享和坦然接受批评，而不是不分场合地讲荤段子，不是让别人站到前面然后问别人“第一次用的是什么姿势”；真正的“员工第二”是站在员工立场上考虑问题、虚心听取员工提出的问题，而不是在员工有意见的时候首先进行价值观教育，不是强迫员工拥抱不可理喻的变化；真正的对“用户体验”的重视是尊重用户、切身考虑用户感受，不是在年会上把某个子公司的总裁骂哭，不是为了巨额广告费用而在首页做弹窗，不是让员工为了 KPI 每隔几个月就想着改版；真正的“幸福感”是来自于发自内心的对公司的认同、对公司产品的成就感，而不是来自于整齐划一的口号和对某个人的崇拜，也不是来自于被灌输的“换个角度看世界”。脱离了原本的初衷，就算宣传得再好口号喊得再响亮，也不过是看上去很美的空洞的形式主义，这样的公司有什么底气去做“百年公司”呢？</p>
<p>技术的悲哀</p>
<p>有着世界级的研发实力却不得不悲惨收场，我想再没有人比中国雅虎的工程师更能强烈地意识到技术所能决定的事情实在是太少太少。在中国，互联网只是一个营销工具，“技术改变世界”也不过是一个笑话。那些商人们从来不相信“一个优秀的程序员抵得上一百个平庸的程序员”，却虚伪地把“我不懂技术但是尊重技术”挂在嘴边；他们整日想的不是创造价值，而是如何赚更多钱；他们更相信“廉价劳动力”所带来的成本优势，也总能把“技术密集型”的公司做成“劳动密集型”，以至于国内的互联网公司不是山寨就是血汗工厂，雇佣着大批大批会写代码的高级民工。这样的环境和氛围，暂且不说 Google 和 Apple 这样伟大的公司，什么时候我们才能有产生像 37Signals 和 The Omni Group 那样的小公司的土壤呢？</p>
<p>文章的最后，还是那句老话：他日江湖相逢，再当杯酒言欢。</p>
<p>各位雅虎人，多保重了。</p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://gfneg.org"  rel="external nofollow"  class="url" >small2</a> writes: 看完文章，留念一下。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://gfeng.org"  rel="external nofollow"  class="url" >small2</a> writes: 一激动拼错链接地址了gfeng.org  ：)</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://www.zhuoqun.net"  rel="external nofollow"  class="url" >Dreamer</a> writes: 哈哈，你别来无恙？</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @Dreamer 我还好,呵呵, 你关于描述金**的那段, 我现在想起来还是依旧来气...</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://www.zhuoqun.net"  rel="external nofollow"  class="url" >Dreamer</a> writes: 恩，当时雅虎还有那么好的技术实力，想起来就十分来气。

Bleeding purple!</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://t.sina.com.cn/meiyoucumian"  rel="external nofollow"  class="url" >meiyoucumian</a> writes: 你写得还真长</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, fortruth writes: 恩， 的确很悲情。。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://www.oicic.cn"  rel="external nofollow"  class="url" >mrzhaoguohui</a> writes: 我当初也会唱不理解yahoo 的推出- - 马云只是商人。。。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://www.0915seo.net/"  rel="external nofollow"  class="url" >商洛SEO</a> writes: 屁股决定脑袋……

做技术的衣食无忧，并有一定的理想，当然有“技术”追求。

中国企业家大多是草根穷人出身，当然以赚钱为基本目的。

如果作者是农村出来的穷人娃，又会写出怎样的文章？</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/02</a>, <a href="http://liansi.org/?p=45"  rel="external nofollow"  class="url" >[转载]技术文化和惨淡命运 —— 怀念中国雅虎&nbsp;/&nbsp; liansi.org</a> writes: [...] 2010/11/02, small2 writes: 看完文章，留念一下。 [...]</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/03</a>, <a href="http://www.eallion.com"  rel="external nofollow"  class="url" >eallion</a> writes: 有值得学习的地方。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/03</a>, <a href="http://hema.v5n.org/archives/2767"  rel="external nofollow"  class="url" >[转载]技术文化和惨淡命运 —— 怀念中国雅虎&nbsp;|&nbsp;HEMAmedia</a> writes: [...] 本文地址: http://www.laruence.com/2010/11/02/1789.html [...]</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/03</a>, <a href="http://nidayede.cn"  rel="external nofollow"  class="url" >璎珞</a> writes: 雅虎真的真的真的是被玩死的，跟文化木有啥大关系。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/05</a>, <a href="http://www.fallensnow.net/index.php/archives/1641"  rel="external nofollow"  class="url" >[转载]技术文化和惨淡命运 &mdash;&mdash; 怀念中国雅虎 | 落雪实验室</a> writes: [...] 本文地址: http://www.laruence.com/2010/11/02/1789.html [...]</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/05</a>, <a href="http://www.mkrss.com/?p=212"  rel="external nofollow"  class="url" >[转载]技术文化和惨淡命运 —— 怀念中国雅虎 &laquo; Yet another wordpress blog</a> writes: [...] 本文地址: http://www.laruence.com/2010/11/02/1789.html [...]</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/05</a>, <a href="http://www.windphp.com"  rel="external nofollow"  class="url" >wnian</a> writes: 首先，很不辛的是，我的验证码是“move”
然后是，文章我看完了，没跳
深有感触</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/11</a>, davis writes: 我发现我的验证码为什么是DAN而不是DNA，这令我很纠结。刚转行PHP的菜鸟程序爱好者希望能和作者交个朋友，感激。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/11</a>, ggg writes: 我是一般观众，我无比愤恨马云这种商业混子糟蹋互联网的事业的举动。我简直无比鄙视这个马云庸人。他竟然成为某些人的榜样，真没天理了。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/14</a>, <a href="http://shiyangxt.cnblogs.com"  rel="external nofollow"  class="url" >shiyang</a> writes: 非常棒的文章，让我了解了雅虎的精神。末尾“技术的悲哀”和我有种共鸣，氛围确实不行。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/14</a>, boylxz writes: 物竞天择适者生存~</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/11/30</a>, <a href="http://plafer.tk"  rel="external nofollow"  class="url" >逸川</a> writes: 从第一次使用雅虎中国起，就没有觉得它好过
但是如今刚刚踏入 IT 圈，却发现雅虎真的很牛
我一直在寻找雅虎中国变得那么烂的原因
看了本文，了解了
也了解了技术的悲哀</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/12/08</a>, <a href="http://llphp.com"  rel="external nofollow"  class="url" >wclssdn</a> writes: 我是冲这验证码回复的- - :micro ...</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/12/09</a>, xi writes: 了解了
尊重技术的公司，一定会从技术中得到回报。
只是，互联网已经不在靠技术了，

但计算机技术还可以延续。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2010/12/29</a>, <a href="http://231"  rel="external nofollow"  class="url" >3123</a> writes: 321</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/01/26</a>, <a href="http://www.joymvp.com"  rel="external nofollow"  class="url" >jankuo</a> writes: 看了，某根弦触动了！
最后也只能支持一句话了：他日江湖相逢，再当杯酒言欢</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/01/27</a>, <a href="http://www.132cc.com/725.html"  rel="external nofollow"  class="url" >132CC.com &raquo; Blog Archive &raquo; [转载]技术文化和惨淡命运 —— 怀念中国雅虎</a> writes: [...] 本文地址: http://www.laruence.com/2010/11/02/1789.html [...]</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/03/07</a>, Lonely writes: 让我转变了对YAHOO的看法</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/04/27</a>, Kyli writes: 理想的好公司，
谷歌中国里的laruence估计过两年也会出来一篇类似的文章</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/05/17</a>, ubuntu writes: 我就一直纳闷，雅虎怎么变的这么糟糕，现在算是明白了！</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/05/28</a>, <a href="http://www.apesk.com"  rel="external nofollow"  class="url" >luxucc</a> writes: 商业模式才是王道。。搞技术的必须为商业模式服务。在中国我看是这样。</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/07/06</a>, tufei writes: 荡气回肠...
我一般不爱留言，但是这次真的是心有所感!虽然没去过雅虎，但是听了楼主的介绍，感觉那就像是程序员的天堂，共产主义估计也不过如此了，爱一个公司不是天天喊口号，而是有一天当你要离开他的时候感觉他就像自己的亲人。一个公司如果用情而不是钱留住员工那实在是难能可贵，真要在这样的公司工作那才是享受生活</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/08/21</a>, <a href="http://geekdream.com"  rel="external nofollow"  class="url" >xxfs91</a> writes: 我是一名大学生,
自学php半年了.

看到博主的文章
感慨良多
企业文化很重要

商业模式把技术当劳力
感到有点悲哀

希望我大学毕业也可以找到一份类似像楼主第一次去工作的环境一样,这样才可以成长</li><li><a href="http://www.laruence.com/2010/11/02/1789.html" >2011/10/04</a>, Helloyou writes: 嗯,马云说对购买yahoo(世界)很感兴趣...祝他失败</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/12/17/1833.html"  title="PHP是无辜的" >PHP是无辜的</a></li><li><a href="http://www.laruence.com/2009/01/07/656.html"  title="Mess it up!" >Mess it up!</a></li><li><a href="http://www.laruence.com/2009/05/26/871.html"  title="PHP+Gtk实例(求24点)" >PHP+Gtk实例(求24点)</a></li><li><a href="http://www.laruence.com/2008/08/15/274.html"  title="PHP 源代码分析 V0.0.2" >PHP 源代码分析 V0.0.2</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2011/07/13/2110.html"  title="PHP RFC: 让PHP的foreach支持list" >PHP RFC: 让PHP的foreach支持list</a></li><li><a href="http://www.laruence.com/2009/06/14/945.html"  title="深入理解PHP原理之扩展载入过程" >深入理解PHP原理之扩展载入过程</a></li><li><a href="http://www.laruence.com/2008/08/16/301.html"  title="扩展PHP[Extending PHP](一)" >扩展PHP[Extending PHP](一)</a></li><li><a href="http://www.laruence.com/2010/03/26/1365.html"  title="使用SoapHeader实现Soap请求验证" >使用SoapHeader实现Soap请求验证</a></li><li><a href="http://www.laruence.com/2009/08/18/1042.html"  title="保证PHP扩展的依赖关系" >保证PHP扩展的依赖关系</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/11/02/1789.html/feed</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Facebook发布又一PHP改进项目XHP</title>
		<link>http://www.laruence.com/2010/07/16/1638.html</link>
		<comments>http://www.laruence.com/2010/07/16/1638.html#comments</comments>
		<pubDate>Fri, 16 Jul 2010 07:14:27 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1638</guid>
		<description><![CDATA[   根据Github上项目的文档维基，XHP是一个PHP扩展，通过它，开发人员可以直接在PHP代码中内嵌XML文档片段，作为合法的PHP表达式。这样，PHP就成为一个更为严格的模板引擎，大大简化了实现可重用组件的工作。
]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/07/16/1638.html"  title="Permanet Link to Facebook发布又一PHP改进项目XHP" >http://www.laruence.com/2010/07/16/1638.html</a></li>
<li>文章转自: http://news.csdn.net/a/20100211/216991.html</li>
</ul></div>
<p>     就在Google高调发布业界普遍认为针对Facebook的Buzz的同时，Facebook则低调发布了XHP项目。这是一个多月以来，继HipHop之后，Facebook推出的又一重要PHP改进项目。看来，在社会化网络市场地位稳固之后，Facebook也开始大力回馈技术社区，在口碑和攒人品方面与Google展开竞争了。</p>
<p>   根据<a href="http://wiki.github.com/facebook/xhp/"  target="_blank" >Github上项目的文档维基</a>，XHP是一个PHP扩展，通过它，开发人员可以直接在PHP代码中内嵌XML文档片段，作为合法的PHP表达式。这样，PHP就成为一个更为严格的模板引擎，大大简化了实现可重用组件的工作。</p>
<p>比如这样的简单代码示例：</p>
<pre name="code"  class="sh_php"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;?php
rquire &quot;xphsrc/php-lib/init.php&quot;;
$href = 'http://www.facebook.com';
echo &lt;a href={$href}&gt;Facebook&lt;/a&gt;
</pre>
<p>注意第三行代码中的语法，其中echo后的不是字符串。</p>
<p>项目负责人Facebook工程师Marcel Laverdet则表示，XHP不仅使前端代码更容易理解，还有助于防止跨站脚本攻击。事实上，Facebook Lite网站（快速简化版本的Facebook）就是完全用XHP写成的。</p>
<p>和上次HipHop发布一样，PHP之父Rasmus Lerdorf也很快做出回应（<a href="http://toys.lerdorf.com/archives/54-A-quick-look-at-XHP.html" >英文原文链接</a>），他说：</p>
<blockquote><p>XHP其实就是支持内嵌XML，这在VB中称为<a href="http://msdn.microsoft.com/zh-cn/library/bb384832.aspx" >XML元素文本</a>。它增加了一个额外的分析步骤，将内嵌的XML元素映射为PHP类。类的语法有些奇怪。至少对我而言，其中主要有意思的地方，是PHP现在理解要输出的XML了，就可以以上下文敏感的方式进行过滤。</p></blockquote>
<p>Lerdorf也指出，XHP存在明显的性能问题，它的XML运行时验证显然会增加开销。为此，Facebook不得不使用APC[Alternative PHP Cache]再加上HipHop。</p>
<p>对此，Marcel Laverdet回复：</p>
<blockquote><p>性能的确是XHP最引人关注的问题。确实，XHP比原始的字符串拼接要慢2到3倍，但是这对大多数程序都不是问题。另外，虽然APC肯定是必需的（大多数网站都是如此），HipHop则不然。其实Lite网站只是到最近才开始切换到HipHop，之前也表现很不错。在实际应用中，XHP对性能影响并不是很大。在简洁和性能之间的权衡上，XHP做得不错。</p></blockquote>
<p>此外，Wikispaces的创始人James Byers也写到：</p>
<blockquote><p>对我来说，XHP比HipHop有意思得多。它将完全改变模板还是只用PHP的争论。对此我很高兴。PHP应该继续这样改进。</p></blockquote>
<p>Tipjoy的联合创始人，现在也在Facebook任工程师的Ivan Kirigin也对XHP赞赏有加：</p>
<blockquote><p>XHP是我在Facebook唯一使用的PHP工具，比其他语言类似的东西都好。记号完美代表了对象，不用折腾面向对象编程那些烂东西了，这可是非常罕见的宝贝。</p></blockquote>
<p><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/16</a>, <a href="http://liruqi.cn/"  rel="external nofollow"  class="url" >liruqi</a> writes: 赞, 这东西可以直接替代smarty框架了.</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/16</a>, <a href="http://dothing"  rel="external nofollow"  class="url" >lake</a> writes: 又有得折腾了，也证明了php持续在受到关注。</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/16</a>, <a href="http://www.bpzc.net/"  rel="external nofollow"  class="url" >bpzc</a> writes: 热切关注中~~~</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/16</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @liruqi 还能做标签配对检查, 输出转义,,,,,</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/17</a>, <a href="http://topsy.com/www.laruence.com/2010/07/16/1638.html?utm_source=pingback&#038;utm_campaign=L2"  rel="external nofollow"  class="url" >Tweets that mention Facebook发布又一PHP改进项目XHP | 风雪之隅 -- Topsy.com</a> writes: [...] This post was mentioned on Twitter by 大房 and Jason Yu, Angus Li. Angus Li said: Facebook发布又一PHP改进项目XHP http://ff.im/-nNZx8 [...]</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/17</a>, <a href="http://woshimaijia.com"  rel="external nofollow"  class="url" >xinqiyang</a> writes: 这样有个好处就是落花了模板引擎的了.......

关注下呵呵</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/22</a>, <a href="http://www.xiuyu.com"  rel="external nofollow"  class="url" >修愚</a> writes: 路过，学习</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/07/26</a>, wclssdn writes: 我怎么感觉模板框架是为了分工而使用的呢- - 

美工直接修改模板文件而不必理会PHP代码.. 

要是按照上边所说的... 内个. php程序员无敌了..</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/09/01</a>, <a href="http://www.globalmarket.com"  rel="external nofollow"  class="url" >China Suppliers</a> writes: PHP被应用得越来越广泛了。以前我只看到了大多数人开始倾向用PHP来做网站，现在SNS的应用也开始使用PHP了。</li><li><a href="http://www.laruence.com/2010/07/16/1638.html" >2010/12/09</a>, xi writes: PHP的意义在于可以折腾，比起其他脚本语言，
容易折腾到更底层，从底层折腾的好处就是，有不满，可以自己做库，不需要官方支持。

所以底层知识是一定要掌握的，这样就好自己折腾了</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/02/03/1283.html"  rel="bookmark"  title="Permanent Link: Facebook性能大提升的秘密：HipHop" >Facebook性能大提升的秘密：HipHop</a></li><li><a href="http://www.laruence.com/2010/11/02/1789.html"  rel="bookmark"  title="Permanent Link: [转载]技术文化和惨淡命运 —— 怀念中国雅虎" >[转载]技术文化和惨淡命运 —— 怀念中国雅虎</a></li><li><a href="http://www.laruence.com/2011/12/02/2333.html"  rel="bookmark"  title="Permanent Link: Yaf 2.1性能测试(Yaf 2.1 Benchmark)" >Yaf 2.1性能测试(Yaf 2.1 Benchmark)</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2008/08/16/301.html"  title="扩展PHP[Extending PHP](一)" >扩展PHP[Extending PHP](一)</a></li><li><a href="http://www.laruence.com/2009/12/17/1182.html"  title="服务器搬到国外主机" >服务器搬到国外主机</a></li><li><a href="http://www.laruence.com/2008/07/01/322.html"  title="在Gvim中使用和Vim一样的配色方案" >在Gvim中使用和Vim一样的配色方案</a></li><li><a href="http://www.laruence.com/2009/04/23/692.html"  title="最近发生了一些很重要的事情" >最近发生了一些很重要的事情</a></li><li><a href="http://www.laruence.com/2009/02/21/662.html"  title="PHP字符串比较" >PHP字符串比较</a></li><li><a href="http://www.laruence.com/2009/06/17/951.html"  title="思考能力何其重要.." >思考能力何其重要..</a></li><li><a href="http://www.laruence.com/2008/10/16/559.html"  title="引用外部JS文件的编码问题" >引用外部JS文件的编码问题</a></li><li><a href="http://www.laruence.com/2011/09/19/2148.html"  title="PHP的版本发布历程" >PHP的版本发布历程</a></li><li><a href="http://www.laruence.com/2010/06/22/1618.html"  title="ReflectionFunction(Method)引用参数导致Invocation failed" >ReflectionFunction(Method)引用参数导致Invocation failed</a></li><li><a href="http://www.laruence.com/2011/03/22/1929.html"  title="PHP Reflection Extension的一个bug" >PHP Reflection Extension的一个bug</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/07/16/1638.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>用Vim写Blog</title>
		<link>http://www.laruence.com/2010/04/17/1433.html</link>
		<comments>http://www.laruence.com/2010/04/17/1433.html#comments</comments>
		<pubDate>Sat, 17 Apr 2010 03:57:02 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.laruence.com/2010/04/17/1433.html</guid>
		<description><![CDATA[Vim是一种毒品，一旦你习惯之后就无法离开：），写Blog也是如此。以前用Vim写Blog是依赖Vimperator可以调出Vim进行编辑，不过今天发现了更简便、连游览器都不需要开的方法，那就是Vim的Blog插件：vimpress。vimpress支持获取文章列表并编辑修改文件、新建文章、现场保存，并支持文章分类、标签。]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/04/17/1433.html"  title="Permanet Link to 用Vim写Blog" >http://www.laruence.com/2010/04/17/1433.html</a></li>
<li>文章转自: <a href="http://www.imv0m.com/?p=512"  target="_blank" >Venom</a></li>
</ul></div>
<p>Vim是一种毒品，一旦你习惯之后就无法离开：），写Blog也是如此。以前用Vim写Blog是依赖Vimperator可以调出Vim进行编辑，不过今天发现了更简便、连游览器都不需要开的方法，那就是Vim的Blog插件：vimpress。vimpress支持获取文章列表并编辑修改文件、新建文章、现场保存，并支持文章分类、标签。</p>
<p>PS：这篇文章就是我使用vimpress直接在gVim中完成的。</p>
<p>需注意的是，vimpress仅支持xlmrpc，下载前请先检查你的Blog是否具有xlmrpc功能！具体关于xlmrpc的信息请访问http://zh.wikipedia.org/zh-cn/XML-RPC</p>
<p>vimpress的下载地址在http://www.vim.org/scripts/script.php?script_id=1953</p>
<p>下载完vimpress之后，将插件对应文件夹放入。然后编辑blog.vim找到并修改以下代码。</p>
<pre name="code"  class="sh_python"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
command! -nargs=0 BlogList exec(&quot;py blog_list_posts()&quot;)
command! -nargs=0 BlogNew exec(&quot;py blog_new_post()&quot;)
command! -nargs=0 BlogSend exec(&quot;py blog_send_post()&quot;)
command! -nargs=1 BlogOpen exec('py blog_open_post(&lt;f-args&gt;)')
python &lt;&lt;EOF
# -*- coding: utf-8 -*-
import urllib , urllib2 , vim , xml.dom.minidom , xmlrpclib , sys , string , re

#####################
#      Settings     #
#####################

enable_tags = 1
blog_username = 'Test' #你用于登陆Blog的账户名
blog_password = 'Test' #你的Blog账户的地址
blog_url = 'http://www.test.com/xmlrpc.php' #你的Blog的xmlrpc文件地址  

#####################
# Do not edit below #
#####################

handler = xmlrpclib.ServerProxy(blog_url).metaWeblog
edit = 1

def blog_edit_off():
  global edit
  if edit:
    edit = 0
    for i in [&quot;i&quot;,&quot;a&quot;,&quot;s&quot;,&quot;o&quot;,&quot;I&quot;,&quot;A&quot;,&quot;S&quot;,&quot;O&quot;]:
    .....省略
</pre>
<p>然后重新启动你的Vim即可，以下是vimpress的命令清单。</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
:BlogList #列出Blog里的文章
:BlogNew #创建新文章
:BlogOpen ID #打开ID为“”的文章
:BlogSend #发布文章
</pre>
<p>vimpress的格式为：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&quot;Strid #你的文章的ID
&quot;Title #文章的标题
&quot;Cats #文章分类，如有多个分类需建立多个Cats
&quot;Tags #文章标签，多个标签需中间加入，空格
</pre>
<p>转载标注: 如果是wordpress, 在setting->writing中开启xml-rpc既可以使用. 不过目前不支持excerpt和custom fields, 比较郁闷.<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_python.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/18</a>, 小熊 writes: 小熊来拜雪候鸟锅锅</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/18</a>, <a href="http://topsy.com/trackback?utm_source=pingback&#038;utm_campaign=L2&#038;url=http://www.laruence.com/2010/04/17/1433.html"  rel="external nofollow"  class="url" >Tweets that mention 用Vim写Blog -- Topsy.com</a> writes: [...] This post was mentioned on Twitter by Jerry Wang, 开瓢android机器人. 开瓢android机器人 said: 用Vim写Blog http://goo.gl/fb/TvtOr [...]</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/18</a>, Yufeng writes: 哈哈，的确是会上瘾的，也说不上来为啥，只感觉别的工具写代码都好像不那么好用……</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/18</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @yufeng 呵呵,现在赞同我当时要求你使用VIM了吧. :)</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/19</a>, <a href="http://sanmuding.com"  rel="external nofollow"  class="url" >Anders</a> writes: 帮你纠错:

需注意的是，vimpress仅支持xlmrpc，下载前请先检查你的Blog是否具有xlmrpc功能！具体关于xlmrpc的信息请访问http://zh.wikipedia.org/zh-cn/XML-RPC

应该为 xmlrpc吧。</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/19</a>, <a href="http://blog.fouland.com/2010/04/vimpress-and-new-colorscheme-of-wp.sb"  rel="external nofollow"  class="url" >SpriteWood &raquo; Blog Archive &raquo; vimpress and new colorscheme of wp</a> writes: [...] google reader, 在 风雪之隅 上发现了这个蛮好玩的东东 vimpress, 配置一下 用户名/密码/xmlrpc地址 [...]</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/04/20</a>, <a href="http://www.js4j.com"  rel="external nofollow"  class="url" >技术世界</a> writes: 我用的不是博客程序!~~</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/05/06</a>, yufeng writes: @雪候鸟 唉，当时要是不用就好了，导致心理失衡，看人家用IDE就想推销VIM，还要用力克制推销欲望，只淡淡一句：哦，其实VIM也挺好用的。</li><li><a href="http://www.laruence.com/2010/04/17/1433.html" >2010/07/12</a>, <a href="http://www.bestfinance-blog.com"  rel="external nofollow"  class="url" >personal loans</a> writes: Do you acknowledge that it is the best time to get the mortgage loans, which will help you.</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/08/18/1718.html"  title="将PHP Manual融入(g)Vim" >将PHP Manual融入(g)Vim</a></li><li><a href="http://www.laruence.com/2007/10/03/5.html"  title="VIM中文乱码解决方案" >VIM中文乱码解决方案</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/04/17/1433.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>浏览器缓存机制</title>
		<link>http://www.laruence.com/2010/03/05/1332.html</link>
		<comments>http://www.laruence.com/2010/03/05/1332.html#comments</comments>
		<pubDate>Fri, 05 Mar 2010 06:19:51 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[cache-control]]></category>
		<category><![CDATA[浏览器]]></category>
		<category><![CDATA[缓存]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1332</guid>
		<description><![CDATA[<style>
#excerpt_random_111 {
   border:1px #000 solid;
   border-collapse:collapse;
}
#excerpt_random_111 td {
   border:1px #000 solid;
   padding:0;
}
</style>
<table id="excerpt_random_111">
	<tr>
                <caption>关键结论</caption>
		<td width="12%">打开新窗口</td>
		<td>如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如：Cache-control: max-age=5 表示当访问此网页后的5秒内再次访问不会去服务器.</td>
	</tr>
	<tr>
		<td>在地址栏回车</td>
		<td>如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。 </td>
	</tr>
	<tr>
		<td>按后退按扭</td>
		<td>如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.</td>
	</tr>
	<tr>
		<td>按刷新按扭</td>
		<td>无论为何值,都会重复访问. </td>
	</tr>
</table>
]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/03/05/1332.html"  title="Permanet Link to 浏览器缓存机制" >http://www.laruence.com/2010/03/05/1332.html</a></li>
<li>文章转自: http://harry.javaeye.com/blog/605749</li>
</ul></div>
<style>
	#random_2832398324 table {
		border:1px #555 solid; 
		border-collapse:collapse; 
		margin-top:10px;
	}
	#random_2832398324 td {
		border:1px #555 solid; 
		padding:1px;
	}
	#random_2832398324 th {
		background:none;
		border:1px #555 solid; 
		text-align:center;
	}
</style>
<div id="random_2832398324" >
	<b>Cache-Control</b></p>
<p>	Cache-Control 是最重要的规则。这个字段用于指定所有缓存机制在整个请求/响应链中必须服从的指令。这些指令指定用于阻止缓存对请求或响应造成不利干扰的行为。这些指令通常覆盖默认缓存算法。缓存指令是单向的，即请求中存在一个指令并不意味着响应中将存在同一个指令。</p>
<p>	cache-control 定义是：Cache-Control = &#8220;Cache-Control&#8221; &#8220;:&#8221; cache-directive。表 1 展示了适用的值。</p>
<table>
<caption>
			表 1. 常用 cache-directive 值<br/>
		</caption>
<tr>
<th>Cache-directive</th>
<th>说明</th>
</tr>
<tr>
<td>public</td>
<td>所有内容都将被缓存</td>
</tr>
<tr>
<td>private</td>
<td>内容只缓存到私有缓存中</td>
</tr>
<tr>
<td>no-cache</td>
<td>所有内容都不会被缓存</td>
</tr>
<tr>
<td>no-store</td>
<td>所有内容都不会被缓存到缓存或 Internet 临时文件中</td>
</tr>
<tr>
<td>must-revalidation/proxy-revalidation</td>
<td>如果缓存的内容失效，请求必须发送到服务器/代理以进行重新验证</td>
</tr>
<tr>
<td>max-age=xxx (xxx is numeric)</td>
<td>缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并如果和Last-Modified一起使用时, 优先级较高</td>
</tr>
</table>
<p>	表 2 表明在不同的情形下，浏览器是将请求重新发送到服务器还是使用缓存的内容。</p>
<table>
<caption>
			表 2. 对 cache-directive 值的浏览器响应<br/>
		</caption>
<tr>
<th>Cache-directive</th>
<th>打开一个新的浏览器窗口</th>
<th>在原窗口中单击 Enter 按钮</th>
<th>刷新</th>
<th>单击 Back 按钮</th>
</tr>
<tr>
<td>public</td>
</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器</td>
<td>浏览器呈现来自缓存的页面</td>
</tr>
<tr>
<td>private</td>
<td>浏览器重新发送请求到服务器</td>
<td>第一次，浏览器重新发送请求到服务器；此后，浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器</td>
<td>浏览器呈现来自缓存的页面</td>
</tr>
<tr>
<td>no-cache/no-store</td>
<td>浏览器重新发送请求到服务器</td>
<td>浏览器重新发送请求到服务器</td>
<td>浏览器重新发送请求到服务器</td>
<td>浏览器重新发送请求到服务器</td>
</tr>
<tr>
<td>must-revalidation/proxy-revalidation</td>
<td>浏览器重新发送请求到服务器</td>
<td>第一次，浏览器重新发送请求到服务器；此后，浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器</td>
<td>浏览器呈现来自缓存的页面</td>
</tr>
<tr>
<td>max-age=xxx (xxx is numeric)</td>
<td>在 xxx 秒后，浏览器重新发送请求到服务器</td>
<td>在 xxx 秒后，浏览器重新发送请求到服务器</td>
<td>浏览器重新发送请求到服务器</td>
<td>在 xxx 秒后，浏览器重新发送请求到服务器</td>
</tr>
</tr>
</table>
<p>Cache-Control是关于浏览器缓存的最重要的设置，因为它覆盖其他设置，比如 Expires 和 Last-Modified。另外，由于浏览器的行为基本相同，这个属性是处理跨浏览器缓存问题的最有效的方法。</p>
<p><b>失效</b></p>
<p>Expires 头部字段提供一个日期和时间，响应在该日期和时间后被认为失效。失效的缓存条目通常不会被缓存（无论是代理缓存还是用户代理缓存）返回，除非首先通过原始服务器（或者拥有该实体的最新副本的中介缓存）验证。（注意：cache-control max-age 和 s-maxage 将覆盖 Expires 头部。）</p>
<p>Expires 字段接收以下格式的值：“Expires: Sun, 08 Nov 2009 03:37:26 GMT”。如果查看内容时的日期在给定的日期之前，则认为该内容没有失效并从缓存中提取出来。反之，则认为该内容失效，缓存将采取一些措施。表 3-6 表明针对不同用户操作的不同浏览器的行为。</p>
<table>
<caption>
		表 3. 当用户打开一个新的浏览器窗口时的失效操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容没有失效</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
</tr>
<tr>
<td>内容失效</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<table>
<caption>
		表 4. 当用户在原始浏览器窗口中单击 Enter 按钮时的失效操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容没有失效</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
</tr>
<tr>
<td>内容失效</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<table>
<caption>
		表 5. 当用户按 F5 键刷新页面时的失效操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容没有失效</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
</tr>
<tr>
<td>内容失效</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<table>
<caption>
		表 6. 当用户单击 Back 或 Forward 按钮时的失效操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容没有失效</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
</tr>
<tr>
<td>内容失效</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<p>注意：所有浏览器都假定为使用默认设置运行。</p>
<p><b>Last-Modified/E-Tag</b></p>
<p>Last-Modified 实体头部字段值通常用作一个缓存验证器。简单来说，如果实体值在 Last-Modified 值之后没有被更改，则认为该缓存条目有效。ETag 响应头部字段值是一个实体标记，它提供一个 “不透明” 的缓存验证器。这可能在以下几种情况下提供更可靠的验证：不方便存储修改日期；HTTP 日期值的 one-second 解决方案不够用；或者原始服务器希望避免由于使用修改日期而导致的某些冲突。</p>
<p>不同的浏览器有不同的配置行为。表 7-10 表明针对不同用户操作的不同浏览器的行为。</p>
<table>
<caption>
		表 7. 当用户打开一个新的浏览器窗口时的 Last-Modified E-Tag 操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容自上次访问以来没有被修改</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
</tr>
<tr>
<td>内容自上次访问以来已经被修改</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<table>
<caption>
		表 8. 当用户在原始浏览器窗口中单击 Enter 按钮时的 Last-Modified E-Tag 操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容自上次访问以来没有被修改</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
</tr>
<tr>
<td>内容自上次访问以来已经被修改</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<table>
<caption>
		表 9. 当用户按 F5 键刷新页面时的 Last-Modified E-Tag 操作<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容自上次访问以来没有被修改</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
<td>浏览器重新发送请求到服务器。返回代码是 304</td>
</tr>
<tr>
<td>内容自上次访问以来已经被修改</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<table>
<caption>
		表 10. 没有缓存设置且用户单击 Back 或 Forward 按钮<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>内容自上次访问以来没有被修改</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
</tr>
<tr>
<td>内容自上次访问以来已经被修改</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器呈现来自缓存的页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<p>注意：所有浏览器都假定使用默认设置运行。</p>
<p>不进行任何缓存相关设置</p>
<p>如果您不定义任何缓存相关设置，则不同的浏览器有不同的行为。有时，同一个浏览器在相同的情形下每次运行时的行为都是不同的。情况可能很复杂。另外，有些不该缓存的内容如果被缓存，将会导致安全问题。<br/>
不同的浏览器有不同的行为。表 11 展示了不同的浏览器行为。</p>
<table>
<caption>
		表 11. 没有缓存设置且用户打开一个新的浏览器窗口<br/>
	</caption>
<tr>
<th></th>
<th>Firefox 3.5</th>
<th>IE 8</th>
<th>Chrome 3</th>
<th>Safari 4</th>
</tr>
<tr>
<td>打开一个新页面</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
<tr>
<td>在原始窗口中单击 Enter 按钮</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器呈现来自缓存的页面。</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
<tr>
<td>按 F5 键刷新</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
<tr>
<td>单击 Back 或 Forward 按钮</td>
<td>浏览器呈现来自缓存的页面。</td>
<td>浏览器呈现来自缓存的页面。</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
<td>浏览器重新发送请求到服务器。返回代码是 200</td>
</tr>
</table>
<p>注意：所有浏览器都假定使用默认设置运行。</p>
<p>最后, 概括下关键的结论:</p>
<table>
<caption>关键结论</caption>
<tr>
<td width="12%" >打开新窗口</td>
<td>如果指定cache-control的值为private、no-cache、must-revalidate,那么打开新窗口访问时都会重新访问服务器。而如果指定了max-age值,那么在此值内的时间里就不会重新访问服务器,例如：Cache-control: max-age=5 表示当访问此网页后的5秒内再次访问不会去服务器.</td>
</tr>
<tr>
<td>在地址栏回车</td>
<td>如果值为private或must-revalidate,则只有第一次访问时会访问服务器,以后就不再访问。如果值为no-cache,那么每次都会访问。如果值为max-age,则在过期之前不会重复访问。 </td>
</tr>
<tr>
<td>按后退按扭</td>
<td>如果值为private、must-revalidate、max-age,则不会重访问,而如果为no-cache,则每次都重复访问.</td>
</tr>
<tr>
<td>按刷新按扭</td>
<td>无论为何值,都会重复访问. </td>
</tr>
</table>
</div>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/03/17</a>, <a href="http://zhangabc.com"  rel="external nofollow"  class="url" >yufeng</a> writes: 学习了，呵呵 。</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/03/17</a>, <a href="http://www.beeboo.org.cn"  rel="external nofollow"  class="url" >beeboo</a> writes: 好文章！</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/03/25</a>, <a href="http://zhangabc.com"  rel="external nofollow"  class="url" >yufeng</a> writes: 呵呵，你的博客被墙了，唉。</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/05/05</a>, bailey writes: 不错  顶</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/05/07</a>, <a href="http://rss.9ria.com/?p=4"  rel="external nofollow"  class="url" >达达的Google Reader分享 [2010-03-05] &laquo; 9RIA.Com 天地会博客聚合</a> writes: [...] 浏览器缓存机制 [...]</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/05/11</a>, <a href="http://www.impng.com/front-end/add-expires-header-read-notes.html"  rel="external nofollow"  class="url" >第三章：添加Expires头 —《高性能网站建设指南》读书笔记 &#8211; im Png</a> writes: [...] 更多的关于浏览器缓存及其参数可以参看浏览器缓存机制一文。 [...]</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/05/29</a>, <a href="http://rss.9ria.com/?p=1323"  rel="external nofollow"  class="url" >达达的Google Reader分享 [2010-03-05] : : 9RIA.Com 天地会博客聚合</a> writes: [...] 浏览器缓存机制 [...]</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2010/09/10</a>, <a href="http://www.interpretersky.com"  rel="external nofollow"  class="url" >Tour guide beijing</a> writes: 我的新网站改版后，测试一直出错，检查一直找不到错误。问了人才知道原来是浏览器缓存的问题。刚好看到你的博客，收藏起来先，以后或许还用得着。嘻嘻。</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2011/05/04</a>, <a href="http://interbund.com"  rel="external nofollow"  class="url" >Shanghai Business Interpreter</a> writes: 好深奥</li><li><a href="http://www.laruence.com/2010/03/05/1332.html" >2011/08/26</a>, <a href="http://www.coblogs.co"  rel="external nofollow"  class="url" >Mr.CO</a> writes: 不错！好东东！学习了！
博主想给你交换个友链哦！</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/10/19/2247.html"  title="Zend Signal in PHP 5.4" >Zend Signal in PHP 5.4</a></li><li><a href="http://www.laruence.com/2008/10/31/574.html"  title="关于一笔试题(Iterator模式)" >关于一笔试题(Iterator模式)</a></li><li><a href="http://www.laruence.com/2008/04/17/110.html"  title="页面乱码问题根源浅析" >页面乱码问题根源浅析</a></li><li><a href="http://www.laruence.com/2010/05/24/1515.html"  title="shell下发推脚本" >shell下发推脚本</a></li><li><a href="http://www.laruence.com/2011/09/30/2187.html"  title="和一朋友对话有感" >和一朋友对话有感</a></li><li><a href="http://www.laruence.com/2008/12/31/647.html"  title="一个低概率的PHP Core dump" >一个低概率的PHP Core dump</a></li><li><a href="http://www.laruence.com/2008/08/17/313.html"  title="PHP的老式语法" >PHP的老式语法</a></li><li><a href="http://www.laruence.com/2010/03/31/1377.html"  title="东方时尚约车脚本(greaseMoney)V2.0" >东方时尚约车脚本(greaseMoney)V2.0</a></li><li><a href="http://www.laruence.com/2008/08/15/274.html"  title="PHP 源代码分析 V0.0.2" >PHP 源代码分析 V0.0.2</a></li><li><a href="http://www.laruence.com/2009/05/14/803.html"  title="浏览器的结构" >浏览器的结构</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/03/05/1332.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Facebook性能大提升的秘密：HipHop</title>
		<link>http://www.laruence.com/2010/02/03/1283.html</link>
		<comments>http://www.laruence.com/2010/02/03/1283.html#comments</comments>
		<pubDate>Wed, 03 Feb 2010 03:00:08 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[hiphop]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1283</guid>
		<description><![CDATA[评论: 从最早听说Facebook搞一个神奇的项目开始, 我就在猜测它会怎么做? 想APC一样编译成Opcode? 或者是象phc从Opcode再次加工. 但, 今天看到的介绍, 让我还是有点出乎意料...哪就是- HipHop提供编译器, 让你可以"用PHP的语法写C++代码".

以下为转载原文:Facebook神秘的PHP项目HipHop for  PHP终于揭开面纱。这个项目由一个PHP到C++的转换程序，一个重新实现的PHP运行库，和许多常用PHP扩展的重写版本构成，目的是旨在加速和优化 PHP。]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/02/03/1283.html"  title="Permanet Link to Facebook性能大提升的秘密：HipHop" >http://www.laruence.com/2010/02/03/1283.html</a></li>
<li>文章转自: <a href="http://www.csdn.net/"  target="_blank" >CSDN</a></li>
</ul></div>
<p>评论: 从最早听说Facebook搞一个神奇的项目开始, 我就在猜测它会怎么做? 想APC一样编译成Opcode? 或者是象phc从Opcode再次加工. 但, 今天看到的介绍, 让我还是有点出乎意料&#8230;哪就是- HipHop提供编译器, 让你可以&#8221;用PHP的语法写C++代码&#8221;.</p>
<p>以下为转载原文:<br/>
<a href="http://laruence-wordpress.stor.sinaapp.com/uploads/20100203-044306-pic1.png" ><img class="alignright size-full wp-image-1286"  title="20100203-044306-pic1"  src="http://laruence-wordpress.stor.sinaapp.com/uploads/20100203-044306-pic1.png"  alt=""  width="213"  height="278" /></a>Facebook神秘的PHP项目HipHop for  PHP终于揭开面纱。这个项目由一个PHP到C++的转换程序，一个重新实现的PHP运行库，和许多常用PHP扩展的重写版本构成，目的是旨在加速和优化 PHP。</p>
<p>用<a href="http://developers.facebook.com/news.php?story=358blog=1" >Facebook 官方博客</a>（无法直接访问）上项目负责人赵海平（北大1987届遗传与分子生物专业，普林斯顿计算机科学博士）的话说，HipHop项目对 Facebook影响巨大。它目前已经支撑了Facebook 90%的Web流量。由于HipHop，Facebook  Web服务器上的CPU使用平均减少了50%，从而大大减少了服务器的需求。为了让这一改进也惠及社区，他们决定将之开源，希望能够进一步帮助提高更多大 型复杂PHP网站的可伸缩性。</p>
<p><strong>PHP和Facebook的问题</strong></p>
<p>众所周知，Facebook的前端主要是用PHP写的。赵海平说，过去六年Facebook从PHP语言的进展上获益良多。PHP非常简单，易学易 用，好读好调试，因此新工程师成长很快，有利地促进了Facebook的更快的创新。<br/>
<a href="http://laruence-wordpress.stor.sinaapp.com/uploads/20100203-043453-pic1.jpg" ><img class="alignright size-full wp-image-1287"  title="20100203-043453-pic1"  src="http://laruence-wordpress.stor.sinaapp.com/uploads/20100203-043453-pic1.jpg"  alt=""  width="200"  height="200" /></a></p>
<p>PHP是一种脚本语言，其好处是编程效率高，能够支持产品的快速迭代。但是与传统的编译语言相比，脚本语言的CPU和内存使用效率不好。随着 Ajax技术的广泛采用，加上SNS对动态要求较高，这些缺点更显得突出。对于每月超过4000亿次PV的Facebook来说，如何实现扩展，尤其具有 挑战性。</p>
<p>常见的办法是直接用C++重写PHP应用中比较复杂的部分，作为PHP扩展。实际上，PHP就转变为一种胶水语言，连接前端HTML和C++应用逻 辑。从技术角度讲这也没有问题，但是增加了技能需求，能够在整个应用上工作的工程师数量就大大减少了。学习C++只是编写PHP扩展的第一步，接下来还要 理解Zend  API。由于Facebook的工程团队较小，每个工程师要支持100万以上的用户。有些代码不是团队里每个人都能看懂，这对于Facebook是无法接 受的。</p>
<p>Facebook网站本身的可伸缩性更具挑战性，因为几乎每次页面浏览都是有个性化体验的登录用户发起。浏览主页  时，系统需要查询所有朋友、朋友最重要的状态更新、  根据隐私设置筛选结果，然后还要显示评论、照片等等动态，这一切都需要在一秒内完  成。</p>
<p>自2007年以来，Facebook曾写过几种不同办法解决这些问题。其中包括用另   一种语言重写Facebook，但是由于开发的复杂性和速度等原因，未能实现。他们还重写了PHP的核心部分Zend引擎，并提交给了PHP项目，但最终 还是没有获得所需的性能。最后，他们选择了HipHop，终于得偿所愿。</p>
<p>有了HipHop，工程师可以编写代码，用PHP编写组合最后页面的逻辑，并能够继续快速迭代，同时后端服务使用C++, Erlang,  Java, Py  thon编写，提供新闻提要、搜索、聊天和其他核心功能。</p>
<p><strong>HipHop开发故事</strong></p>
<p>赵海平透露，项目最初是来自几年前Facebook公司一次Hackathon活动（员工在一个晚上自由发挥，实验新的想法），他手工将PHP转换 为C++代码，虽然语法上很类似，但是无论是CPU还是内存使用，转换后的C++代码都大大优于PHP。于是他想，如果构建一个系统，编程实现转换，会怎 么样呢？</p>
<p>在此之前，已经有了不少改善PHP性能的方法。Zend引擎在运行时转换PHP源代码为运行在Zend虚拟机上的opcode。开源项目APC和 eAccelerator将输出缓存，为大多数PHP网站所使用。此外，还有Zend  Server这样的商业产品，通过opcode优化和缓存，提高PHP速度。赵海平选择了另一条道路，将PHP直接转为C++，然后再变成本地机器码。当 然，有许多开源项目也是同样的思路，Roadsend和phc编译为C，Quercus编译为Java，而Phalanger编译为.NET。</p>
<p>Hackathon之后8个月，赵海平拿出了原型，足以说明这条路可以走通，编译后的代码的确更快。不久，Iain  Proctor和Minghui  Yang加入进来。接下来又开发了10个月，在生产服务器上测试了6个月。然后正式上线部署，6个月之后，Facebook  90%以上的Web流量都使用了HipHop。</p>
<p>按赵海平的说法，凭借HipHop，Facebook  Web服务器上的CPU使用平均减少了50%，从而大大减少了服务器的需求。项目对Facebook影响巨大。为了让这一改进也惠及社区，他们决定将之开 源，希望能够进一步帮助提高更多大型复杂PHP网站的可伸缩性。</p>
<div id="attachment_1288"  class="wp-caption aligncenter"  style="width: 660px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/20100203-050719-pic1.jpg" ><img class="size-full wp-image-1288"  title="20100203-050719-pic1"  src="http://laruence-wordpress.stor.sinaapp.com/uploads/20100203-050719-pic1.jpg"  alt=""  width="650"  height="406" /></a><p class="wp-caption-text" >Hiphop for PHP transformation process</p></div>
<p><strong>HipHop的原理</strong></p>
<p>HipHop将PHP代码转换为高度优化的C++代码，然后再用g++编译器编译。它可以保持语义等效地执行源代码，但为了提高性能，牺牲了一些很 少用到的特性，比如eval()。</p>
<p>HipHop开发中的主要困难在于，在PHP和C++这两种很不一样的语言之间怎么实现转换。虽然PHP也可以写一些很巧妙的动态特性，但是大多数 PHP代码还是非常简单的。if (&#8230;) {&#8230;} else {..} 比foo($x) { include $x; }  肯定更常见。这为性能提高提供了机会。HipHop生成的代码尽可能地使用函数和变量的静态绑定。同时，还使用类型推演来选出变量最可能对应的某个类型， 从而节省内存。</p>
<p>转换过程分三步：</p>
<p>1. 静态分析。收集声明关系和依赖关系等信息。</p>
<p>2. 类型推演。选择最合适的类型，是C++的标量？还是String, Array, classes, Object或者Variant。</p>
<p>3. 代码生成。大部分直接将PHP语句和表达式对应为C++的语句和表达式。</p>
<p>在开发过程中，还有一个副产品：HPHPi，是一个实验性的解释器。通过它，不编译PHP源代码也可以运行。它已经用于HipHop自身的调试中。</p>
<p>HipHop在保持了PHP优点的同时，也兼得了C++的性能优势。项目总共有30万行代码，5000多个单元测试。所有这些都将以PHP开源许可 证形式发布到GitHub。</p>
<p>更多信息，可以申请加入HipHop的邮件列表：</p>
<p><a href="http://groups.google.com/group/hiphop-php-dev" >http://groups.google.com/group/hiphop-php-dev</a></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/02/03/1283.html" >2010/02/04</a>, <a href="http://www.909520.cn"  rel="external nofollow"  class="url" >侯良</a> writes: 这个是个好东西。
一定要把它学会 。</li><li><a href="http://www.laruence.com/2010/02/03/1283.html" >2010/02/05</a>, <a href="http://www.nnbizhi.com"  rel="external nofollow"  class="url" >cnan</a> writes: 感觉想不想google的用java写JavaScript</li><li><a href="http://www.laruence.com/2010/02/03/1283.html" >2010/02/10</a>, yufeng writes: 前一阵子看到了，不过没有这篇文章详细，据说还要开源的。</li><li><a href="http://www.laruence.com/2010/02/03/1283.html" >2010/02/11</a>, jimmy writes: 是 c++ 而不是 c 的原因是什么呢，laruence.</li><li><a href="http://www.laruence.com/2010/02/03/1283.html" >2010/02/21</a>, Anonymous writes: 本来我想用的是C，而不是C++。
看来慢了一步了。</li><li><a href="http://www.laruence.com/2010/02/03/1283.html" >2011/11/18</a>, <a href="http://www.51facebook.com"  rel="external nofollow"  class="url" >51facebook</a> writes: 现在国内无法直接上facebook，不过可以参考51facebook.com的教程来上，非常方便！</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/07/16/1638.html"  rel="bookmark"  title="Permanent Link: Facebook发布又一PHP改进项目XHP" >Facebook发布又一PHP改进项目XHP</a></li><li><a href="http://www.laruence.com/2010/11/02/1789.html"  rel="bookmark"  title="Permanent Link: [转载]技术文化和惨淡命运 —— 怀念中国雅虎" >[转载]技术文化和惨淡命运 —— 怀念中国雅虎</a></li><li><a href="http://www.laruence.com/2011/12/02/2333.html"  rel="bookmark"  title="Permanent Link: Yaf 2.1性能测试(Yaf 2.1 Benchmark)" >Yaf 2.1性能测试(Yaf 2.1 Benchmark)</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li><li><a href="http://www.laruence.com/2011/12/29/2412.html"  title="通过构造Hash冲突实现各种语言的拒绝服务攻击" >通过构造Hash冲突实现各种语言的拒绝服务攻击</a></li><li><a href="http://www.laruence.com/2011/12/06/2381.html"  title="更简单的重现PHP Core的调用栈" >更简单的重现PHP Core的调用栈</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/02/03/1283.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>pkg-config与LD_LIBRARY_PATH</title>
		<link>http://www.laruence.com/2010/01/27/1265.html</link>
		<comments>http://www.laruence.com/2010/01/27/1265.html#comments</comments>
		<pubDate>Wed, 27 Jan 2010 11:34:28 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[GNU C/C++]]></category>
		<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[ld.so.conf]]></category>
		<category><![CDATA[LD_LIBRARY_PATH]]></category>
		<category><![CDATA[pkg-config]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1265</guid>
		<description><![CDATA[    一般来说，如果库的头文件不在 /usr/include 目录中，那么在编译的时候需要用 -I 参数指定其路径。由于同一个库在不同系统上可能位于不同的目录下，用户安装库的时候也可以将库安装在不同的目录下，所以即使使用同一个库，由于库的路径的不同，造成了用 -I 参数指定的头文件的路径也可能不同，其结果就是造成了编译命令界面的不统一。如果使用 -L 参数，也会造成连接界面的不统一。编译和连接界面不统一会为库的使用带来麻烦。

       为了解决编译和连接界面不统一的问题，人们找到了一些解决办法。其基本思想就是：事先把库的位置信息等保存起来，需要的时候再通过特定的工具将其中有用的 信息提取出来供编译和连接使用。这样，就可以做到编译和连接界面的一致性。其中，目前最为常用的库信息提取工具就是下面介绍的 pkg-config...]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2010/01/27/1265.html"  title="Permanet Link to pkg-config与LD_LIBRARY_PATH" >http://www.laruence.com/2010/01/27/1265.html</a></li>
<li>文章转自: <a href="http://hi.baidu.com/litaosmile/blog/item/751be4f45bbb4ee67609d7be.html"  target="_blank" >Lucky_xi的百度空间</a></li>
</ul></div>
<p>最近遇到的几个问题， 都和LD_LIBRARY_PATH有关， 想整理一篇心得， 但发现一片比较好的介绍文章， 就不再赘笔了。</p>
<h3>一、编译和连接</h3>
<p>        一般来说，如果库的头文件不在 /usr/include 目录中，那么在编译的时候需要用 -I 参数指定其路径。由于同一个库在不同系统上可能位于不同的目录下，用户安装库的时候也可以将库安装在不同的目录下，所以即使使用同一个库，由于库的路径的不同，造成了用 -I 参数指定的头文件的路径也可能不同，其结果就是造成了编译命令界面的不统一。如果使用 -L 参数，也会造成连接界面的不统一。编译和连接界面不统一会为库的使用带来麻烦。</p>
<p>       为了解决编译和连接界面不统一的问题，人们找到了一些解决办法。其基本思想就是：事先把库的位置信息等保存起来，需要的时候再通过特定的工具将其中有用的 信息提取出来供编译和连接使用。这样，就可以做到编译和连接界面的一致性。其中，目前最为常用的库信息提取工具就是下面介绍的 pkg-config。</p>
<p>       pkg-config 是通过库提供的一个 .pc 文件获得库的各种必要信息的，包括版本信息、编译和连接需要的参数等。这些信息可以通过 pkg-config 提供的参数单独提取出来直接供编译器和连接器使用。</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
  The pkgconfig package contains tools for passing the include path and/or library
paths to build tools during the make file execution.

  pkg-config is a function that returns meta information for the specified library.

  The default setting for PKG_CONFIG_PATH is /usr/lib/pkgconfig because of the prefix
we use to install pkgconfig. You may add to PKG_CONFIG_PATH by exporting additional
paths on your system where pkgconfig files are installed. Note that PKG_CONFIG_PATH is
only needed when compiling packages, not during run-time.
</pre>
<p>        在默认情况下，每个支持 pkg-config 的库对应的 .pc 文件在安装后都位于安装目录中的 lib/pkgconfig 目录下。例如，我们在上面已经将 Glib 安装在 /opt/gtk 目录下了，那么这个 Glib 库对应的 .pc 文件是 /opt/gtk/lib/pkgconfig 目录下一个叫 glib-2.0.pc 的文件：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
prefix=/opt/gtk/
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

glib_genmarshal=glib-genmarshal
gobject_query=gobject-query
glib_mkenums=glib-mkenums

Name: GLib
Description: C Utility Library
Version: 2.12.13
Libs: -L${libdir} -lglib-2.0
Cflags: -I${includedir}/glib-2.0 -I${libdir}/glib-2.0/include
</pre>
<p>使用 pkg-config 的 &#8211;cflags 参数可以给出在编译时所需要的选项，而 &#8211;libs 参数可以给出连接时的选项。例如，假设一个 sample.c 的程序用到了 Glib 库，就可以这样编译：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ gcc -c `pkg-config --cflags glib-2.0` sample.c
</pre>
<p>然后这样连接：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ gcc sample.o -o sample `pkg-config --libs glib-2.0`
</pre>
<p>或者上面两步也可以合并为以下一步：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ gcc sample.c -o sample `pkg-config --cflags --libs glib-2.0`
</pre>
<p>可以看到：由于使用了 pkg-config 工具来获得库的选项，所以不论库安装在什么目录下，都可以使用相同的编译和连接命令，带来了编译和连接界面的统一。</p>
<p>使用 pkg-config 工具提取库的编译和连接参数有两个基本的前提：</p>
<p>库本身在安装的时候必须提供一个相应的 .pc 文件。不这样做的库说明不支持 pkg-config 工具的使用。</p>
<p>pkg-config 必须知道要到哪里去寻找此 .pc 文件。</p>
<p>GTK+ 及其依赖库支持使用 pkg-config 工具，所以剩下的问题就是如何告诉 pkg-config 到哪里去寻找库对应的 .pc 文件，这也是通过设置搜索路径来解决的。</p>
<p>       对于支持 pkg-config 工具的 GTK+ 及其依赖库来说，库的头文件的搜索路径的设置变成了对 .pc 文件搜索路径的设置。.pc 文件的搜索路径是通过环境变量 PKG_CONFIG_PATH 来设置的，pkg-config 将按照设置路径的先后顺序进行搜索，直到找到指定的 .pc 文件为止。</p>
<p>安装完 Glib 后，在 bash 中应该进行如下设置：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH
</pre>
<p>可以执行下面的命令检查是否 /opt/gtk/lib/pkgconfig 路径已经设置在 PKG_CONFIG_PATH 环境变量中：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ echo $PKG_CONFIG_PATH
</pre>
<p>这样设置之后，使用 Glib 库的其它程序或库在编译的时候 pkg-config 就知道首先要到 /opt/gtk/lib/pkgconfig 这个目录中去寻找 glib-2.0.pc 了（GTK+ 和其它的依赖库的 .pc 文件也将拷贝到这里，也会首先到这里搜索它们对应的 .pc 文件）。之后，通过 pkg-config 就可以把其中库的编译和连接参数提取出来供程序在编译和连接时使用。</p>
<p>另外还需要注意的是：环境变量的设置只对当前的终端窗口有效。如果到了没有进行上述设置的终端窗口中，pkg-config 将找不到新安装的 glib-2.0.pc 文件、从而可能使后面进行的安装（如 Glib 之后的 Atk 的安装）无法进行。</p>
<p>       在我们采用的安装方案中，由于是使用环境变量对 GTK+ 及其依赖库进行的设置，所以当系统重新启动、或者新开一个终端窗口之后，如果想使用新安装的 GTK+ 库，需要如上面那样重新设置 PKG_CONFIG_PATH 和 LD_LIBRARY_PATH 环境变量。</p>
<p>这种使用 GTK+ 的方法，在使用之前多了一个对库进行设置的过程。虽然显得稍微繁琐了一些，但却是一种最安全的使用 GTK+ 库的方式，不会对系统上已经存在的使用了 GTK+ 库的程序（比如 GNOME 桌面）带来任何冲击。</p>
<p>为了使库的设置变得简单一些，可以把下面的这两句设置保存到一个文件中（比如 set_gtk-2.10 文件）:</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
export PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig:$PKG_CONFIG_PATH
export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
</pre>
<p>之后，就可以用下面的方法进行库的设置了（其中的 source 命令也可以用 . 代替）：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ source set_gtk-2.10
</pre>
<p>只有在用新版的 GTK+ 库开发应用程序、或者运行使用了新版 GTK+ 库的程序的时候，才有必要进行上述设置。</p>
<p>           如果想避免使用 GTK+ 库之前上述设置的麻烦，可以把上面两个环境变量的设置在系统的配置文件中（如 /etc/profile）或者自己的用户配置文件中（如 ~/.bash_profile） ；库的搜索路径也可以设置在 /etc/ld.so.conf 文件中，等等。这种设置在系统启动时会生效，从而会导致使用 GTK+ 的程序使用新版的 GTK+ 运行库，这有可能会带来一些问题。当然，如果你发现用新版的 GTK+ 代替旧版没有什么问题的话，使用这种设置方式是比较方便的。加入到~/.bashrc中，例如：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
PKG_CONFIG_PATH=/opt/gtk/lib/pkgconfig
</pre>
<p>重启之后：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
[root@localhost ~]# echo $PKG_CONFIG_PATH
/opt/gtk/lib/pkgconfig
</pre>
<h3> 二、运行时 </h3>
<p>        库文件在连接（静态库和共享库）和运行（仅限于使用共享库的程序）时被使用，其搜索路径是在系统中进行设置的。一般 Linux 系统把 /lib 和 /usr/lib 两个目录作为默认的库搜索路径，所以使用这两个目录中的库时不需要进行设置搜索路径即可直接使用。对于处于默认库搜索路径之外的库，需要将库的位置添加到 库的搜索路径之中。设置库文件的搜索路径有下列两种方式，可任选其一使用：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
在环境变量 LD_LIBRARY_PATH 中指明库的搜索路径。
在 /etc/ld.so.conf 文件中添加库的搜索路径。
</pre>
<p>        将自己可能存放库文件的路径都加入到/etc/ld.so.conf中是明智的选择 ^_^<br/>
添加方法也极其简单，将库文件的绝对路径直接写进去就OK了，一行一个。例如：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
/usr/X11R6/lib
/usr/local/lib
/opt/lib
</pre>
<p>        需要注意的是：第二种搜索路径的设置方式对于程序连接时的库（包括共享库和静态库）的定位已经足够了，但是对于使用了共享库的程序的执行还是不够的。这是 因为为了加快程序执行时对共享库的定位速度，避免使用搜索路径查找共享库的低效率，所以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非文本的数据文件，不能直接编辑，它是根据 /etc/ld.so.conf 中设置的搜索路径由 /sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的（ldconfig 命令要以 root 权限执行）。因此，为了保证程序执行时对库的定位，在 /etc/ld.so.conf 中进行了库搜索路径的设置之后，还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件之后才可以。ldconfig ,简单的说，它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件，(例如刚安装好glib)，或者修改ld.so.conf增加新的库路径后，需要运行一下 /sbin/ldco                                 .cache中，如果没做，即使库文件明明就在/usr/lib下的，也是不会被使用 的，结果编译                                现明明就在那放着，搞的想大骂computer蠢猪一个。 ^_^</p>
<p>       在程序连接时，对于库文件（静态库和共享库）的搜索路径，除了上面的设置方式                                 。因为用 -L 设置的路径将被优先搜索，所以在连接的时候通常都会以这种方式直接指定</p>
<p>        前面已经说明过了，库搜索路径的设置有两种方式：在环境变量 LD_LIBRARY_PA                                文件中设置。其中，第二种设置方式需要 root 权限，以改变 /etc/ld.so.conf 文件并执                                 系统重新启动后，所有的基于 GTK2 的程序在运行时都将使用新安装的 GTK+ 库。不幸的                                会给应用程序带来兼容性的问题，造成某些程序运行不正常。为了避免出现上面的这些情                                中对于库的搜索路径的设置将采用第一种方式进行。这种设置方式不需要 root 权限，设</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
</pre>
<p>可以用下面的命令查看 LD_LIBRAY_PATH 的设置内容：</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ echo $LD_LIBRARY_PATH
</pre>
<p>至此，库的两种设置就完成了。<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script></p>
<hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2008/11/11/606.html"  rel="bookmark"  title="Permanent Link: 图解aclocal、autoconf、automake、autoheader、configure" >图解aclocal、autoconf、automake、autoheader、configure</a></li><li><a href="http://www.laruence.com/2008/08/19/327.html"  rel="bookmark"  title="Permanent Link: 用Tidy优化你的HTML(Optimizing HTML with Tidy)" >用Tidy优化你的HTML(Optimizing HTML with Tidy)</a></li><li><a href="http://www.laruence.com/2011/10/05/2192.html"  rel="bookmark"  title="Permanent Link: mysqlnd插件mysqlnd_ms的介绍" >mysqlnd插件mysqlnd_ms的介绍</a></li><li><a href="http://www.laruence.com/2008/08/21/358.html"  rel="bookmark"  title="Permanent Link: Firefox DNS Cache 清除 扩展 V0.1" >Firefox DNS Cache 清除 扩展 V0.1</a></li><li><a href="http://www.laruence.com/2008/08/16/301.html"  rel="bookmark"  title="Permanent Link: 扩展PHP[Extending PHP](一)" >扩展PHP[Extending PHP](一)</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/10/10/2212.html"  title="Array dereferencing" >Array dereferencing</a></li><li><a href="http://www.laruence.com/2010/05/04/1450.html"  title="深入理解PHP之require/include顺序" >深入理解PHP之require/include顺序</a></li><li><a href="http://www.laruence.com/2008/07/11/108.html"  title="IE下的Javascript调试利器:Companion.js" >IE下的Javascript调试利器:Companion.js</a></li><li><a href="http://www.laruence.com/2008/08/12/180.html"  title="深入理解Zend SAPIs(Zend SAPI Internals)" >深入理解Zend SAPIs(Zend SAPI Internals)</a></li><li><a href="http://www.laruence.com/2009/04/28/719.html"  title="用C/C++扩展你的PHP" >用C/C++扩展你的PHP</a></li><li><a href="http://www.laruence.com/2008/09/04/498.html"  title="PHP4中模拟类的析构函数" >PHP4中模拟类的析构函数</a></li><li><a href="http://www.laruence.com/2011/11/28/2317.html"  title="PHP5.4中一个需要注意的变化(Chained string offsets)" >PHP5.4中一个需要注意的变化(Chained string offsets)</a></li><li><a href="http://www.laruence.com/2011/09/13/2139.html"  title="关于做PHP扩展开发的一些资源" >关于做PHP扩展开发的一些资源</a></li><li><a href="http://www.laruence.com/2007/11/15/10.html"  title="一个误区（关于javascript的字符串拼接)" >一个误区（关于javascript的字符串拼接)</a></li><li><a href="http://www.laruence.com/2009/10/15/1131.html"  title="提升PHP性能之改变Zend引擎分发方式" >提升PHP性能之改变Zend引擎分发方式</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2010/01/27/1265.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>automake,autoconf使用详解</title>
		<link>http://www.laruence.com/2009/11/18/1154.html</link>
		<comments>http://www.laruence.com/2009/11/18/1154.html#comments</comments>
		<pubDate>Wed, 18 Nov 2009 08:37:50 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[GNU C/C++]]></category>
		<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[aclocal]]></category>
		<category><![CDATA[autoconf]]></category>
		<category><![CDATA[automake]]></category>
		<category><![CDATA[configure]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1154</guid>
		<description><![CDATA[    作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下,大家都是手工写一个简单Makefile,如果要想写出一个符合自由软件惯例的Makefile就不那么容易了.

    在本文中,将给大家介绍如何使用autoconf和automake两个工具来帮助我们自动地生成符合自由软件惯例的 Makefile,这样就可以象常见的 GNU程序一样,只要使用"./configure","make","make instal"就可以把程序安装到Linux系统中去了.

    这将特别适合想做开放源代码软件的程序开发人员,又或如果你只是自己写些小的Toy程序,那么这个文章对你也会有很大的帮助.
转自:<a href="http://www.linuxcomputer.cn/jishuwendang/xinshourumen/200902/03-3029.html">http://www.linuxcomputer.cn/jishuwendang/xinshourumen/200902/03-3029.html</a>]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2009/11/18/1154.html"  title="Permanet Link to automake,autoconf使用详解" >http://www.laruence.com/2009/11/18/1154.html</a></li>
<li>文章转自: <a href="http://www.linuxcomputer.cn/jishuwendang/xinshourumen/200902/03-3029.html" >http://www.linuxcomputer.cn/</a></li>
</ul></div>
<p>	作为Linux下的程序开发人员,大家一定都遇到过Makefile,用make命令来编译自己写的程序确实是很方便.一般情况下,大家都是手工写一个简单Makefile,如果要想写出一个符合自由软件惯例的Makefile就不那么容易了.</p>
<p>	在本文中,将给大家介绍如何使用autoconf和automake两个工具来帮助我们自动地生成符合自由软件惯例的 Makefile,这样就可以象常见的 GNU程序一样,只要使用&#8221;./configure&#8221;,&#8221;make&#8221;,&#8221;make instal&#8221;就可以把程序安装到Linux系统中去了.</p>
<p>       这将特别适合想做开放源代码软件的程序开发人员,又或如果你只是自己写些小的Toy程序,那么这个文章对你也会有很大的帮助.<br/>
　<br/>
<h3>一.Makefile介绍</h3>
<p>　　Makefile是用于自动编译和链接的 ,一个工程有很多文件组成,每一个文件的改变都会导致工程的重新链接,但是不是 所有的文件都需要重新编译,Makefile中纪录有文件的信息,在 make时会决定在链接的时候需要重新编译哪些文件.<br/>
　<br/>
　	Makefile的宗旨就是 ：让编译器知道要编译一个文件需要依赖其他的 哪些文件.当那些依赖文件有了改变,编译器会自动的发现最终的生成文件已经过时,而重新编译相应的 模块.<br/>
　　<br/>
	Makefile的 基本结构不是 很复杂,但当一个程序开发人员开始写Makefile时,经常会怀疑自己写的 是 否符合惯例,而且自己写的 Makefile经常和自己的 开发环境相关联,当系统环境变量或路径发生了变化后,Makefile可能还要跟着修改.这样就造成了手工书写Makefile的 诸多问题,automake恰好能很好地帮助我们解决这些问题.<br/>
　　<br/>
	使用automake,程序开发人员只需要写一些简单的 含有预定义宏的 文件,由autoconf根据一个宏文件生成configure,由automake根据另一个宏文件生成Makefile.in,再使用configure依据Makefile.in来生成一个符合惯例的 Makefile.下面我们将详细介绍Makefile的 automake生成方法.<br/>
　　</p>
<h3>二.使用的 环境</h3>
<p>　　本文所提到的 程序是 基于Linux发行版本：Fedora Core release 1,它包含了我们要用到的 autoconf,automake.</p>
<p>　　<br/>
<h3>三.从helloworld入手</h3>
<p>　　我们从大家最常使用的 例子程序helloworld开始.</p>
<p>　　下面的 过程如果简单地说来就是 ：</p>
<p>　　新建三个文件：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
　　　helloworld.c
　　　configure.in
　　　Makefile.am
</pre>
<p>　　然后执行：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
aclocal; autoconf; automake --add-missing; ./configure; make; ./helloworld
</pre>
<p>　　就可以看到Makefile被产生出来,而且可以将helloworld.c编译通过.</p>
<p>　　很简单吧,几条命令就可以做出一个符合惯例的 Makefile,感觉如何呀.</p>
<p>　　<b>现在 开始介绍详细的 过程：</b></p>
<p>　　1.建目录</p>
<p>　　在 你的 工作目录下建一个helloworld目录,我们用它来存放helloworld程序及相关文件,如在 /home/my/build下：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ mkdir helloword
$ cd helloworld
</pre>
<p>　　2. helloworld.c</p>
<p>　　然后用你自己最喜欢的 编辑器写一个hellowrold.c文件,如命令：vi helloworld.c.使用下面的 代码作为helloworld.c的 内容.</p>
<pre name="code"  class="sh_c"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
#include &lt;stdio.h&gt;
int main(int argc, char** argv){
	printf(&quot;%s&quot;, 'Hello, Linux World!\n&quot;);
	return 0;
}
</pre>
<p>　　完成后保存退出.<br/>
　　现在 在 helloworld目录下就应该有一个你自己写的 helloworld.c了.</p>
<p>　　3.生成configure</p>
<p>　　我们使用autoscan命令来帮助我们根据目录下的 源代码生成一个configure.in的 模板文件.<br/>
　　命令：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ autoscan
$ ls
configure.scan helloworld.c
</pre>
<p>　　执行后在 hellowrold目录下会生成一个文件：configure.scan,我们可以拿它作为configure.in的 蓝本.<br/>
　　现在 将configure.scan改名为configure.in,并且编辑它,按下面的 内容修改,去掉无关的 语句：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
==========================configure.in内容开始=========================================
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_INIT(helloworld.c)
AM_INIT_AUTOMAKE(helloworld, 1.0)
# Checks for programs.
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_OUTPUT(Makefile)
==========================configure.in内容结束=========================================
</pre>
<p>　　然后执行命令aclocal和autoconf,分别会产生aclocal.m4及configure两个文件：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ aclocal
$ls
aclocal.m4 configure.in helloworld.c
$ autoconf
$ ls
aclocal.m4 autom4te.cache configure configure.in helloworld.c
</pre>
<p>　　大家可以看到configure.in内容是 一些宏定义,这些宏经autoconf处理后会变成检查系统特性.环境变量.软件必须的 参数的 shell脚本.</p>
<p>　　autoconf 是 用来生成自动配置软件源代码脚本（configure）的 工具.configure脚本能独立于autoconf运行,且在 运行的 过程中,不需要用户的 干预.</p>
<p>　　要生成configure文件,你必须告诉autoconf如何找到你所用的 宏.方式是 使用aclocal程序来生成你的 aclocal.m4.</p>
<p>　　aclocal根据configure.in文件的 内容,自动生成aclocal.m4文件.aclocal是 一个perl 脚本程序,它的 定义是 ：&#8221;aclocal &#8211; create aclocal.m4 by scanning configure.ac&#8221;.</p>
<p>　　autoconf从configure.in这个列举编译软件时所需要各种参数的 模板文件中创建configure.</p>
<p>　　autoconf需要GNU m4宏处理器来处理aclocal.m4,生成configure脚本.</p>
<p>　　m4是 一个宏处理器.将输入拷贝到输出,同时将宏展开.宏可以是 内嵌的 ,也可以是 用户定义的 .除了可以展开宏,m4还有一些内建的 函数,用来引用文件,执行命令,整数运算,文本操作,循环等.m4既可以作为编译器的 前端,也可以单独作为一个宏处理器.</p>
<p>4.新建Makefile.am<br/>
　　新建Makefile.am文件,命令：</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ vi Makefile.am
　　内容如下:
AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS=helloworld
helloworld_SOURCES=helloworld.c
</pre>
<p>　　automake会根据你写的 Makefile.am来自动生成Makefile.in.</p>
<p>　　Makefile.am中定义的 宏和目标,会指导automake生成指定的 代码.例如,宏bin_PROGRAMS将导致编译和连接的 目标被生成.<br/>
　　5.运行automake:</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ automake --add-missing
configure.in: installing `./install-sh'
configure.in: installing `./mkinstalldirs'
configure.in: installing `./missing'
Makefile.am: installing `./depcomp'
</pre>
<p>　　automake会根据Makefile.am文件产生一些文件,包含最重要的 Makefile.in.</p>
<p>　　6.执行configure生成Makefile</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking for gcc... gcc
checking for C compiler default output... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables...
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ANSI C... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
$ ls -l Makefile
-rw-rw-r-- 1 yutao yutao 15035 Oct 15 10:40 Makefile
</pre>
<p>你可以看到,此时Makefile已经产生出来了.</p>
<p>7.使用Makefile编译代码</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$make
if gcc -DPACKAGE_NAME=\&quot;FULL-PACKAGE-NAME\&quot; -DPACKAGE_TARNAME=\&quot;full-package-name\&quot; -DPACKAGE_VERSION=\&quot;VERSION\&quot; -DPACKAGE_STRING=\&quot;FULL-PACKAGE-NAME\ VERSION\&quot; -DPACKAGE_BUGREPORT=\&quot;BUG-REPORT-ADDRESS\&quot; -DPACKAGE=\&quot;helloworld\&quot; -DVERSION=\&quot;1.0\&quot; -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_STDLIB_H=1  -I. -I.     -g -O2 -MT helloworld.o -MD -MP -MF &quot;.deps/helloworld.Tpo&quot; -c -o helloworld.o helloworld.c; \
then mv -f &quot;.deps/helloworld.Tpo&quot; &quot;.deps/helloworld.Po&quot;; else rm -f &quot;.deps/helloworld.Tpo&quot;; exit 1; fi
gcc  -g -O2   -o helloworld  helloworld.o
</pre>
<p>　　运行helloworld</p>
<pre name="code"  class="sh_sh"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
$ ./helloworld
Hello, Linux World!
</pre>
<p>　　这样helloworld就编译出来了,你如果按上面的 步骤来做的 话,应该也会很容易地编译出正确的 helloworld文件.你还可以试着使用一些其他的 make命令,如make clean,make install,make dist,看看它们会给你什么样的 效果.感觉如何？自己也能写出这么专业的 Makefile,老板一定会对你刮目相看.</p>
<h3>四.深入浅出</h3>
<p>　　针对上面提到的 各个命令,我们再做些详细的 介绍.</p>
<pre  style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
　　1. autoscan
　　autoscan是 用来扫描源代码目录生成configure.scan文件的 .autoscan
可以用目录名做为参数,但如果你不使用参数的 话,那么autoscan将认为使用的是当前目录.
autoscan将扫描你所指定目录中的 源文件,并创建configure.scan文件.
　　2. configure.scan
　　configure.scan包含了系统配置的 基本选项,里面都是 一些宏定义.我们需要将它改名为
configure.in
　　3. aclocal
　　aclocal是 一个perl 脚本程序.aclocal根据configure.in文件的 内容
,自动生成aclocal.m4文件.aclocal的 定义是 ："aclocal - create
aclocal.m4 by scanning configure.ac".
　　4. autoconf
　　autoconf是 用来产生configure文件的 .configure是 一个脚本,它能设置
源程序来适应各种不同的操作系统平台,并且根据不同的 系统来产生合适的 Makefile,从而可以使
你的源代码能在不同的操作系统平台上被编译出来.
　　configure.in文件的 内容是 一些宏,这些宏经过autoconf 处理后会变成检查系统
特性.环境变量.软件必须的 参数的 shell脚本.configure.in文件中的 宏的 顺序并没
有规定,但是 你必须在 所有宏的 最前面和最后面分别加上AC_INIT宏和AC_OUTPUT宏.
　　在 configure.ini中：
　　#号表示注释,这个宏后面的 内容将被忽略.
　　AC_INIT(FILE)
　　这个宏用来检查源代码所在 的 路径.
AM_INIT_AUTOMAKE(PACKAGE, VERSION)
　　 这个宏是 必须的 ,它描述了我们将要生成的 软件包的 名字及其版本号：PACKAGE是软件包
的名字,VERSION是 版本号.当你使用make dist命令时,它会给你生成一个类似
helloworld-1.0.tar.gz的 软件发行包,其中就有对应的 软件包的 名字和版本号.
AC_PROG_CC
　　这个宏将检查系统所用的 C编译器.
AC_OUTPUT(FILE)
　　这个宏是 我们要输出的 Makefile的 名字.
　　我们在 使用automake时,实际上还需要用到其他的 一些宏,但我们可以用aclocal 来帮
我们自动产生.执行aclocal后我们会得到aclocal.m4文件.
　　产生了configure.in和aclocal.m4 两个宏文件后,我们就可以使用autocon
f来产生configure文件了.
　　5. Makefile.am
　　Makefile.am是 用来生成Makefile.in的 ,需要你手工书写.Makefile.
am中定义了一些内容：
AUTOMAKE_OPTIONS
　　这个是 automake的 选项.在 执行automake时,它会检查目录下是 否存在 标准
GNU软件包中应具备的各种文件,例如AUTHORS.ChangeLog.NEWS等文件.
我们将其设置成foreign时,automake会改用一般软件包的 标准来检查.
bin_PROGRAMS
　　这个是 指定我们所要产生的 可执行文件的 文件名.如果你要产生多个可执行文件,
那么在各个名字间用空格隔开.
helloworld_SOURCES
　　这个是 指定产生"helloworld"时所需要的 源代码.如果它用到了多个源文件,
那么请使用空格符号将它们隔开.比如需要helloworld.h,helloworld.c那么请写成:
helloworld_SOURCES= helloworld.h helloworld.c.
　　如果你在 bin_PROGRAMS定义了多个可执行文件,则对应每个可执行文件都要定义相对的
filename_SOURCES.
　　6. automake
　　我们使用automake --add-missing来产生Makefile.in.
　　选项--add-missing的 定义是 "add missing standard files
 to package",它会让automake加入一个标准的 软件包所必须的 一些文件.
　　我们用automake产生出来的 Makefile.in文件是 符合GNU Makefile惯例
的 ,接下来我们只要执行configure这个shell 脚本就可以产生合适的 Makefile 文
件了.
　　7. Makefile
　　在 符合GNU Makefiel惯例的 Makefile中,包含了一些基本的 预先定义的 操作：

make
　　根据Makefile编译源代码,连接,生成目标文件,可执行文件.
make clean
　　清除上次的 make命令所产生的 object文件（后缀为".o"的 文件）及可执行文件.
make install
　　将编译成功的 可执行文件安装到系统目录中,一般为/usr/local/bin目录.
make dist
　　产生发布软件包文件（即distribution package）.这个命令将会将可执行文件及相关
文件打包成一个tar.gz压缩的 文件用来作为发布软件的 软件包.
　　它会在 当前目录下生成一个名字类似"PACKAGE-VERSION.tar.gz"的 文件.PA
CKAGE和VERSION,是 我们在 configure.in中定义的 AM_INIT_AUTOM
AKE(PACKAGE, VERSION).
make distcheck
　　生成发布软件包并对其进行测试检查,以确定发布包的正确性.
</pre>
<p><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_c.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_sh.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/11/18/1154.html" >2010/01/25</a>, Nathan writes: That's awesome!
It would be great help for me.</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/08/04/2131.html"  title="Plua进入Pecl" >Plua进入Pecl</a></li><li><a href="http://www.laruence.com/2011/10/10/2212.html"  title="Array dereferencing" >Array dereferencing</a></li><li><a href="http://www.laruence.com/2009/09/14/1081.html"  title="CSS让你的IE浏览器崩溃(Crash your IE)" >CSS让你的IE浏览器崩溃(Crash your IE)</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2009/05/10/786.html"  title="东方时尚约车脚本(greaseMoney)" >东方时尚约车脚本(greaseMoney)</a></li><li><a href="http://www.laruence.com/2009/12/26/1198.html"  title="深入理解PHP原理之变量生命期(一)" >深入理解PHP原理之变量生命期(一)</a></li><li><a href="http://www.laruence.com/2010/05/20/1495.html"  title="Nginx + PHP CGI的一个可能的安全漏洞" >Nginx + PHP CGI的一个可能的安全漏洞</a></li><li><a href="http://www.laruence.com/2010/06/20/1602.html"  title="深入理解PHP之匿名函数" >深入理解PHP之匿名函数</a></li><li><a href="http://www.laruence.com/2008/09/04/498.html"  title="PHP4中模拟类的析构函数" >PHP4中模拟类的析构函数</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2009/11/18/1154.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>深入理解JavaScript定时机制</title>
		<link>http://www.laruence.com/2009/09/23/1089.html</link>
		<comments>http://www.laruence.com/2009/09/23/1089.html#comments</comments>
		<pubDate>Wed, 23 Sep 2009 07:18:28 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[Js/CSS]]></category>
		<category><![CDATA[转载]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[setinterval]]></category>
		<category><![CDATA[settimeout]]></category>
		<category><![CDATA[单线程]]></category>
		<category><![CDATA[原理]]></category>
		<category><![CDATA[定时器]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1089</guid>
		<description><![CDATA[<pre class="sh_javascript">
setTimeout(function() {
    alert('你好!');
}, 0);
setInterval(callbackFunction, 100);
</pre>

认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了.
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!

但随着JavaScript应用开发经验不断的增加和丰富,有一天你发现了一段怪异的代码而百思不得其解.....]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2009/09/23/1089.html"  title="Permanet Link to 深入理解JavaScript定时机制" >http://www.laruence.com/2009/09/23/1089.html</a></li>
<li>转载文章</li>
</ul></div>
<p>转帖地址:<a href="http://www.9demo.com/archives/341" >http://www.9demo.com/archives/341</a></p>
<p>容易欺骗别人感情的JavaScript定时器</p>
<p>JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如</p>
<pre class="sh_javascript"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
setTimeout(function() {
    alert('你好!');
}, 0);
setInterval(callbackFunction, 100);
</pre>
<p>认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了.<br/>
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!</p>
<p>但随着JavaScript应用开发经验不断的增加和丰富,有一天你发现了一段怪异的代码而百思不得其解:</p>
<pre class="sh_javascript"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
div.onclick = function(){
        setTimeout(function() {
                document.getElementById('inputField').focus();
        }, 0);
};
</pre>
<p>既然是0毫秒后执行,那么还用setTimeout干什么, 此刻, 坚定的信念已开始动摇.</p>
<p>直到最后某一天 , 你不小心写了一段糟糕的代码:</p>
<pre class="sh_javascript"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
setTimeout(function() {
        while (true) {
        }
}, 100);
setTimeout(function() {
        alert('你好!');
}, 200);
setInterval(callbackFunction, 200);
</pre>
<p>第一行代码进入了死循环,但不久你就会发现,第二,第三行并不是预料中的事情,alert问候未见出现,callbacKFunction也杳无音讯!</p>
<p>这时你彻底迷惘了,这种情景是难以接受的,因为改变长久以来既定的认知去接受新思想的过程是痛苦的,但情事实摆在眼前,对JavaScript真理的探求并不会因为痛苦而停止,下面让我们来展开JavaScript线程和定时器探索之旅!</p>
<p>拔开云雾见月明</p>
<p>出现上面所有误区的最主要一个原因是:潜意识中认为,JavaScript引擎有多个线程在执行,JavaScript的定时器回调函数是异步执行的.</p>
<p>而事实上的,JavaScript使用了障眼法,在多数时候骗过了我们的眼睛,这里背光得澄清一个事实:</p>
<p>JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序.</p>
<p>JavaScript引擎用单线程运行也是有意义的,单线程不必理会线程同步这些复杂的问题,问题得到简化.</p>
<p>那么单线程的JavaScript引擎是怎么配合浏览器内核处理这些定时器和响应浏览器事件的呢?<br/>
下面结合浏览器内核处理方式简单说明.</p>
<p>浏览器内核实现允许多个线程异步执行,这些线程在内核制控下相互配合以保持同步.假如某一浏览器内核的实现至少有三个常驻线程:javascript引擎线程,界面渲染线程,浏览器事件触发线程,除些以外,也有一些执行完就终止的线程,如Http请求线程,这些异步线程都会产生不同的异步事件,下面通过一个图来阐明单线程的JavaScript引擎与另外那些线程是怎样互动通信的.虽然每个浏览器内核实现细节不同,但这其中的调用原理都是大同小异.</p>
<div id="attachment_1090"  class="wp-caption aligncenter"  style="width: 510px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/jstimer.jpg" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/jstimer.jpg"  alt="Js线程图示"  title="jstimer"  width="500"  height="272"  class="size-full wp-image-1090" /></a><p class="wp-caption-text" >Js线程图示</p></div>
<p>由图可看出,浏览器中的JavaScript引擎是基于事件驱动的,这里的事件可看作是浏览器派给它的各种任务,这些任务可以源自JavaScript引擎当前执行的代码块,如调用setTimeout添加一个任务,也可来自浏览器内核的其它线程,如界面元素鼠标点击事件,定时触发器时间到达通知,异步请求状态变更通知等.从代码角度看来任务实体就是各种回调函数,JavaScript引擎一直等待着任务队列中任务的到来.由于单线程关系,这些任务得进行排队,一个接着一个被引擎处理.</p>
<p>上图t1-t2..tn表示不同的时间点,tn下面对应的小方块代表该时间点的任务,假设现在是t1时刻,引擎运行在t1对应的任务方块代码内,在这个时间点内,我们来描述一下浏览器内核其它线程的状态.</p>
<p>t1时刻:</p>
<p>GUI渲染线程:</p>
<p>该线程负责渲染浏览器界面HTML元素,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行.本文虽然重点解释JavaScript定时机制,但这时有必要说说渲染线程,因为该线程与JavaScript引擎线程是互斥的,这容易理解,因为JavaScript脚本是可操纵DOM元素,在修改这些元素属性同时渲染界面,那么渲染线程前后获得的元素数据就可能不一致了.</p>
<p>在JavaScript引擎运行脚本期间,浏览器渲染线程都是处于挂起状态的,也就是说被”冻结”了.</p>
<p>所以,在脚本中执行对界面进行更新操作,如添加结点,删除结点或改变结点的外观等更新并不会立即体现出来,这些操作将保存在一个队列中,待JavaScript引擎空闲时才有机会渲染出来.</p>
<p>GUI事件触发线程:</p>
<p>JavaScript脚本的执行不影响html元素事件的触发,在t1时间段内,首先是用户点击了一个鼠标键,点击被浏览器事件触发线程捕捉后形成一个鼠标点击事件,由图可知,对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标点击事件正在等待处理.</p>
<p>定时触发线程:</p>
<p>注意这里的浏览器模型定时计数器并不是由JavaScript引擎计数的,因为JavaScript引擎是单线程的,如果处于阻塞线程状态就计不了时,它必须依赖外部来计时并触发定时,所以队列中的定时事件也是异步事件.</p>
<p>由图可知,在这t1的时间段内,继鼠标点击事件触发后,先前已设置的setTimeout定时也到达了,此刻对JavaScript引擎来说,定时触发线程产生了一个异步定时事件并放到任务队列中, 该事件被排到点击事件回调之后,等待处理.<br/>
同理, 还是在t1时间段内,接下来某个setInterval定时器也被添加了,由于是间隔定时,在t1段内连续被触发了两次,这两个事件被排到队尾等待处理.</p>
<p>可见,假如时间段t1非常长,远大于setInterval的定时间隔,那么定时触发线程就会源源不断的产生异步定时事件并放到任务队列尾而不管它们是否已被处理,但一旦t1和最先的定时事件前面的任务已处理完,这些排列中的定时事件就依次不间断的被执行,这是因为,对于JavaScript引擎来说,在处理队列中的各任务处理方式都是一样的,只是处理的次序不同而已.</p>
<p>t1过后,也就是说当前处理的任务已返回,JavaScript引擎会检查任务队列,发现当前队列非空,就取出t2下面对应的任务执行,其它时间依此类推,由此看来:</p>
<p>如果队列非空,引擎就从队列头取出一个任务,直到该任务处理完,即返回后引擎接着运行下一个任务,在任务没返回前队列中的其它任务是没法被执行的.</p>
<p>相信您现在已经很清楚JavaScript是否可多线程,也了解理解JavaScript定时器运行机制了,下面我们来对一些案例进行分析:</p>
<p>案例1:setTimeout与setInterval</p>
<pre class="sh_javascript"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
setTimeout(function() {
        /* 代码块... */
        setTimeout(arguments.callee, 10);
}, 10);

setInterval(function(){
        /*代码块... */
}, 10);
</pre>
<p>这两段代码看一起效果一样,其实非也,第一段中回调函数内的setTimeout是JavaScript引擎执行后再设置新的setTimeout定时, 假定上一个回调处理完到下一个回调开始处理为一个时间间隔,理论两个setTimeout回调执行时间间隔>=10ms .第二段自setInterval设置定时后,定时触发线程就会源源不断的每隔十秒产生异步定时事件并放到任务队列尾,理论上两个setInterval回调执行时间间隔<=10.</p>
<p>案例2:ajax异步请求是否真的异步?</p>
<p>很多同学朋友搞不清楚,既然说JavaScript是单线程运行的,那么XMLHttpRequest在连接后是否真的异步?<br/>
其实请求确实是异步的,不过这请求是由浏览器新开一个线程请求(参见上图),当请求的状态变更时,如果先前已设置回调,这异步线程就产生状态变更事件放到JavaScript引擎的处理队列中等待处理,当任务被处理时,JavaScript引擎始终是单线程运行回调函数,具体点即还是单线程运行onreadystatechange所设置的函数.<script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_javascript.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_javascript.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_javascript.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_javascript.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2009/09/23</a>, <a href="http://hqlong.com"  rel="external nofollow"  class="url" >hqlong</a> writes: 分析问题很有深度，似乎是你的风格。</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2009/09/24</a>, silasoni writes: 博主分析问题很有深度是没错
不过这篇是转贴的呀</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2009/09/29</a>, aaaaaa writes: 很多是转载的，不过博主整理知识还是很认真的</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2009/09/29</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: :), 
如果遇到好的文章, 我会认真读完以后, 如果觉得很有保留价值, 我会转载, 转载会注明转载, 划在转载分类中. 表明转载地址. 
没有以上的, 都是原创..</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2010/09/07</a>, 小豪_Scorpio writes: 不错，问题讲的有深度。俺就从你这里转了。</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2011/01/05</a>, <a href="http://www.skygq.com"  rel="external nofollow"  class="url" >Jquery教程</a> writes: 博主很厉害呀~从两个javascript函数就可以分析出来这么多道理来~~佩服呀~~</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2011/02/18</a>, <a href="http://idamag.com/blog"  rel="external nofollow"  class="url" >idamag</a> writes: 分析的很深刻！</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2011/03/28</a>, winting writes: div.onclick = function(){
        setTimeout(function() {
             document.getElementById('inputField').focus();
        }, 0);
};

大侠你好， 请教一下。
 document.getElementById('inputField').focus();
这个会不会产生一个GUI事件触发线程，写到某个时间段。
（对于JavaScript引擎线程来说,这事件是由其它线程异步传到任务队列尾的,由于引擎正在处理t1时的任务,这个鼠标点击事件正在等待处理。）
是的话，就不用setTimeout。
有点迷糊。</li><li><a href="http://www.laruence.com/2009/09/23/1089.html" >2011/06/01</a>, 周某某4 writes: 这个是不是可以这样理解，setTimeout是在整个脚本执行完后，再执行回调函数</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/09/08/1076.html"  rel="bookmark"  title="Permanent Link: 深入理解Javascript之this关键字" >深入理解Javascript之this关键字</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Related Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/03/29/1949.html"  title="深入理解PHP原理之Session Gc的一个小概率Notice" >深入理解PHP原理之Session Gc的一个小概率Notice</a></li><li><a href="http://www.laruence.com/2010/05/18/1482.html"  title="深入理解PHP原理之对象(一)" >深入理解PHP原理之对象(一)</a></li><li><a href="http://www.laruence.com/2010/05/13/1462.html"  title="Javascript原型链和原型的一个误区" >Javascript原型链和原型的一个误区</a></li><li><a href="http://www.laruence.com/2010/01/21/1254.html"  title="IE下var的重要性的又一佐证" >IE下var的重要性的又一佐证</a></li><li><a href="http://www.laruence.com/2009/09/27/1123.html"  title="关于Javascript的俩个有趣的探讨" >关于Javascript的俩个有趣的探讨</a></li><li><a href="http://www.laruence.com/2009/09/08/1076.html"  title="深入理解Javascript之this关键字" >深入理解Javascript之this关键字</a></li><li><a href="http://www.laruence.com/2009/08/09/1036.html"  title="正确使用JS中的正则" >正确使用JS中的正则</a></li><li><a href="http://www.laruence.com/2009/05/28/863.html"  title="Javascript作用域原理" >Javascript作用域原理</a></li><li><a href="http://www.laruence.com/2009/05/18/809.html"  title="使用JS做文档处理" >使用JS做文档处理</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2009/09/23/1089.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>CSS让你的IE浏览器崩溃(Crash your IE)</title>
		<link>http://www.laruence.com/2009/09/14/1081.html</link>
		<comments>http://www.laruence.com/2009/09/14/1081.html#comments</comments>
		<pubDate>Mon, 14 Sep 2009 09:41:07 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[Js/CSS]]></category>
		<category><![CDATA[转载]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1081</guid>
		<description><![CDATA[ <p>严格来说不单是CSS就能令IE浏览器崩溃(crash)，而要配合相应的XHTML架构。到现时为止发现有两种正常写法及一种错误结构分别导致会IE6、IE7崩溃(crash)，至于原因我尝试寻找过答案但至今还没找到…如你有这方面的认识或更详细的资料很希望你能分享！
</p>]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2009/09/14/1081.html"  title="Permanet Link to CSS让你的IE浏览器崩溃(Crash your IE)" >http://www.laruence.com/2009/09/14/1081.html</a></li>
<li>转载文章</li>
</ul></div>
<p>严格来说不单是CSS就能令IE浏览器崩溃(crash)，而要配合相应的XHTML架构。到现时为止发现有两种正常写法及一种错误结构分别导致会IE6、IE7崩溃(crash)，至于原因我尝试寻找过答案但至今还没找到…如你有这方面的认识或更详细的资料很希望你能分享！
</p>
<h3>1 crash IE6 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie6.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie6.html</a></p>
<p>此BUG只存在IE6中,当伪类为 a:active 时同样会遇到此问题</p>
<pre class="sh_css"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
a{position:relative;}
a:hover{float:left;}
</pre>
<p><strong>解决方案：</strong>为 &lt;a&gt; 添加 zoom:1; 令其触发haslayout </p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
a{position:relative;zoom:1;}
a:hover{float:left;}
</pre>
<h3>2 crash IE6 code</h3>
<p>这是HTML结构错误而导致IE6的崩溃,在&lt;col width=&#8221;100&#8243;/&gt;前或后添加任何字符均会导致IE6 Crash</p>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/HTML_errors_crash_ie6.html"  target="_blank" >http://blog.gulu77.com/demo/200808/HTML_errors_crash_ie6.html</a></p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;table style=&quot;table-layout:fixed;&quot;&gt;
&lt;colgroup&gt;
&lt;col width=&quot;100&quot;/&gt;Crash IE6
&lt;/colgroup&gt;
&lt;/table&gt;
</pre>
<h3>3 crash IE7 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie7.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie7.html</a></p>
<p>Bug from <a href="http://www.tommyfan.com"  title="TommyFan" >偷米饭</a>，此bug只存在IE7中据估计是处理省略字的时候导致IE7崩溃.</p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">&lt;style type=&quot;text/css&quot;&gt;
div{float:left;width:175px;}
ul{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
li{position:relative;}
&lt;/style&gt;

&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;崩溃崩溃崩溃崩溃崩溃crash ie7&lt;/li&gt;
&lt;li&gt;崩溃崩溃崩溃崩溃崩溃crash ie7&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;</pre>
<p><strong>解决方案：</strong>为
<li> 添加 zoom:1; 令其触发haslayout</p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">&lt;style type=&quot;text/css&quot;&gt;
div{float:left;width:175px;}
ul{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}
li{position:relative;zoom:1;}
&lt;/style&gt;</pre>
<h3>4 crash IE6 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie6_test1.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie6_test1.html</a></p>
<p>当再次改变定位时浏览器崩溃，但似乎也需要N个帮凶才会导致崩溃的代码中CSS table的相属性都缺一不可。</p>
<pre name="code"  class="sh_html"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
  	&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
  	&lt;head&gt;
  	&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
  	&lt;title&gt;CRASH-IE,CSS让你的IE浏览器崩溃&lt;/title&gt;
	&lt;style type=&quot;text/css&quot;&gt;
  	html, body {overflow: hidden;scrollbar-base-color: #330066;}
  	.crash {position:absolute;left:200px;top:200px;width:200px;}
	&lt;/style&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
  	function galgenfrist() {
  	window.setTimeout('crashIE();',1000);
  	}

 function crashIE() {
  	var moveNode = document.getElementById(&quot;move&quot;);
  	if(moveNode) {
  	moveNode.style.top = &quot;100px&quot;;
  	moveNode.style.left = &quot;200px&quot;;
  	}
  	}
	&lt;/script&gt;
	&lt;/head&gt;

&lt;body onload=&quot;galgenfrist();&quot;&gt;
	&lt;h1&gt;CRASH-IE&lt;/h1&gt;
	&lt;div id=&quot;move&quot; class=&quot;crash&quot;&gt;
	&lt;table&gt;
	&lt;tbody&gt;
	&lt;tr&gt;
	&lt;td&gt;
	&lt;textarea&gt;&lt;/textarea&gt;
	&lt;/td&gt;
	&lt;/tr&gt;
	&lt;/tbody&gt;
	&lt;/table&gt;
	&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<h3>5 crash IE6 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie6_test2.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie6_test2.html</a></p>
<p>具体引起的原因暂时无法解析，但在兼容性和执行效率来看一般不会采取这样的写法。</p>
<pre name="code"  class="sh_javascript"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;script&gt;
	for (x in document.write) {
		document.write(x);}
&lt;/script&gt;
</pre>
<h3>6 crash IE6 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie6_test3.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie6_test3.html</a></p>
<p>传说是一名日本人发现的，table中直接放置内容，在IE6会引起Mshtml.all模块损坏而关闭浏览器，非IE6则安全无恙。</p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;style&gt;
	* {position:relative}
&lt;/style&gt;
&lt;table&gt;
	&lt;input&gt;
&lt;/table&gt;
</pre>
<h3>7 crash IE6 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie6_test4.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie6_test4.html</a></p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;body onLoad=”window()”&gt;
</pre>
<h3>8 crash IE6 code</h3>
<p>Demo:<a href="http://blog.gulu77.com/demo/200808/crash_ie6_test5.html"  target="_blank" >http://blog.gulu77.com/demo/200808/crash_ie6_test5.html</a></p>
<p>CSS中出现@+任意字符+/* 立即崩溃。</p>
<pre name="code"  class="sh_css"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
&lt;style&gt;
	@;/*
&lt;/style&gt;
</pre>
<p> 原文地址:<a href="http://blog.gulu77.com/?p=59" >http://blog.gulu77.com/?p=59</p>
<p><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_html.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_javascript.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_css.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/09/14</a>, Edward writes: IE7以前的浏览器是有好多的问题～而且IE有自己的一套标准，根本不去理会什么W3C。

但是IE8好多了哦～

但是悲剧的是，还有绝大部分的用户在使用IE6.应为windows内置的就是IE6.而且大家除了浏览网页以外，基本上没所有什么其他的需求。所以，很少有人去更换自己的浏览器，对web开发来说，这个也算是让人小小头痛的事情吧！</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/09/16</a>, 5455 writes: 您好：
   PHP Pallas CMS的数据库 我找不到在哪里？ 想学习学习php。可以发数据库给我吗？
      谢谢</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/09/16</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: sql文件在包里有.pscms_admin/tables.sql</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/09/18</a>, <a href="http://www.xidea.org"  rel="external nofollow"  class="url" >jindw</a> writes: 不错，呵呵。</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/09/19</a>, toms writes: 大侠能不能说下这个是怎么回事阿

class base
{
    public function run($module, $params)
    {
        $this-&gt;{$module}($params);
    }
}

class sub extends base
{
    public functin show()
    {
        $this-&gt;run('module_news', $params);
    }
    
    public function module_news($params)
    {
    }
}

我看见joomla里的代码有这样的写法， 但joomla是php4的写法， 为什么module_news为public的时候才能被调用呢？</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/09/25</a>, fybird writes: 赞！</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/10/09</a>, berger writes: 以前也遇到过一次css crash，让人郁闷了快一天，当时遇到的问题是，编码写的太不规范，自觉着，要是规范点使用标签，会好点</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2009/11/26</a>, <a href="http://www.sn00py.cn"  rel="external nofollow"  class="url" >samuel</a> writes: 全都是IE的，还是FIREFOX好啊</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2010/03/18</a>, <a href="http://www.lowest-rate-loans.com"  rel="external nofollow"  class="url" >SAUNDERSSANDY</a> writes: When you are in not good state and have no money to go out from that, you would require to take the <a href="http://lowest-rate-loans.com/topics/personal-loans"  rel="nofollow" >personal loans</a>. Just because that should aid you unquestionably. I take bank loan every single year and feel myself fine because of this.</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2010/05/26</a>, <a href="http://www.js4j.com"  rel="external nofollow"  class="url" >技术门户网站</a> writes: windows7内置的是IE8</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2011/08/19</a>, <a href="http://hiheng.com/blog"  rel="external nofollow"  class="url" >hiheng</a> writes: 真是万能的zoom:1,哈哈。</li><li><a href="http://www.laruence.com/2009/09/14/1081.html" >2011/11/14</a>, <a href="http://qitiancom.com"  rel="external nofollow"  class="url" >朱宝祥</a> writes: 真实神奇的bug。学习了，标记一下，以后学耍酷来这里。哈</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/05/04/1450.html"  title="深入理解PHP之require/include顺序" >深入理解PHP之require/include顺序</a></li><li><a href="http://www.laruence.com/2009/11/27/1164.html"  title="memory_limit的一个bug" >memory_limit的一个bug</a></li><li><a href="http://www.laruence.com/2009/04/21/680.html"  title="phpDocumentor" >phpDocumentor</a></li><li><a href="http://www.laruence.com/2009/05/10/786.html"  title="东方时尚约车脚本(greaseMoney)" >东方时尚约车脚本(greaseMoney)</a></li><li><a href="http://www.laruence.com/2009/07/19/1003.html"  title="使用gettext来支持PHP的多语言" >使用gettext来支持PHP的多语言</a></li><li><a href="http://www.laruence.com/2008/08/24/427.html"  title="PHP5多层继承顺序的bug" >PHP5多层继承顺序的bug</a></li><li><a href="http://www.laruence.com/2010/12/14/1816.html"  title="Compilation failed: support for \P, \p, and \X has not been compiled" >Compilation failed: support for \P, \p, and \X has not been compiled</a></li><li><a href="http://www.laruence.com/2010/04/15/1414.html"  title="深入理解ob_flush和flush的区别" >深入理解ob_flush和flush的区别</a></li><li><a href="http://www.laruence.com/2008/09/23/539.html"  title="使用PHP Embed SAPI实现Opcodes查看器" >使用PHP Embed SAPI实现Opcodes查看器</a></li><li><a href="http://www.laruence.com/2008/08/17/313.html"  title="PHP的老式语法" >PHP的老式语法</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2009/09/14/1081.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>字符编码详解(基础)</title>
		<link>http://www.laruence.com/2009/08/22/1059.html</link>
		<comments>http://www.laruence.com/2009/08/22/1059.html#comments</comments>
		<pubDate>Sat, 22 Aug 2009 03:40:53 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[转载]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[字符编码]]></category>
		<category><![CDATA[字符集，编码集]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=1059</guid>
		<description><![CDATA[字符编码问题, 对于一个在伟大天朝的程序员来说, 几乎不可能遇不到, 从我刚开始接触Coding到现在, 乱码, 编码转换问题就好像一直没有停息过.
   
从最初的数据库到客户端乱码,到后来不同浏览器Url编码习惯不同,再到服务器和脚本编码不同的问题等等.
   
   朋友一直希望我能写一篇关于编码的文章,  但无奈面太广, 设计到的问题多, 所以也一直写不出来.

   不过, 作为基础, 大家先看看这篇文章吧:《字符编码详解》...]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>本文地址: <a href="http://www.laruence.com/2009/08/22/1059.html"  title="Permanet Link to 字符编码详解(基础)" >http://www.laruence.com/2009/08/22/1059.html</a></li>
<li>转载文章</li>
</ul></div>
<p>
   字符编码问题, 对于一个在伟大天朝的程序员来说, 几乎不可能遇不到, 从我刚开始接触Coding到现在, 乱码, 编码转换问题就好像一直没有停息过.</p>
<p>   从最初的数据库到客户端乱码,到后来不同浏览器Url编码习惯不同,再到服务器和脚本编码不同的问题等等.</p>
<p>   朋友一直希望我能写一篇关于编码的文章,  但无奈面太广, 设计到的问题多, 所以也一直写不出来.</p>
<p>   不过, 作为基础, 大家先看看这篇文章吧<a href="http://blog.csdn.net/stilling2006/archive/2009/04/27/4129700.aspx"  target="_blank" >《字符编码详解》</a>:</p>
<hr/></hr>
<p>   很久很久以前，有一群人，他们决定用8个可以开合的晶体管来组合成不同的状态，以表示世界上的万物。他们看到8个开关状态是好的，于是他们把这称为&#8221;字节&#8221;。</p>
<p>  再后来，他们又做了一些可以处理这些字节的机器，机器开动了，可以用字节来组合出很多状态，状态开始变来变去。他们看到这样是好的，于是它们就这机器称为&#8221;计算机&#8221;。</p>
<p>  开始计算机只在美国用。八位的字节一共可以组合出256(2的8次方)种不同的状态。</p>
<p>	他们把其中的编号从0开始的32种状态分别规定了特殊的用途，一但终端、打印机遇上约定好的这些字节被传过来时，就要做一些约定的动作。遇上00&#215;10, 终端就换行，遇上0&#215;07, 终端就向人们嘟嘟叫，例如遇上0x1b, 打印机就打印反白的字，或者终端就用彩色显示字母。他们看到这样很好，于是就把这些0&#215;20以下的字节状态称为&#8221;控制码&#8221;．</p>
<p>	他们又把所有的空格、标点符号、数字、大小写字母分别用连续的字节状态表示，一直编到了第127号，这样计算机就可以用不同字节来存储英语的文字了。大家 看到这样，都感觉很好，于是大家都把这个方案叫做 ANSI 的&#8221;Ascii&#8221;编码（American Standard Code for Information Interchange，美国信息互换标准代码）。当时世界上所有的计算机都用同样的ASCII方案来保存英文文字。</p>
<p>	后来，就像建造巴比伦塔一样，世界各地的都开始使用计算机，但是很多国家用的不是英文，他们的字母里有许多是ASCII里没有的，为了可以在计算机保存他 们的文字，他们决定采用127号之后的空位来表示这些新的字母、符号，还加入了很多画表格时需要用下到的横线、竖线、交叉等形状，一直把序号编到了最后一 个状态255。从128到255这一页的字符集被称&#8221;扩展字符集&#8221;。从此之后，贪婪的人类再没有新的状态可以用了，美帝国主义可能没有想到还有第三世界国 家的人们也希望可以用到计算机吧！</p>
<p>  等中国人们得到计算机时，已经没有可以利用的字节状态来表示汉字，况且有6000多个常用汉字需要保存呢。但是这难不倒智慧的中国人民，我们不客气地把那些127号之后的奇异符号们直接取消掉,</p>
<p>  规定：一个小于127的字符的意义与原来相同，但两个大于127的字符连在一起时，就表示一个汉字，前面的一个字节（他称之为高字节）从0xA1用到 0xF7，后面一个字节（低字节）从0xA1到0xFE，这样我们就可以组合出大约7000多个简体汉字了。在这些编码里，我们还把数学符号、罗马希腊的 字母、日文的假名们都编进去了，连在 ASCII 里本来就有的数字、标点、字母都统统重新编了两个字节长的编码，这就是常说的&#8221;全角&#8221;字符，而原来在127号以下的那些就叫&#8221;半角&#8221;字符了。</p>
<p>  中国人民看到这样很不错，于是就把这种汉字方案叫做 &#8220;GB2312&#8243;。GB2312 是对 ASCII 的中文扩展．</p>
<p>  但是中国的汉字太多了，我们很快就就发现有许多人的人名没有办法在这里打出来，特别是某些很会麻烦别人的国家领导人。于是我们不得不继续把 GB2312 没有用到的码位找出来老实不客气地用上。</p>
<p>  后来还是不够用，于是干脆不再要求低字节一定是127号之后的内码，只要第一个字节是大于127就固定表示这是一个汉字的开始，不管后面跟的是不是扩展字 符集里的内容。结果扩展之后的编码方案被称为 GBK 标准，GBK 包括了 GB2312 的所有内容，同时又增加了近20000个新的汉字（包括繁体字）和符号。</p>
<p>  后来少数民族也要用电脑了，于是我们再扩展，又加了几千个新的少数民族的字，GBK 扩成了GB18030。从此之后，中华民族的文化就可以在计算机时代中传承了。</p>
<p>  中国的程序员们看到这一系列汉字编码的标准是好的，于是通称他们叫做 &#8220;DBCS&#8221;（Double Byte Charecter Set 双字节字符集）。在DBCS系列标准里，最大的特点是两字节长的汉字字符和一字节长的英文字符并存于同一套编码方案里，因此他们写的程序为了支持中文处 理，必须要注意字串里的每一个字节的值，如果这个值是大于127的，那么就认为一个双字节字符集里的字符出现了。那时候凡是受过加持，会编程的计算机僧侣 们都要每天念下面这个咒语数百遍：</p>
<p>  &#8220;一个汉字算两个英文字符！一个汉字算两个英文字符……&#8221;</p>
<p>  因为当时各个国家都像中国这样搞出一套自己的编码标准，结果互相之间谁也不懂谁的编码，谁也不支持别人的编码，连大陆和台湾这样只相隔了150海里，使用 着同一种语言的兄弟地区，也分别采用了不同的 DBCS 编码方案——当时的中国人想让电脑显示汉字，就必须装上一个&#8221;汉字系统&#8221;，专门用来处理汉字的显示、输入的问题，但是那个台湾的愚昧封建人士写的算命程序 就必须加装另一套支持 BIG5  编码的什么&#8221;倚天汉字系统&#8221;才可以用，装错了字符系统，显示就会乱了套！这怎么办？而且世界民族之林中还有那些一时用不上电脑的穷苦人民，他们的文字又怎 么办？</p>
<p>  真是计算机的巴比伦塔命题啊！</p>
<p>  正在这时，大天使加百列及时出现了——一个叫 ISO（国际标谁化组织）的国际组织决定着手解决这个问题。他们采用的方法很简单：废了所有的地区性编码方案，重新搞一个包括了地球上所有文化、所有字母 和符号的编码！他们打算叫它&#8221;Universal Multiple-Octet Coded Character Set&#8221;，简称 UCS, 俗称 &#8220;UNICODE&#8221;。</p>
<p>  UNICODE 开始制订时，计算机的存储器容量极大地发展了，空间再也不成为问题了。于是 ISO 就直接规定必须用两个字节，也就是16位来统一表示所有的字符，对于ascii里的那些“半角”字符，UNICODE 包持其原编码不变，只是将其长度由原来的8位扩展为16位，而其他文化和语言的字符则全部重新统一编码。由于&#8221;半角&#8221;英文符号只需要用到低8位，所以其高 8位永远是0，因此这种大气的方案在保存英文文本时会多浪费一倍的空间。</p>
<p>  这时候，从旧社会里走过来的程序员开始发现一个奇怪的现象：他们的strlen函数靠不住了，一个汉字不再是相当于两个字符了，而是一个！是的，从 UNICODE 开始，无论是半角的英文字母，还是全角的汉字，它们都是统一的&#8221;一个字符&#8221;！同时，也都是统一的&#8221;两个字节&#8221;，请注意&#8221;字符&#8221;和&#8221;字节&#8221;两个术语的不 同，“字节”是一个8位的物理存贮单元，而“字符”则是一个文化相关的符号。在UNICODE 中，一个字符就是两个字节。一个汉字算两个英文字符的时代已经快过去了。</p>
<p>  从前多种字符集存在时，那些做多语言软件的公司遇上过很大麻烦，他们为了在不同的国家销售同一套软件，就不得不在区域化软件时也加持那个双字节字符集咒 语，不仅要处处小心不要搞错，还要把软件中的文字在不同的字符集中转来转去。UNICODE 对于他们来说是一个很好的一揽子解决方案，于是从 Windows NT 开始，MS 趁机把它们的操作系统改了一遍，把所有的核心代码都改成了用 UNICODE 方式工作的版本，从这时开始，WINDOWS 系统终于无需要加装各种本土语言系统，就可以显示全世界上所有文化的字符了。</p>
<p>  但是，UNICODE 在制订时没有考虑与任何一种现有的编码方案保持兼容，这使得 GBK 与UNICODE 在汉字的内码编排上完全是不一样的，没有一种简单的算术方法可以把文本内容从UNICODE编码和另一种编码进行转换，这种转换必须通过查表来进行。</p>
<p>  如前所述，UNICODE 是用两个字节来表示为一个字符，他总共可以组合出65535不同的字符，这大概已经可以覆盖世界上所有文化的符号。如果还不够也没有关系，ISO已经准备 了UCS-4方案，说简单了就是四个字节来表示一个字符，这样我们就可以组合出21亿个不同的字符出来（最高位有其他用途），这大概可以用到银河联邦成立 那一天吧！</p>
<p>  UNICODE 来到时，一起到来的还有计算机网络的兴起，UNICODE 如何在网络上传输也是一个必须考虑的问题，于是面向传输的众多 UTF（UCS Transfer Format）标准出现了，顾名思义，UTF8就是每次8个位传输数据，而UTF16就是每次16个位，只不过为了传输时的可靠性，从UNICODE到 UTF时并不是直接的对应，而是要过一些算法和规则来转换。</p>
<p>  受到过网络编程加持的计算机僧侣们都知道，在网络里传递信息时有一个很重要的问题，就是对于数据高低位的解读方式，一些计算机是采用低位先发送的方法，例 如我们PC机采用的 INTEL 架构，而另一些是采用高位先发送的方式，在网络中交换数据时，为了核对双方对于高低位的认识是否是一致的，采用了一种很简便的方法，就是在文本流的开始时 向对方发送一个标志符——如果之后的文本是高位在位，那就发送&#8221;FEFF&#8221;，反之，则发送&#8221;FFFE&#8221;。不信你可以用二进制方式打开一个UTF-X格式的 文件，看看开头两个字节是不是这两个字节？</p>
<p>  讲到这里，我们再顺便说说一个很著名的奇怪现象：当你在 windows 的记事本里新建一个文件，输入&#8221;联通&#8221;两个字之后，保存，关闭，然后再次打开，你会发现这两个字已经消失了，代之的是几个乱码！呵呵，有人说这就是联通之所以拼不过移动的原因。</p>
<p>  其实这是因为GB2312编码与UTF8编码产生了编码冲撞的原因。</p>
<p>  从网上引来一段从UNICODE到UTF8的转换规则：</p>
<pre name="code"  class="sh_shell"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
Unicode
UTF-8
0000 - 007F
0xxxxxxx
0080 - 07FF
110xxxxx 10xxxxxx
0800 - FFFF
1110xxxx 10xxxxxx 10xxxxxx
</pre>
<p>    例如&#8221;汉&#8221;字的Unicode编码是6C49。6C49在0800-FFFF之间，所以要用3字节模板：1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是：0110 1100 0100 1001，将这个比特流按三字节模板的分段方法分为0110 110001 001001，依次代替模板中的x，得到：1110-0110 10-110001 10-001001，即E6 B1 89，这就是其UTF8的编码。 </p>
<p>    而当你新建一个文本文件时，记事本的编码默认是ANSI,如果你在ANSI的编码输入汉字，那么他实际就是GB系列的编码方式，在这种编码下，&#8221;联通&#8221;的内码是： </p>
<pre name="code"  class="sh_shell"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
c1 1100 0001
aa 1010 1010
cd 1100 1101
a8 1010 1000
</pre>
<p>    注意到了吗？第一二个字节、第三四个字节的起始部分的都是&#8221;110&#8243;和&#8221;10&#8243;，正好与UTF8规则里的两字节模板是一致的，于是再次打开记事本时，记事 本就误认为这是一个UTF8编码的文件，让我们把第一个字节的110和第二个字节的10去掉，我们就得到了&#8221;00001 101010&#8243;，再把各位对齐，补上前导的0，就得到了&#8221;0000 0000 0110 1010&#8243;，不好意思，这是UNICODE的006A，也就是小写的字母&#8221;j&#8221;，而之后的两字节用UTF8解码之后是0368，这个字符什么也不是。这就 是只有&#8221;联通&#8221;两个字的文件没有办法在记事本里正常显示的原因。</p>
<p>    而如果你在&#8221;联通&#8221;之后多输入几个字，其他的字的编码不见得又恰好是110和10开始的字节，这样再次打开时，记事本就不会坚持这是一个utf8编码的文件，而会用ANSI的方式解读之，这时乱码又不出现了。</p>
<p>    好了，终于可以回答NICO的问题了，在数据库里，有n前缀的字串类型就是UNICODE类型，这种类型中，固定用两个字节来表示一个字符，无论这个字符是汉字还是英文字母，或是别的什么。</p>
<p>    如果你要测试&#8221;abc汉字&#8221;这个串的长度，在没有n前缀的数据类型里，这个字串是7个字符的长度，因为一个汉字相当于两个字符。而在有n前缀的数据类型里，同样的测试串长度的函数将会告诉你是5个字符，因为一个汉字就是一个字符。</p>
<hr/>
<p>   原文地址:http://blog.csdn.net/stilling2006/archive/2009/04/27/4129700.aspx</p>
<p><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_shell.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_shell.js" ></script></p>
<hr/><h2>Comments</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2009/08/24</a>, pangyongtao writes: http://www.joelonsoftware.com/articles/Unicode.html</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2009/08/24</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @pangyongtao 有不少我没有涉及到的知识点,好文.</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2009/08/28</a>, Jessica writes: 记事本里面写一个 "联通" 是不是就是这原因</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2009/08/28</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @jessica 是阿....有说的</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2009/09/14</a>, Edward writes: 那么可以这样说了，Unicode是编码方式，而utf8只是一种数据传输的方式……

%￥#@&amp;*我发现我太白痴了，我居然以为utf8是编码方式……看来还需要学习！</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2009/09/21</a>, <a href="http://blog.csdn.net/yycai"  rel="external nofollow"  class="url" >小蔡</a> writes: 原来utf-8只是一种数据传输方式。。。</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2010/01/28</a>, sam.huang writes: 很久之前研究过这些东西，希望与lz交流...</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2011/05/05</a>, <a href="http://www.am82.com/houzan/archives/5669/"  rel="external nofollow"  class="url" >字符集和字符编码（Charset &amp; Encoding） &laquo; 葡萄树 On The Road</a> writes: [...] Laruence. 字符编码详解(基础). http://www.laruence.com/2009/08/22/1059.html, [...]</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2011/05/22</a>, <a href="http://unknownerror.net/2011-05/discuss-2-character-coding-24737"  rel="external nofollow"  class="url" >Discuss (2) character coding</a> writes: [...] 3)http://www.laruence.com/2009/08/22/1059.html ,Using an easy way to tell the development history of the code. [...]</li><li><a href="http://www.laruence.com/2009/08/22/1059.html" >2011/11/05</a>, <a href="http://www.owd.cc/?p=919"  rel="external nofollow"  class="url" >常见字符编码分析 | 嵌入式系统世界</a> writes: [...] Unicode. http://zh.wikipedia.org/wiki/Unicode, 2011-4-30 8.Laruence. 字符编码详解(基础). http://www.laruence.com/2009/08/22/1059.html, 2009-8-22 9.Jan Hunt. Character Sets and Encoding for Web Designers &#8211; UCS/UNICODE. [...]</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2010/12/14/1816.html"  title="Compilation failed: support for \P, \p, and \X has not been compiled" >Compilation failed: support for \P, \p, and \X has not been compiled</a></li><li><a href="http://www.laruence.com/2008/01/05/12.html"  title="深入Mysql字符集设置" >深入Mysql字符集设置</a></li><li><a href="http://www.laruence.com/2009/05/17/815.html"  title="关于事件模拟" >关于事件模拟</a></li><li><a href="http://www.laruence.com/2011/01/27/1854.html"  title="深入理解PHP内存管理之一个低概率Core的分析" >深入理解PHP内存管理之一个低概率Core的分析</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2009/09/26/1103.html"  title="PHP文件上传源码分析(RFC1867)" >PHP文件上传源码分析(RFC1867)</a></li><li><a href="http://www.laruence.com/2010/04/21/1442.html"  title="Le Putty &#8211; Putty with Zmodem" >Le Putty &#8211; Putty with Zmodem</a></li><li><a href="http://www.laruence.com/2011/06/23/2057.html"  title="如何调试PHP的Core之获取基本信息" >如何调试PHP的Core之获取基本信息</a></li><li><a href="http://www.laruence.com/2008/04/18/104.html"  title=" C++判断本机的字节序的方法" > C++判断本机的字节序的方法</a></li><li><a href="http://www.laruence.com/2008/08/19/338.html"  title="PHP的单引号和双引号" >PHP的单引号和双引号</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2009/08/22/1059.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

