<?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>风雪之隅</title>
	<atom:link href="http://www.laruence.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.laruence.com</link>
	<description>PHP语言, PHP扩展, Zend引擎相关的研究,技术,新闻分享 - 左手代码 右手诗</description>
	<lastBuildDate>Thu, 02 Feb 2012 03:59:23 +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>我们什么时候应该使用异常?</title>
		<link>http://www.laruence.com/2012/02/02/2515.html</link>
		<comments>http://www.laruence.com/2012/02/02/2515.html#comments</comments>
		<pubDate>Thu, 02 Feb 2012 03:36:06 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[exception]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[status code]]></category>
		<category><![CDATA[异常]]></category>
		<category><![CDATA[状态码]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2515</guid>
		<description><![CDATA[先说个题外话: 在公司做了俩件事, 是我觉得很有意义的, 第一就是成立了一个PHP邮件组, 第二就是成立了一个Hi群. 目前俩者都有超过500 phpers在里面.  我一直认为, 构建一个交流平台, 让同学们能顺畅, 简单的沟通, 是营造积极的技术学习氛围的基础和前提. 让每个人的问题不会成为别人的问题, 则是最直接的利益.
 
   昨天, 有同事在邮件组提了个问题:
<blockquote>
PHP应该什么时候使用 Exception ？ 它的性能如何？
</blockquote>

  这个问题也算是一个久经争论的经典问题了.  我谈谈我的个人看法.
]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2012/02/02/2515.html"  title="Permanet Link to 我们什么时候应该使用异常?" >http://www.laruence.com/2012/02/02/2515.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   先说个题外话: 在公司做了俩件事, 是我觉得很有意义的, 第一就是成立了一个PHP邮件组, 第二就是成立了一个Hi群. 目前俩者都有超过500 phpers在里面.  我一直认为, 构建一个交流平台, 让同学们能顺畅, 简单的沟通, 是营造积极的技术学习氛围的基础和前提. 让每个人的问题不会成为别人的问题, 则是最直接的利益.</p>
<p>   昨天, 有同事在邮件组提了个问题:</p>
<blockquote><p>
PHP应该什么时候使用 Exception ？ 它的性能如何？
</p></blockquote>
<p>  这个问题也算是一个久经争论的经典问题了.  我谈谈我的个人看法.</p>
<p>  异常与之对应的错误码(或者状态码),  到底各自有什么优点, 缺点, 我们应该怎么使用呢? </p>
<h3>错误码</h3>
<p>  首先来说, 异常机制是在错误码机制之后才出现的, 那么根据进化论, 异常自然是避免了错误码机制的一些不足. 这些不足包括.</p>
<h4>1. 错误信息不丰富</h4>
<p>   函数, 只能有一个返回值(当然, Lua可以返回多个, 但其实也相当于在PHP中返回一个数组),  我们见过最多的函数说明就是: 成功时候返回***, 错误的时候返回FALSE, 然而一个函数出错我原因可能有多种, 出错的种类更有多种. 一个简单的FALSE, 并不能把具体的错误信息告诉调用者. </p>
<p>   于是, 我们也就见过一些, 这样的函数说明: 如果返回值大于0, 则表示成功的状态码,  如果返回值小于0, 则表示出错的状态码. </p>
<p>   然而, 这个要求函数是返回整形(或者数字),  对于一些其他函数, 我们并不能通过0, >0,  <0来判别, 并且, 即使通过这样的方式, 我们还需要用返回的错误码和一些预定义宏(或者调用类似strerror())来获取具体的, 可读的错误信息.</p>
<p>   于是, 就有一些函数使用全局的错误码, 和错误信息, 来保存具体的错误信息, 这个时候我们就看到这样的函数描述: 成功返回***, 出错的时候返回FALSE, 错误代码保存在全局变量$errno中(至少大多数Linux库函数是这样描述的, 呵呵).</p>
<p>   Okey, 这样的方式确实可以工作, 但是, 是不是觉得, 很丑陋呢?</p>
<h4>2. 加入错误状态码可能需要改变函数签名</h4>
<p>   假设, 你编写了一个函数,  这个函数很简单, 很简单, 你认为他绝对不会出错, 于是你申明为(用C语言为例, PHP没有返回类型提示):</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;">
void dummy() {
}
</pre>
<p>  但是后来你慢慢修改了这个函数, 给了它更多的功能, 此时这个函数可能会失败了. 而你现在根本无法为这个函数, 加入错误返回码了.  </p>
<p>  也许有人说PHP没有返回值类型限制一说, 但是想想PHP的构造函数, 构造函数是没有返回值的, 当发生错误的时候, 如果你不使用异常, 我想你只能选择die, 或者使用2中的方法来错误继续执行了.</p>
<p>  另外, 在一个良好的软件系统中, 返回类型其实也是约定俗成的,  当所有的使用的函数的地方, 都没有检查返回值的时候, 你还是无法为这个函数加入错误返回码.</p>
<h4>3. 错误状态码可能会被忽略</h4>
<p>   当你的一个函数, 出错了, 返回了错误状态码, 而调用方并没有检测这个返回值,  会发生什么情况呢?  -_#.   令一方面,  处处检测返回状态码, 会造成代码非常的,,ugly:</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
  if (!call1()) {
      die();
  }

  if (call2() != SUCCESS) {
     die();
  }

  if (call3() &lt; 0) {
      $msg = error_get_last();
      die($msg[&quot;message&quot;]);
  }
</pre>
<h3>异常机制</h3>
<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
try {
   call1();
   call2();
   call3();
} catch (Exception $e) {
   die($e-&gt;getMessage());
}
</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
function myFunc() {
   call1();
   call2();
   call3();
}
</pre>
<p>   而一个异常对象, 可以包含更丰富的错误信息, 比如错误信息, 错误码, 错误的行数, 文件, 甚至出错上下文, 等等, 避免的&#8221;1.错误信息不丰富&#8221;的不足.</p>
<p>   我们也可以为一个返回void类型的函数增加异常,  而不改变他的函数签名, 也就不会有上面说的&#8221;2.加入错误状态码可能需要改变函数签名&#8221;.  对于PHP来说, 如果我们新加入的错误没有被捕捉, 也不用担心, 会明显的出错的. 也就不会发生上面所说的&#8221;3. 错误状态码可能会被忽略&#8221;的情况.</p>
<p>   然而, 也有一些反对使用异常的声音:</p>
<h4> 1. 性能</h4>
<p>    正如文章开头提问中的: &#8220;它的性能如何？&#8221;,  异常机制确实要比返回状态码的方式昂贵一些, 对于C++来说, 在异常发生的时候, 还要发生堆栈解退(对于PHP来说, 没有这个逻辑, 具体的大家可以参看我之间写的一篇文章:<a href="http://www.laruence.com/2010/08/03/1697.html" > 深入理解PHP原理之异常机制</a>). </p>
<p>    性能和方便, 往往是一个矛盾体,  我只能说, 你需要权衡,  如果你写的是一个小的模块, 并且它的生命期可能很短, 也不需要什么特殊的设计模式, 那我觉得你可以不用异常.</p>
<p>    而如果你在为一个庞大的软件做开发, 我想你更应该看重的, 应该是, 它的可扩展性, 可维护性.</p>
<h4>2. 太多可能的Uncaught Exception</h4>
<p>     如果, 你调用了一个可能发生异常的函数, 但是却没有捕获这个异常, okey, Fatal Error了,  所以让我们的代码看起来:</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
try {
} catch () {
}
....

try {
} catch () {
}
....
try {
} catch () {
}
</pre>
<p>     然而, 这个是可以经过良好设计避免的, 比如我在设计<a href="http://pecl.php.net/package/yaf" >Yaf</a>的时候, 就提供了全局异常处理, 也就是类似于, 你在最最顶层, 加上了一个try catch,  所有的异常错误逻辑都加到这个里面, 你也可以很方面的把你自己的异常加进去.  </p>
<h3>结论</h3>
<p>     经常有人批评我是俩面派,  呵呵, 但是在大家了解了上面的利弊以后, 是否也会和我一样认为: 这个事情没有定论呢? 一切从实际出发. <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> </p>
<p>     说了这么多, 算是抛砖引玉, 欢迎补充, 交流: <a href="http://www.laruence.com" >here</a> or <a href="http://weibo.com/laruence" >here</a>.<br/>
   <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_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/2012/02/02/2515.html" >2012/02/02</a>, <a href="http://www.shibeike.net"  rel="external nofollow"  class="url" >treesky</a> writes: 前排留名啊。学习。HI群有点麻烦，能不能让我们也加入邮件列表啊。</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, darasion writes: 顶。
这个问题是我问的。

多谢，看完这文章明白多了。</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, lin writes: 能不能加入邮件列表和HI群</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, benson writes: 请问，作为一个production，异常处理的使用是为了在产品发生错误的时候能更好的提示用户，或者通知开发者，是这样理解吗？</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, <a href="http://blog.chedushi.com"  rel="external nofollow"  class="url" >岭南六少</a> writes: 哈哈，现在用hi的人貌似不是很多啊</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, <a href="http://www.kaiiak.com"  rel="external nofollow"  class="url" >xiaokaizi</a> writes: class xx{
    public $box[2] = 'fds';

    public function echso() {
        // ...
    }
}  这样定义类为什么报语法错误？

在zend_language_parser.c里，变量名是不允许带[]的，估计在词法分析那一步把$box[2]分割成了一个变量名，fds是值，到语法分析这步就出错了。
如果是这样原因。问题是为什么要在类的成员变量中这样分割，而普通变量缺不呢?</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @xiaokaizi class的属性声明必须使用常数, 见:http://www.php.net/manual/en/language.oop5.properties.php 

这个常数, 同时对值, 和, 名有效. :)</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, oboodo writes: 求hi群号，惠兄！</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/02</a>, <a href="http://blankyao.com"  rel="external nofollow"  class="url" >blankyao</a> writes: 前几天遇到一个问题，类似下面的操作
stream1.close();
stream2.close();
stream3.close();
...

这几行代码都有可能抛出异常，但是抛出异常后也得保证后面的代码继续执行，所以就不能在外面搞一个try catch，所以现在是每一行都加一个tray catch，但是感觉比较ugly，有啥好的建议不？</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/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><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/2011/11/09/2277.html"  title="PHP原理之内存管理中难懂的几个点" >PHP原理之内存管理中难懂的几个点</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/02/2515.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>使用exit(-1)为什么得到255退出码?</title>
		<link>http://www.laruence.com/2012/02/01/2503.html</link>
		<comments>http://www.laruence.com/2012/02/01/2503.html#comments</comments>
		<pubDate>Wed, 01 Feb 2012 08:45:25 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[-1]]></category>
		<category><![CDATA[255]]></category>
		<category><![CDATA[exec]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[退出码]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2503</guid>
		<description><![CDATA[今天有人在<a href="http://www.weibo.com/laruence">微博</a>上问了一个问题, 使用:
<coolcode lang="php" linenum="off">
string exec ( string $command [, array &#038;$output [, int &#038;$return_var ]] )
</coolcode>
调用一个程序, 程序退出-1,  但是PHP得到的为什么是255?]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2012/02/01/2503.html"  title="Permanet Link to 使用exit(-1)为什么得到255退出码?" >http://www.laruence.com/2012/02/01/2503.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>今天有人在<a href="http://www.weibo.com/laruence" >微博</a>上问了一个问题, 使用:</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;">
string exec ( string $command [, array &amp;$output [, int &amp;$return_var ]] )
</pre>
<p>调用一个程序, 程序退出-1,  但是PHP得到的为什么是255?</p>
<p>这个问题简单的说, 是因为exit或者main函数中的return, 只能使用0~255之间的值. -1 的unsigned值就是255.</p>
<p>那么复杂点的说呢?</p>
<p>我们知道, 在Shell中,  运行一个命令, 一个程序, 都是fork一个子进程(然后exec)来执行的, 而这个程序的退出码, 被Shell(父进程), 通过wait来收集而后报告给我们的.</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;">
pid_t wait(int *statloc);
</pre>
<p>而对于wait来说, 历史上原因, 他将通过statloc返回一个16bit的interge(现在也有用32位表示的, 但是会兼容已有的设计).  这16bits的interge中, 高8位就是程序退出的值(exit, 或者return), 而低八位表示导致这个程序退出的信号(其中一位表示是否有Core文件产生), 如果程序是正常退出, 那么低八位为0<font style="size:80%" >[1]</font>.</p>
<p>所以, 如果我们返回-1,  并且因为我们是正常退出, 所以Shell通过wait收集到的子进程退出状态是:</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;">
11111111 00000000
</pre>
<p>而高八位作为unsigned, 就是255了.</p>
<p>另外, 补充一下, 在Linux的内建Shell命令中, 很多都会遵守一个退出状态码的约定, 具体的值对应的意思<font style="size:80%" >[2]</font>:</p>
<table>
<thead>
<tr>
<th>Exit Code Number</th>
<th>Meaning</th>
<th>Example</th>
<th>Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td><tt>1</tt></td>
<td>Catchall for general errors</td>
<td>let &#8220;var1 = 1/0&#8243;</td>
<td>Miscellaneous errors, such as &#8221;divide by zero&#8221; and other impermissible operations</td>
</tr>
<tr>
<td><tt>2</tt></td>
<td>Misuse of shell builtins (according to Bash documentation)</td>
<td>empty_function() {}</td>
<td>Seldom seen, usually defaults to exit code 1</td>
</tr>
<tr>
<td><tt>126</tt></td>
<td>Command invoked cannot execute</td>
<td></td>
<td>Permission problem or command is not an executable</td>
</tr>
<tr>
<td><tt>127</tt></td>
<td>&#8220;command not found&#8221;</td>
<td>illegal_command</td>
<td>Possible problem with <tt>$PATH</tt> or a typo</td>
</tr>
<tr>
<td><tt>128</tt></td>
<td>Invalid argument to <a href="http://tldp.org/LDP/abs/html/exit-status.html#EXITCOMMANDREF" >exit</a></td>
<td>exit 3.14159</td>
<td><strong>exit</strong> takes only integer args in the range 0 &#8211; 255 (see first footnote)</td>
</tr>
<tr>
<td><tt>128+n</tt></td>
<td>Fatal error signal &#8221;n&#8221;</td>
<td><em>kill -9</em> <tt>$PPID</tt> of script</td>
<td><tt><strong>$?</strong></tt> returns 137 (128 + 9)</td>
</tr>
<tr>
<td><tt>130</tt></td>
<td>Script terminated by Control-C</td>
<td></td>
<td>Control-C is fatal error signal 2, (130 = 128 + 2, see above)</td>
</tr>
<tr>
<td><tt>255*</tt></td>
<td>Exit status out of range</td>
<td>exit -1</td>
<td><strong>exit</strong> takes only integer args in the range 0 &#8211; 255</td>
</tr>
</tbody>
</table>
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>[1]: <a href="http://stackoverflow.com/questions/2726447/why-is-the-exit-code-255-instead-of-1-in-perl" >http://stackoverflow.com/questions/2726447/why-is-the-exit-code-255-instead-of-1-in-perl</a></li>
<li>[2]: <a href="http://tldp.org/LDP/abs/html/exitcodes.html" >http://tldp.org/LDP/abs/html/exitcodes.html</a></li>
</ul>
<p><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_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/2012/02/01/2503.html" >2012/02/02</a>, 唐僧 writes: 你太牛逼了。膜拜！！！</li><li><a href="http://www.laruence.com/2012/02/01/2503.html" >2012/02/02</a>, <a href="http://kimwu.sinaapp.com"  rel="external nofollow"  class="url" >熊少</a> writes: 哈 了解了</li><li><a href="http://www.laruence.com/2012/02/01/2503.html" >2012/02/02</a>, <a href="http://blog.chedushi.com"  rel="external nofollow"  class="url" >岭南六少</a> writes: 又充了下电啦
赞</li><li><a href="http://www.laruence.com/2012/02/01/2503.html" >2012/02/03</a>, ooxx 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" >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/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</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><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/2011/11/09/2277.html"  title="PHP原理之内存管理中难懂的几个点" >PHP原理之内存管理中难懂的几个点</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/01/2503.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>大家新年好~</title>
		<link>http://www.laruence.com/2012/01/24/2494.html</link>
		<comments>http://www.laruence.com/2012/01/24/2494.html#comments</comments>
		<pubDate>Tue, 24 Jan 2012 03:11:13 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[随笔]]></category>
		<category><![CDATA[拜年]]></category>
		<category><![CDATA[龙年]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2494</guid>
		<description><![CDATA[<p>
   写博客3年了, 也借此认识了不少朋友. 

   到今天, 博客的google订阅数3,870,  那就祝愿所有订阅我博客的同学们, 身体永远健康, 所有不经意来到我博客的同学们, 身体比较健康!!

   龙年大吉. 

thanks
</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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2012/01/24/2494.html"  title="Permanet Link to 大家新年好~" >http://www.laruence.com/2012/01/24/2494.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   写博客3年了, 也借此认识了不少朋友. </p>
<p>   到今天, 博客的google订阅数3,870,  那就祝愿所有订阅我博客的同学们, 身体永远健康, 所有不经意来到我博客的同学们, 身体比较健康!! 嘿嘿.<br/>
<div id="attachment_2499"  class="wp-caption aligncenter"  style="width: 371px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/0fc8b37f0fcb49688544f969.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/0fc8b37f0fcb49688544f969.png"  alt=""  title="0fc8b37f0fcb49688544f969"  width="361"  height="543"  class="size-full wp-image-2499" /></a><p class="wp-caption-text" >新年快乐</p></div><br/>
   龙年大吉. </p>
<p>thanks</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/24/2494.html" >2012/01/24</a>, <a href="http://www.jymoz.com"  rel="external nofollow"  class="url" >Lotte</a> writes: 3870分之一啊 哈哈</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/24</a>, <a href="http://veapon.com"  rel="external nofollow"  class="url" >veapon</a> writes: 这图很有内涵...
恭喜发财，，</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/24</a>, <a href="http://blog.francistm.com"  rel="external nofollow"  class="url" >francis</a> writes: 新年快乐，恭喜发财啊～</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/26</a>, <a href="http://blog.greycode.cn"  rel="external nofollow"  class="url" >stvenx</a> writes: 新年快乐！</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/27</a>, joey writes: 新年好~~配图很牛X~</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/28</a>, <a href="http://solupro.sinaapp.com"  rel="external nofollow"  class="url" >solu</a> writes: 新年快乐！
“比较”亮了！</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/29</a>, <a href="http://rossobe.com"  rel="external nofollow"  class="url" >Amaranth</a> writes: "比较健康" 好无语</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/30</a>, <a href="http://digdeeply.info"  rel="external nofollow"  class="url" >DigDeeply</a> writes: 我是身体永远健康的，，哈哈。</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/30</a>, <a href="http://blog.chedushi.com"  rel="external nofollow"  class="url" >岭南六少</a> writes: 向鸟哥学习</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/30</a>, 谢飞 writes: 新年快乐,恭喜发财</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/01/31</a>, litton writes: 新年好</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/02/01</a>, Joe writes: 为了身体永远健康,赶紧订阅了一下!-_-</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/02/02</a>, oboodo 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/2010/06/22/1618.html"  title="ReflectionFunction(Method)引用参数导致Invocation failed" >ReflectionFunction(Method)引用参数导致Invocation failed</a></li><li><a href="http://www.laruence.com/2010/05/28/1565.html"  title="PHP错误抑制符(@)导致引用传参失败的Bug" >PHP错误抑制符(@)导致引用传参失败的Bug</a></li><li><a href="http://www.laruence.com/2009/07/27/1020.html"  title="深入理解PHP原理之错误抑制与内嵌HTML" >深入理解PHP原理之错误抑制与内嵌HTML</a></li><li><a href="http://www.laruence.com/2008/11/20/630.html"  title="深入理解PHP原理之foreach" >深入理解PHP原理之foreach</a></li><li><a href="http://www.laruence.com/2009/08/23/1065.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/2010/12/17/1833.html"  title="PHP是无辜的" >PHP是无辜的</a></li><li><a href="http://www.laruence.com/2009/11/16/1147.html"  title="分割GBK中文遭遇乱码的解决" >分割GBK中文遭遇乱码的解决</a></li><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/2008/11/19/625.html"  title="让人无语的139邮箱" >让人无语的139邮箱</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/01/24/2494.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<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/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><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/11/2482.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>如何设置一个严格30分钟过期的Session</title>
		<link>http://www.laruence.com/2012/01/10/2469.html</link>
		<comments>http://www.laruence.com/2012/01/10/2469.html#comments</comments>
		<pubDate>Tue, 10 Jan 2012 07:02:17 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[随笔]]></category>
		<category><![CDATA[COOKIE]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[session]]></category>
		<category><![CDATA[过期]]></category>
		<category><![CDATA[面试题]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2469</guid>
		<description><![CDATA[今天在我的微博(<a href="http://t.sina.com.cn/laruence">Laruence</a>)上发出一个问题:
<blockquote>
我在面试的时候, 经常会问一个问题: "如何设置一个30分钟过期的Session?", 大家不要觉得看似简单, 这里面包含的知识挺多, 特别适合考察基本功是否扎实, 谁来回答试试? 呵呵
</blockquote>

   为什么问这个问题呢?  1. 我在Twitter上看到了有人讨论这个<a href="http://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes">问题</a>, 2 想起来我经常问这个问题, 所以~~

   在这里, 我来解答下这个题目.]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2012/01/10/2469.html"  title="Permanet Link to 如何设置一个严格30分钟过期的Session" >http://www.laruence.com/2012/01/10/2469.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    今天在我的微博(<a href="http://t.sina.com.cn/laruence" >Laruence</a>)上发出一个问题:</p>
<blockquote><p>
我在面试的时候, 经常会问一个问题: &#8220;如何设置一个30分钟过期的Session?&#8221;, 大家不要觉得看似简单, 这里面包含的知识挺多, 特别适合考察基本功是否扎实, 谁来回答试试? 呵呵
</p></blockquote>
<p>   为什么问这个问题呢?  1. 我在Twitter上看到了有人讨论这个<a href="http://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes" >问题</a>, 2 想起来我经常问这个问题, 所以~~</p>
<p>   在这里, 我来解答下这个题目.</p>
<h3>第一种回答</h3>
<p>那么, 最常见的一种回答是: 设置Session的过期时间, 也就是<a href="http://www.php.net/manual/en/session.configuration.php#ini.session.gc-maxlifetime" >session.gc_maxlifetime</a>,  这种回答是不正确的, 原因如下:</p>
<p>   1.  首先, 这个PHP是用一定的概率来运行session的gc的, 也就是session.gc_probability和session.gc_divisor(介绍参看<a href="http://www.laruence.com/2011/03/29/1949.html" > 深入理解PHP原理之Session Gc的一个小概率Notice</a>), 这个默认的值分别是1和100, 也就是有1%的机会, PHP会在一个Session启动时, 运行Session gc. 不能保证到30分钟的时候一定会过期.</p>
<p>   2. 那设置一个大概率的清理机会呢?  还是不妥, 为什么?  因为PHP使用stat Session文件的修改时间来判断是否过期, 如果增大这个概率一来会降低性能, 二来, PHP使用&#8221;一个&#8221;文件来保存和一个会话相关的Session变量, 假设我5分钟前设置了一个a=1的Session变量, 5分钟后又设置了一个b=2的Seesion变量, 那么这个Session文件的修改时间为添加b时刻的时间, 那么a就不能在30分钟的时候, 被清理了. 另外还有下面第三个原因.</p>
<p>   3. PHP默认的(Linux为例), 是使用/tmp 作为Session的默认存储目录, 并且手册中也有如下的描述:</p>
<blockquote><p>
Note: 如果不同的脚本具有不同的 session.gc_maxlifetime 数值但是共享了同一个地方存储会话数据，则具有最小数值的脚本会清理数据。此情况下，与 session.save_path 一起使用本指令。
</p></blockquote>
<p>      也就是说, 如果有俩个应用都没有指定自己独立的save_path, 一个设置了过期时间为2分钟(假设为A), 一个设置为30分钟(假设为B), 那么每次当A的Session gc运行的时候, 就会同时删除属于应用B的Session files.</p>
<p>      所以, 第一种答案是不&#8221;完全严格&#8221;正确的.</p>
<h3>第二种答案</h3>
<p>还有一种常见的答案是: 设置Session ID的载体, Cookie的过期时间, 也就是<a href="http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime" >session.cookie_lifetime</a>.  这种回答也是不正确的, 原因如下:</p>
<p>    这个过期只是Cookie过期,  换个说法这点就考察Cookie和Session的区别, Session过期是服务器过期, 而Cookie过期是客户端(浏览器)来保证的, 即使你设置了Cookie过期, 这个只能保证标准浏览器到期的时候, 不会发送这个Cookie(包含着Session ID), 而如果通过构造请求, 还是可以使用这个Session ID的值.</p>
<h3>第三种答案</h3>
<p>使用memcache, redis等, okey, 这种答案是一种正确答案.  不过, 很显然出题者肯定还会接着问你, 如果只是使用PHP呢?</p>
<h3>第四种答案</h3>
<p>当然, 面试不是为了难道你, 而是为了考察思考的周密性. 在这个过程中我会提示出这些陷阱,  所以一般来说, 符合题意的做法是:</p>
<p>    1. 设置Cookie过期时间30分钟, 并设置Session的lifetime也为30分钟.</p>
<p>    2. 自己为每一个Session值增加Time stamp.</p>
<p>    3. 每次访问之前, 判断时间戳. </p>
<p>最后, 有同学问,  为什么要设置30分钟的过期时间:  这个, 首先这是为了面试, 第二, 实际使用场景的话, 比如30分钟就过期的优惠劵? </p>
<p>thanks <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> </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/10/2469.html" >2012/01/10</a>, peng writes: thanks</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/10</a>, <a href="http://weibo.com/pangee"  rel="external nofollow"  class="url" >pangee</a> writes: 好吧。学习了。</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/10</a>, <a href="http://blog.webfuns.net"  rel="external nofollow"  class="url" >tomheng</a> writes: 应该是stackoverflow吧</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/10</a>, <a href="http://www.cxphp.com"  rel="external nofollow"  class="url" >鑫爷</a> writes: 好东西啊。学习了。。</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/10</a>, <a href="http://www.shibeike.net"  rel="external nofollow"  class="url" >treesky</a> writes: 引用部分的那个歪字体看起来十分费劲。</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/10</a>, heyli writes: 第一回答 php.ini 修改 至于修改那里 不记得要回去查下
第二 要严格的 我会考虑写进数据库</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/10</a>, wclssdn writes: 好吧.. 我的第一反应就是session中存时间戳.. 如果session中变量需要设置过期.. 那就为变量添加时间戳.... 
貌似这个方法最可靠了~~ 
使用内存缓存之类的... 是使用它们替换session存储位置? 
那同样没有设置过期时间的地方... 只能再此基础上封装成类.. 在方法中添加过期时间. 传递给redis.. 而这样.. 就跟添加时间戳没区别了...</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/11</a>, 四不象 writes: 为什么我觉得第一种回答的第一点不成立呢。那个设置是gc，垃圾回收，并非是没被回收的session文件不会过期。PHP的session默认的file引擎在读取session文件前还是会判断文件最后修改时间的，如果超出session.gc_maxlifetime就不会读取这个session文件</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/11</a>, <a href="http://weibo.com/enzohere"  rel="external nofollow"  class="url" >enzo</a> writes: session.gc_maxlifetime既然不能严格控制session的过期时间，这算不算bug？我的愚建是既然有个这样的配置就应该保证这个配置对应的功能能起到确定的作用。</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/12</a>, silentime writes: 实际的应用场景如果需要严格过期的话，应该不会用session机制把？</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/12</a>, <a href="http://blog.byedown.com/topics/489.html"  rel="external nofollow"  class="url" >如何设置一个严格30分钟过期的Session | Just Me</a> writes: [...] 原文地址: http://www.laruence.com/2012/01/10/2469.html [...]</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/01/31</a>, <a href="http://sk80.sinaapp.com/?p=51"  rel="external nofollow"  class="url" >如何设置一个严格30分钟过期的Session | Only WordPress</a> writes: [...] 来源：http://www.laruence.com/2012/01/10/2469.html 第一种回答 [...]</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/02/01</a>, <a href="http://www.tageta.com"  rel="external nofollow"  class="url" >klvoek</a> writes: 第三种答案求深入</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/02/01</a>, <a href="http://www.52sql.com/?p=272"  rel="external nofollow"  class="url" >如何设置一个严格30分钟过期的Session | 迈克</a> writes: [...] 来源：http://www.laruence.com/2012/01/10/2469.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" >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/03/29/1949.html"  title="深入理解PHP原理之Session Gc的一个小概率Notice" >深入理解PHP原理之Session Gc的一个小概率Notice</a></li><li><a href="http://www.laruence.com/2009/12/05/1172.html"  title="PHP5.2.x + APC的一个bug的定位" >PHP5.2.x + APC的一个bug的定位</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/2008/04/04/17.html"  title="在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究" >在PHP Module中获取$_GET/$_POST/$_COOKIE的方法研究</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/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/2012/01/10/2469.html/feed</wfw:commentRss>
		<slash:comments>14</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/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><li><a href="http://www.laruence.com/2011/11/09/2277.html"  title="PHP原理之内存管理中难懂的几个点" >PHP原理之内存管理中难懂的几个点</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>PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</title>
		<link>http://www.laruence.com/2011/12/30/2440.html</link>
		<comments>http://www.laruence.com/2011/12/30/2440.html#comments</comments>
		<pubDate>Fri, 30 Dec 2011 09:05:29 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[Hash冲突]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[拒绝服务攻击]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2440</guid>
		<description><![CDATA[   由我前面的俩篇文章介绍(<a href="http://www.laruence.com/2011/12/29/2412.html">通过构造Hash冲突实现各种语言的拒绝服务攻击</a>, <a href="http://www.laruence.com/2011/12/30/2435.html">PHP数组的Hash冲突实例 </a> ),  这个攻击方法危害很高, 攻击成本也很小.  一个台式机可以轻松搞垮数十台, 上百台服务器.  
   
     而和Pierre沟通后, 官方开发组不会为此发布PHP 5.2.18, 但是目前还是由不少公司还在使用5.2,  所以我特将dmitry为5.4写的patch, 分别apply到5.2上.

     大家如果有用5.2的, 如果被此类攻击威胁, 可以打上下面的patch,  PHP5.3的, 可以考虑升级到5.3.9, 已经包含了此patch(因为5.3.9目前是RC状态, 所以如果不愿意升级, 也可以参照这个patch自己为5.3写一个): 

     <a href="https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars">https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars</a>
    
     另外, 其他语言java, ruby等, 请各位也预先想好对策, 限制post_size是治标不治本的方法, 不过可以用来做临时解决方案.

thanks]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/12/30/2440.html"  title="Permanet Link to PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >http://www.laruence.com/2011/12/30/2440.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
     由我前面的俩篇文章介绍(<a href="http://www.laruence.com/2011/12/29/2412.html" >通过构造Hash冲突实现各种语言的拒绝服务攻击</a>, <a href="http://www.laruence.com/2011/12/30/2435.html" >PHP数组的Hash冲突实例 </a> ),  这个攻击方法危害很高, 攻击成本也很小.  一个台式机可以轻松搞垮数十台, 上百台服务器.  </p>
<p>     而和Pierre沟通后, 官方开发组不会为此发布PHP 5.2.18, 但是目前还是由不少公司还在使用5.2,  所以我特将dmitry为5.4写的patch, 分别apply到5.2上.</p>
<p>     大家如果有用5.2的, 如果被此类攻击威胁, 可以打上下面的patch,  PHP5.3的, 可以考虑升级到5.3.9, 已经包含了此patch(因为5.3.9目前是RC状态, 所以如果不愿意升级, 也可以参照这个patch自己为5.3写一个): </p>
<p>     <a href="https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars" >https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars</a></p>
<p>     补充一下(2012年1月8日): 如果你使用的是Windows下的PHP, 或者其他原因导致你不方便采用打patch的方法, 也可以采用修改PHP的配置max_input_time为一个较小的值来缓解此类攻击带来的影响.</p>
<p>     另外, 其他语言java, ruby等, 请各位也预先想好对策, 限制post_size是治标不治本的方法, 不过可以用来做临时解决方案.</p>
<p>thanks</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/2440.html" >2011/12/30</a>, cha369 writes: 鸟哥效率啊，造福大众</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/30</a>, <a href="http://blog.thephper.com"  rel="external nofollow"  class="url" >板子</a> writes: 鸟哥，这两篇文章一发，大家都不得不升级了 
攻击门槛被降低到约等于0了</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/30</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @板子 不能怨我啊, 这个方法是国外曝出来的.....</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/30</a>, -_- writes: 弱弱的问一下 如何给线上运行的PHP打path</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/31</a>, 蘑菇 writes: 呃,php 5.3.9 在哪?</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/31</a>, coralzd writes: cd Php-5.2.17 ;
执行patch  -p1  php-5.2.17-max-input-vars.patch  
一直在那里卡住！</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/31</a>, Anders writes: 貌似必须restart 才行啊， reload都不行呢。</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/31</a>, 饼饼 writes: patch -p1 &lt; laruence-laruence.github.com-43969a1/php-5.2-max-input-vars/php-5.2.17-max-input-vars.patch
can&#039;t find file to patch at input line 4
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|diff -u -r php-5.2.17/configure php-5.2.17-patched/configure
|--- php-5.2.17/configure       2011-01-07 07:04:43.000000000 +0800
|+++ php-5.2.17-patched/configure       2011-12-31 11:46:11.000000000 +0800
--------------------------
File to patch:


不行挖。。</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/31</a>, boyaa writes: it is can not make effect even though I patched the php-5.2.10 successfully !</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2011/12/31</a>, Justin writes: sed -i "s/PHP_EXTRA_VERSION=\"\"/PHP_EXTRA_VERSION=\"p1\"/" ./configure
sed -i "s/PHP_EXTRA_VERSION=\"\"/PHP_EXTRA_VERSION=\"p1\"/" ./configure.in
sed -i "s/define PHP_EXTRA_VERSION \"\"/define PHP_EXTRA_VERSION \"p1\"/" ./main/php_version.h
sed -i "s/long max_input_nesting_level;/&amp;\n\tlong max_input_vars;/" ./main/php_globals.h

sed -ie "/Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {/a\\\t\t\t\t\tif (zend_hash_num_elements(symtable1) &gt;= PG(max_input_vars)) {\n\t\t\t\t\t\tphp_error_docref(NULL TSRMLS_CC, E_ERROR, \"Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.\", PG(max_input_vars));\n\t\t\t\t\t}" ./main/php_variables.c

sed -ie "/zval_ptr_dtor(&amp;gpc_element);/{n; s/} else {/&amp;\n\t\t\t\tif (zend_hash_num_elements(symtable1) &gt;= PG(max_input_vars)) {\n\t\t\t\t\tphp_error_docref(NULL TSRMLS_CC, E_ERROR, \"Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.\", PG(max_input_vars));\n\t\t\t\t}/;}" ./main/php_variables.c

sed -ie "/PHP_INI_BEGIN()/{n; s/$/&amp;\n\tSTD_PHP_INI_ENTRY(\"max_input_vars\",         \"1000\",     PHP_INI_SYSTEM|PHP_INI_PERDIR,      OnUpdateLongGEZero, max_input_vars, php_core_globals, core_globals)/;}" ./main/main.c</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/02</a>, 不懂 writes: 鸟哥,问你个问题:
在网站访问量比较大的时候,网站应用了伪静态和不用伪静态对主机的性能影响的区别有多大?
应用伪静态会多占用服务器的CPU?</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/04</a>, 一寒 writes: linux的还有办法打补丁重编译，windows下的php5.2.17怎么编译？现在好多加密程序只支持PHP5.2X系列，用不了5.3，而官方又不给5.2.17提供解决办法。强烈建议出一个经验证的完整的windows编译方法</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/04</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @一寒 Windows下, 可以考虑安装suhosin扩展: http://www.hardened-php.net/suhosin/ 它也有类似的suhosin.post.max_vars的设置</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/04</a>, Anonymous writes: 发现这个补丁在post参数超过设置时，错误信息并不能显示在浏览器里（display_errors已经打开），nginx日志为：
2012/01/04 19:32:05 [error] 16816#0: *256659 FastCGI sent in stderr: "PHP Fatal error:  Unknown: Input variables exceeded 1.
To increase the limit change max_input_vars in php.ini. in Unknown on line 0" while reading response header from upstream, cl
ient: *****, server: $host, request: "POST /input_vars.php HTTP/1.1", upstream: 
......

2012/01/04 19:32:05 [error] 16816#0: *256659 upstream sent unexpected FastCGI record: 3 while reading response header from up
stream, client: ******, server: $host, request: "POST /input_vars.php HTTP/1.1", upstream: 
......</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/04</a>, 三少 writes: 发现这个补丁在参数超过设置时错误信息并不能显示出来。

2012/01/04 19:32:05 [error] 16816#0: *256659 FastCGI sent in stderr: "PHP Fatal error:  Unknown: Input variables exceeded 1.
To increase the limit change max_input_vars in php.ini. in Unknown on line 0" while reading response header from upstream, cl
ient: *****, server: $host, request: "POST /input_vars.php HTTP/1.1", upstream: 


2012/01/04 19:32:05 [error] 16816#0: *256659 upstream sent unexpected FastCGI record: 3 while reading response header from up
stream, client: *****, server: $host, request: "POST /input_vars.php HTTP/1.1", upstream:</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/06</a>, rui7905 writes: 5.2.14打过补丁之后，发现file_get_contents函数会报“URL File-Access is Disabled”的错误，修改php.ini的allow_url_include为On之后，就好了。但是补丁之前的allow_url_include也是Off，看过补丁代码也没发现跟这个有关的地方，很奇怪……</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/06</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @rui7905 你打完补丁以后, make clean了么</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/07</a>, <a href="http://blog.jobbole.com/11516/"  rel="external nofollow"  class="url" >PHP哈希表碰撞攻击原理 - 博客 - 伯乐在线</a> writes: [...] 针对POST方式的哈希碰撞攻击，目前PHP的防护措施是控制POST数据的数量。在&gt;=PHP5.3.9的版本中增加了一个配置项max_input_vars，用于标识一次http请求最大接收的参数个数，默认为1000。因此PHP5.3.x的用户可以通过升级至5.3.9来避免哈希碰撞攻击。5.2.x的用户可以使用这个patch：http://www.laruence.com/2011/12/30/2440.html。 [...]</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/07</a>, <a href="http://blog.jobbole.com/11535/"  rel="external nofollow"  class="url" >PHP哈希表碰撞攻击原理 - 博客 - 伯乐在线</a> writes: [...] 针对POST方式的哈希碰撞攻击，目前PHP的防护措施是控制POST数据的数量。在&gt;=PHP5.3.9的版本中增加了一个配置项 max_input_vars，用于标识一次http请求最大接收的参数个数，默认为1000。因此PHP5.3.x的用户可以通过升级至5.3.9来避 免哈希碰撞攻击。5.2.x的用户可以使用这个patch：http://www.laruence.com/2011/12/30/2440.html。 [...]</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/08</a>, <a href="https://lauyu.me/2012/01/08/installed-to-prevent-denial-of-service-attacks-hash-conflict-php-patch/"  rel="external nofollow"  class="url" >安装防止Hash冲突拒绝服务攻击的PHP Patch &laquo; Lauyu的茶几</a> writes: [...] 在随后几天laruence放出了PHP对应的补丁,以解决这一问题. [...]</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/08</a>, <a href="http://blog.mrbird.org/2012/01/installed-to-prevent-denial-of-service-attacks-hash-conflict-php-patch/"  rel="external nofollow"  class="url" >安装防止Hash冲突拒绝服务攻击的PHP Patch | Mr.Bird</a> writes: [...] 在之后laruence放出了PHP对应的补丁,以解决这一问题. [...]</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/09</a>, zlsky writes: 我打了5.2.17的补丁之后,php的session就无法保存了.
大致看了一下应该是cookie的session id 无法映射到服务器里面的session值....
每当页面跳转的时候session值就全部丢失了?会是什么原因造成的.</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/01/12</a>, easyboy writes: centos下用yum安装的PHP能打补丁吗？都不知道怎么进入PHP src目录，求教！～</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/03</a>, <a href="http://none"  rel="external nofollow"  class="url" >none</a> writes: please fix this bug https://bugs.php.net/bug.php?id=60708 in you https://github.com/laruence/laruence.github.com/tree/master/php-5.2-max-input-vars patch</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/03</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @none 我为5.2提供的patch, 不受此影响. thanks :)</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/03</a>, George writes: Hello Laruence,

There were a related vulnerability CVE-2012-0830 for this patch.

May you mind to back-ported the change for PHP 5.2.17 too?

Thank you very much for your kind attention

Regards
George</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/04</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >laruence</a> writes: @George 
hello, there is no such issue in this patch, so plz don't worry. :)</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/04</a>, George writes: Hello Laruence,

您好， 首先謝謝您的回覆, 有少少問題欲請教 - 

在您的 5.2.17 patch 裡， 於 php_error_docref ， 您使用了 E_ERROR (而不是 PHP 5.3.9 原本的 E_WARNING)

我們驗過， 似乎 E_ERROR 是會中止 c 程式執行，所以沒有運行有問題的 Z_ARRVAL_PP；

而 E_WARNING (或 E_NOTICE) 是會讓 PHP 的 php_variables.c 程式繼續執行, 所以間接地牽涉的 Z_ARRVAL_PP

請多多指教。

謝謝
George</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/03/29/1949.html"  rel="bookmark"  title="Permanent Link: 深入理解PHP原理之Session Gc的一个小概率Notice" >深入理解PHP原理之Session Gc的一个小概率Notice</a></li><li><a href="http://www.laruence.com/2008/09/20/523.html"  rel="bookmark"  title="Permanent Link: PHP5.3 α2初体验" >PHP5.3 α2初体验</a></li><li><a href="http://www.laruence.com/2011/07/02/2097.html"  rel="bookmark"  title="Permanent Link: PHP5.4的新特性" >PHP5.4的新特性</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  rel="bookmark"  title="Permanent Link: 二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2011/12/19/2409.html"  rel="bookmark"  title="Permanent Link: 之前提到的PHP5.4一个注意点的update" >之前提到的PHP5.4一个注意点的update</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/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/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><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/2011/11/09/2277.html"  title="PHP原理之内存管理中难懂的几个点" >PHP原理之内存管理中难懂的几个点</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/30/2440.html/feed</wfw:commentRss>
		<slash:comments>28</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/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><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/2011/12/30/2435.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>通过构造Hash冲突实现各种语言的拒绝服务攻击</title>
		<link>http://www.laruence.com/2011/12/29/2412.html</link>
		<comments>http://www.laruence.com/2011/12/29/2412.html#comments</comments>
		<pubDate>Thu, 29 Dec 2011 04:31:12 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[Ddos]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[max_input_vars]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[V8]]></category>
		<category><![CDATA[漏洞]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2412</guid>
		<description><![CDATA[   上周的时候Dmitry突然在5.4发布在即的时候, 引入了一个新的配置项:
<coolcode lang="php" linenum="off">
Added max_input_vars directive to prevent attacks based on hash collisions
</coolcode>

   这个预防的攻击, 就是"通过调用Hash冲突实现各种语言的拒绝服务攻击漏洞"(multiple implementations denial-of-service via hash algorithm collision).
]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/12/29/2412.html"  title="Permanet Link to 通过构造Hash冲突实现各种语言的拒绝服务攻击" >http://www.laruence.com/2011/12/29/2412.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   上周的时候Dmitry突然在5.4发布在即的时候, 引入了一个新的配置项:</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;">
Added max_input_vars directive to prevent attacks based on hash collisions
</pre>
<p>   这个预防的攻击, 就是&#8221;通过调用Hash冲突实现各种语言的拒绝服务攻击漏洞&#8221;(multiple implementations denial-of-service via hash algorithm collision).</p>
<p>   攻击的原理很简单, 目前很多语言, 使用hash来存储k-v数据, 包括常用的来自用户的POST数据, 攻击者可以通过构造请求头, 并伴随POST大量的特殊的&#8221;k&#8221;值(根据每个语言的Hash算法不同而定制), 使得语言底层保存POST数据的Hash表因为&#8221;冲突&#8221;(碰撞)而退化成链表.<br/>
<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="aligncenter size-full wp-image-2415" /></a></p>
<p>   这样一来, 如果数据量<b>足够大</b>, 那么就可以使得语言在计算, 查找, 插入的时候, 造成大量的CPU占用, 从而实现拒绝服务攻击. </p>
<p>   PHP5.4是通过增加一个限制来尽量避免被此类攻击影响:</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;">
  - max_input_vars - specifies how many GET/POST/COOKIE input variables may be
    accepted. default value 1000.
</pre>
</p>
<p><b> 目前已知的受影响的语言以及版本有:</b>:</p>
<p><a href="http://www.java.com" >Java</a>, 所有版本</p>
<p><a href="http://jruby.org/" >JRuby</a> &lt;= 1.6.5</p>
<p><a href="http://www.php.net/" >PHP</a> &lt;= 5.3.8, &lt;= 5.4.0RC3</p>
<p><a href="http://python.org/" >Python</a>, 所有版本</p>
<p><a href="http://rubini.us/" >Rubinius</a>, 所有版本</p>
<p><a href="http://www.ruby-lang.org/" >Ruby</a> &lt;= 1.8.7-p356</p>
<p><a href="http://geronimo.apache.org/" >Apache Geronimo</a>, 所有版本</p>
<p><a href="http://tomcat.apache.org/" >Apache Tomcat</a> &lt;= 5.5.34, &lt;= 6.0.34, &lt;= 7.0.22</p>
<p><a href="http://glassfish.java.net/" >Oracle Glassfish</a> &lt;= 3.1.1</p>
<p><a href="http://www.eclipse.org/jetty/" >Jetty</a>, 所有版本</p>
<p><a href="http://plone.org/" >Plone</a>, 所有版本</p>
<p><a href="http://rack.rubyforge.org/" >Rack</a>, 所有版本</p>
<p><a href="http://code.google.com/p/v8/" >V8 JavaScript Engine</a>, 所有版本</p>
<p><b>不受此影响的语言或者修复版本的语言有:</b>:</p>
<p><a href="http://www.php.net/" >PHP</a> &gt;= 5.3.9, &gt;= 5.4.0RC4</p>
<p><a href="http://jruby.org/" >JRuby</a> &gt;= 1.6.5.1</p>
<p><a href="http://www.ruby-lang.org/" >Ruby</a> &gt;= 1.8.7-p357, 1.9.x</p>
<p><a href="http://tomcat.apache.org/" >Apache Tomcat</a> &gt;= 5.5.35, &gt;= 6.0.35, &gt;= 7.0.23</p>
<p><a href="http://glassfish.java.net/" >Oracle Glassfish</a>, N/A (Oracle reports that the issue is fixed in the main codeline and scheduled for a future CPU)</p>
<p><b>CVE</b>:  <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-4885" >CVE-2011-4885</a> (PHP),  <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-4885" >CVE-2011-4461</a> (Jetty),  <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-4838" >CVE-2011-4838</a> (JRuby),  <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-4885" >CVE-2011-4462</a> (Plone),  <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-4815" >CVE-2011-4815</a> (Ruby)
</p>
<p>    原文: <a href="http://www.ocert.org/advisories/ocert-2011-003.html" >http://www.ocert.org/advisories/ocert-2011-003.html</a><br/>
   <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/2011/12/29/2412.html" >2011/12/29</a>, <a href="http://blog.csdn.net/sunvince"  rel="external nofollow"  class="url" >sunvince</a> writes: 好想法...</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/29</a>, aries writes: 这个，现在有可行的方法来构造大量hash值相同的不同原文？</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, Ferrari writes: 請問這篇的作者解釋的是同一個問題嗎?
http://nikic.github.com/2011/12/28/Supercolliding-a-PHP-array.html</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, <a href="http://xiezhenye.com/"  rel="external nofollow"  class="url" >神仙</a> writes: 如果是用的rbtree之类就不会有这麻烦了吧</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @Ferrari 恩,是一样的事情, :)</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, <a href="http://www.laruence.com/2011/12/30/2435.html"  rel="external nofollow"  class="url" >PHP数组的Hash冲突实例 | 风雪之隅</a> writes: [...]  [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, <a href="http://kimbs.cn"  rel="external nofollow"  class="url" >kim</a> writes: 这不是基本上全部中招？</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, mahone writes: max_input_vars - specifies how many GET/POST/COOKIE input variables may be
    accepted. default value 1000.

这个1000，是get,post,cookie这种加起来一共1000？还是get1000，post1000，cookie1000？</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, jw writes: hi,niaoge
为啥不在每个bucket中加个指针指向链表结尾来解决问题，而是采用限制输入长度的方案
thx</li><li><a href="http://www.laruence.com/2011/12/29/2412.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: [...] Posts:PHP数组的Hash冲突实例通过构造Hash冲突实现各种语言的拒绝服务攻击更简单的重现PHP Core的调用栈GBK编码PHP脚本导致语法错误(Zend [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/30</a>, <a href="http://www.xiuwz.com/site/news-hash-ph-java-ddos/"  rel="external nofollow"  class="url" >高危安全：Hash冲突导致PHP/JAVA/PYTHON等DDOS攻击 | 网站那些事 | 网站点兵</a> writes: [...] 高危安全：Hash冲突导致PHP/JAVA/PYTHON等DDOS攻击   作者: xiuwz 日期: 2011 年 12 月 30 日  发表评论 (0) 查看评论   (No Ratings Yet) &nbsp;Loading ...     分享到：     更多    国外目前报出“multiple implementations denial-of-service via hash algorithm collision”，该hash冲突漏洞对目前所有的WEB动态开发语言都有危害，导致一个用户可以轻松通过构造数据而造成任何网站拒绝服务，从而引发DDOS相关攻击。中文版介绍请参考http://www.laruence.com/2011/12/29/2412.html。 [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.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/29/2412.html） [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/31</a>, <a href="http://dabai.org/life/2011/12/php-array-hash-collisions/"  rel="external nofollow"  class="url" >PHP数组特殊Hash冲突问题</a> writes: [...] 通过构造Hash冲突实现各种语言的拒绝服务攻击 PHP数组的Hash冲突实例 深入理解PHP之数组(遍历顺序) Supercolliding a PHP array 哈希表(HashTable) PHP的哈希表实现    &nbsp;           If you enjoyed this article, please consider sharing it! [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2011/12/31</a>, <a href="http://blog.qijur.com/?p=88"  rel="external nofollow"  class="url" >Hash表碰撞导致dos攻击 | 亿光年</a> writes: [...] http://www.laruence.com/2011/12/29/2412.html [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/02</a>, <a href="http://upsuper.org/"  rel="external nofollow"  class="url" >upsuper</a> writes: Python 似乎受影响不大，首先 Python 本身不解析大量外部数据，所以不存在类似 PHP 那样针对语言层面的攻击，过滤过多参数只需要相关框架增加选项即可。其次 Python 的 Hash 算法似乎并不容易用来大规模构造冲撞数据，构造难度跟纯枚举差不多，所以短期内被攻击的可能性不大。</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/02</a>, yc2266 writes: 这个问题 百度可以共享一下 hi 空间里面的博文链接key 计算方式：

http://hi.baidu.com/baidu/blog/item/b95bb39997ebc2166f068cec.html

b95bb39997ebc2166f068cec 这个key的计算方式能保证在多少范围内不产生碰撞！(具体多少我也不知道)保证这个算法在一定范围的稳定性！</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/03</a>, <a href="http://www.tanglei.name"  rel="external nofollow"  class="url" >tanglei</a> writes: 这个，java怎么中招啊？
求解释。
java中的数组不会支持很大，受内存限制吧。
不过在hashmap中，有类似的影响。不过相差不大。</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/04</a>, <a href="https://larryli.cn/2012/01/644577"  rel="external nofollow"  class="url" >Suhosin, Good job! | 南靖男的时代</a> writes: [...] 年末传出动态语言大范围的 Hash DOS [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/04</a>, <a href="http://&#039;"  rel="external nofollow"  class="url" >'</a> writes: '</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/04</a>, hoho writes: alert('test')</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/05</a>, <a href="http://www.unclejoey.com"  rel="external nofollow"  class="url" >Joey Yin</a> writes: JAVA下hash冲突生成代码请参考：http://www.unclejoey.com/?p=554</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/05</a>, <a href="http://www.openews.net/2012/kangle-2-7-5-emergency-release-anti-collision-attacks-on-hash/"  rel="external nofollow"  class="url" >kangle 2.7.5 emergency release, anti-collision attacks on hash - Open News</a> writes: [...] collision theory:  http://www.laruence.com/2011/12/29/2412.html  [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/05</a>, <a href="http://summerbluet.com/post/533"  rel="external nofollow"  class="url" >通过调用Hash冲突实现各种语言的拒绝服务攻击漏洞 | Charlie&#039;s Coffee House</a> writes: [...] Laruence 的翻疑问 [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/06</a>, <a href="http://www.lnmpblog.com"  rel="external nofollow"  class="url" >fare</a> writes: 彻底的修改方法，就是改一下hash函数，在编译安装的时候，自动生成一个随机的p,hash的时候带上这个p，就很难构造退化的链表了。</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/07</a>, <a href="http://www.osmax.info/2012/01/350.osmax"  rel="external nofollow"  class="url" >kangle 2.7.5 紧急发布,防hash碰撞攻击 | 草石网</a> writes: [...] hash碰撞原理: http://www.laruence.com/2011/12/29/2412.html [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/07</a>, <a href="http://blog.yuaz.net/archives/244"  rel="external nofollow"  class="url" >Ruby和Rack解决因Hash表碰撞导致CPU拒绝服务的Bug &#8211; Imagine::Blog.new</a> writes: [...] 前几天，各个主流语言都爆出来了大Bug：“通过调用Hash冲突实现各种语言的拒绝服务攻击漏洞”（multiple implementations denial-of-service via hash algorithm collisio）。《通过构造Hash冲突实现各种语言的拒绝服务攻击》这篇文章提到PHP里引入了新的配置项，来限制GET/POST/COOKIE输入变量来减少攻击的影响。 [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/08</a>, <a href="http://www.tanglei.name/use-hash-collision-to-realize-dos-in-php-and-java/"  rel="external nofollow"  class="url" >通过构造Hash冲突实现PHP/Java等语言的拒绝服务攻击 &raquo; tanglei&#039;s blog 唐磊的个人博客</a> writes: [...] 前几天看到公司php群谈到这篇博文通过构造Hash冲突实现各种语言的拒绝服务攻击,说的是在PHP中，使用hash来存储k-v数据, 包括常用的来自用户的POST数据, 攻击者可以通过构造请求头, 并伴随POST大量的特殊的”k”值(根据每个语言的Hash算法不同而定制), 使得语言底层保存POST数据的Hash表因为”冲突”(碰撞)而退化成链表. 这样一来, 如果数据量足够大, 那么就可以使得语言在计算, 查找, 插入的时候, 造成大量的CPU占用, 从而实现拒绝服务攻击. 举个例子：如下代码中： 123456789101112131415161718192021222324252627&lt;?php  $size = pow&#040;2, 16&#041;; // 16 is just an example, could also be 15 or 17  $startTime = microtime&#040;true&#041;;  $array = array&#040;&#041;; for &#040;$key = 0, $maxKey = &#040;$size - 1&#041; * $size; $key &lt;= $maxKey; $key += $size&#041; &#123; &nbsp; &nbsp; &nbsp; &nbsp; $array&#091;$key&#093; = 0; &#125;  $endTime = microtime&#040;true&#041;;  echo &#039;Inserting &#039;, $size, &#039; evil elements took &#039;, $endTime - $startTime, &#039; seconds&#039;, &quot;n&quot;;  $startTime = microtime&#040;true&#041;;  $array = array&#040;&#041;; for &#040;$key = 0, $maxKey = $size - 1; $key &lt;= $maxKey; ++$key&#041; &#123; &nbsp; &nbsp; &nbsp; &nbsp; $array&#091;$key&#093; = 0; &#125;  $endTime = microtime&#040;true&#041;;  echo &#039;Inserting &#039;, $size, &#039; good elements took &#039;, $endTime - $startTime, &#039; seconds&#039;, &quot;n&quot;; //http://www.laruence.com/2011/12/30/2435.html ?&gt; [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/11</a>, <a href="http://www.zhouming.me/2012/01/wordpress-and-php-updated/"  rel="external nofollow"  class="url" >WordPress 升级到3.3.1，PHP升级到5.3.9，推荐DiffMerge | Ming&#039;s Blog</a> writes: [...] PHP版本升级到5.3.9，建议没有升级的赶快升级，防止受到Hash冲突拒绝服务攻击，可以参考 http://www.laruence.com/2011/12/29/2412.html，不过这么小的个人站点应该没有人有兴趣攻击。 [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/01/16</a>, <a href="http://www.nginxidc.com/kangle-hash/"  rel="external nofollow"  class="url" >kangle 2.7.5轻松防hash碰撞 &laquo; NginxIDC</a> writes: [...] hash碰撞原理: http://www.laruence.com/2011/12/29/2412.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" >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/2008/07/24/206.html"  title="Apache启动过程(PHP_MINIT_FUNCTION的调用)" >Apache启动过程(PHP_MINIT_FUNCTION的调用)</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/2011/12/29/2412.html/feed</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>之前提到的PHP5.4一个注意点的update</title>
		<link>http://www.laruence.com/2011/12/19/2409.html</link>
		<comments>http://www.laruence.com/2011/12/19/2409.html#comments</comments>
		<pubDate>Mon, 19 Dec 2011 10:26:21 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[Chained string offsets]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2409</guid>
		<description><![CDATA[  在之前, 我曾经介绍过, 在PHP5.4中, <a href="http://www.laruence.com/2011/11/28/2317.html">PHP5.4中一个需要注意的变化(Chained string offsets) </a>,  后续因为大多数人都表示这个变化很敏感, 容易成为坑..  于是, 我们现在对此做了一些改进.

      具体的改变是, 对于一个变量$a, 如果$a是一个字符串, 那么, 对于非数字型索引, 比如$a["foo"], 在isset的时候将返回false, empty返回true,  但是为了兼容已有的代码, 当你获取这个值的时候, 还是会返回$a[0], 不过会额外抛出一个警告信息.  比如:
<coolcode lang="php" linenum="off">
<?php
$a = "laruence";
var_dump($a["foo"]) ; //PHP Warning:  Illegal string offset 'foo'
//output string(1) "l"

var_dump(isset($a["foo"]));
//false

var_dump(empty($a["foo"]));
//true
</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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/12/19/2409.html"  title="Permanet Link to 之前提到的PHP5.4一个注意点的update" >http://www.laruence.com/2011/12/19/2409.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
      在之前, 我曾经介绍过, 在PHP5.4中, <a href="http://www.laruence.com/2011/11/28/2317.html" >PHP5.4中一个需要注意的变化(Chained string offsets) </a>,  后续因为大多数人都表示这个变化很敏感, 容易成为坑..  于是, 我们现在对此做了一些改进.</p>
<p>      具体的改变是, 对于一个变量$a, 如果$a是一个字符串, 那么, 对于非数字型索引, 比如$a["foo"], 在isset的时候将返回false, empty返回true,  但是为了兼容已有的代码, 当你获取这个值的时候, 还是会返回$a[0], 不过会额外抛出一个警告信息.  比如:</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
$a = &quot;laruence&quot;;
var_dump($a[&quot;foo&quot;]) ; //PHP Warning:  Illegal string offset 'foo'
//output string(1) &quot;l&quot;

var_dump(isset($a[&quot;foo&quot;]));
//false

var_dump(empty($a[&quot;foo&quot;]));
//true
</pre>
<p>     而对于键值是bool, double, null的情况, 将会和以前保持一致, 不过会抛出一个Notice信息.</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
$a = &quot;bar&quot;;
echo $a[TRUE];  //PHP Notice:  String offset cast occured
//output a
</pre>
<p>     而对于数字型的字符串索引, 比如&#8221;1&#8243;, &#8220;12&#8243;等, 和以前保持一致.</p>
<p>    不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>    谢谢</p>
<p>    更多更新信息, 请关注: <a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?view=markup"  target="_blank" >Changelog</a><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/12/19/2409.html" >2011/12/19</a>, <a href="http://xiezhenye.com"  rel="external nofollow"  class="url" >神仙</a> writes: 有个notice就好很多了。</li><li><a href="http://www.laruence.com/2011/12/19/2409.html" >2011/12/20</a>, <a href="http://www.shibeike.net"  rel="external nofollow"  class="url" >treesky</a> writes: 这个非常实用，避免了悄无声息的发生问题！</li><li><a href="http://www.laruence.com/2011/12/19/2409.html" >2011/12/28</a>, wclssdn writes: 看来以后只能每次都isset一次了- -..</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/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/12/06/2381.html"  title="更简单的重现PHP Core的调用栈" >更简单的重现PHP Core的调用栈</a></li><li><a href="http://www.laruence.com/2011/11/11/2296.html"  title="PHP5.4新特性-解引用实例化" >PHP5.4新特性-解引用实例化</a></li><li><a href="http://www.laruence.com/2011/11/04/2258.html"  title="三元式(ternary)性能优化" >三元式(ternary)性能优化</a></li><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/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2011/10/10/2229.html"  title="函数类型提示(Callable typehint)" >函数类型提示(Callable typehint)</a></li><li><a href="http://www.laruence.com/2011/10/10/2217.html"  title="上传进度支持(Upload progress in sessions)" >上传进度支持(Upload progress in sessions)</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/2011/10/10/2204.html"  title="JsonSerializable接口" >JsonSerializable接口</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/19/2409.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>关于PHP浮点数你应该知道的(All &#8216;bogus&#8217; about the float in PHP)</title>
		<link>http://www.laruence.com/2011/12/19/2399.html</link>
		<comments>http://www.laruence.com/2011/12/19/2399.html#comments</comments>
		<pubDate>Mon, 19 Dec 2011 03:34:56 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[double]]></category>
		<category><![CDATA[float]]></category>
		<category><![CDATA[IEEE 745]]></category>
		<category><![CDATA[long]]></category>
		<category><![CDATA[loss of precision]]></category>
		<category><![CDATA[双精度]]></category>
		<category><![CDATA[整数]]></category>
		<category><![CDATA[浮点数]]></category>
		<category><![CDATA[精度丢失]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2399</guid>
		<description><![CDATA[    PHP是一种弱类型语言, 这样的特性, 必然要求有无缝透明的隐式类型转换, PHP内部使用zval来保存任意类型的数值, zval的结构如下(5.2为例):
   
    .......

    今天的话题, 我们只关注其中的俩个成员,  lval和dval, 我们要意识到, long lval是随着编译器, OS的字长不同而不定长的, 它有可能是32bits或者64bits,  而double dval由<a href="http://en.wikipedia.org/wiki/IEEE_754-2008">IEEE 745</a>规定, 是定长的, 一定是64bits.
  
    请记住这一点, 造就了PHP的一些代码的"非平台无关性". <b>我们接下来的讨论, 除了特别指明, 都是假设long为64bits</b>]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/12/19/2399.html"  title="Permanet Link to 关于PHP浮点数你应该知道的(All &#8216;bogus&#8217; about the float in PHP)" >http://www.laruence.com/2011/12/19/2399.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    PHP是一种弱类型语言, 这样的特性, 必然要求有无缝透明的隐式类型转换, PHP内部使用zval来保存任意类型的数值, zval的结构如下(5.2为例):</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;">
struct _zval_struct {
    /* Variable information */
    zvalue_value value;     /* value */
    zend_uint refcount;
    zend_uchar type;    /* active type */
    zend_uchar is_ref;
};
</pre>
<p>     上面的结构中, 实际保存数值本身的是zvalue_value联合体:</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;">
typedef union _zvalue_value {
    long lval;                  /* long value */
    double dval;                /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;              /* hash table value */
    zend_object_value obj;
} zvalue_value;
</pre>
<p>    今天的话题, 我们只关注其中的俩个成员,  lval和dval, 我们要意识到, long lval是随着编译器, OS的字长不同而不定长的, 它有可能是32bits或者64bits,  而double dval由<a href="http://en.wikipedia.org/wiki/IEEE_754-2008" >IEEE 745</a>规定, 是定长的, 一定是64bits.</p>
<p>    请记住这一点, 造就了PHP的一些代码的&#8221;非平台无关性&#8221;. <b>我们接下来的讨论, 除了特别指明, 都是假设long为64bits</b></p>
<p>    IEEE 745的浮点计数法, 我这里就不引用了, 大家有兴趣的可以自己查看,  关键的一点是,  double的尾数采用52位bit来保存, 算上隐藏的1位有效位, 一共是53bits.</p>
<p>    在这里, 引出一个很有意思的问题,  我们用c代码举例(假设long为64bits):</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;">
    long a = x;
    assert(a == (long)(double)a);
</pre>
<p>    请问,  a的取值在什么范围内的时候, 上面的代码可以断言成功?(留在文章最后解答)</p>
<p>    现在我们回归正题,  PHP在执行一个脚本之前, 首先需要读入脚本, 分析脚本, 这个过程中也包含着, 对脚本中的字面量进行zval化,  比如对于如下脚本:</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
$a = 9223372036854775807; //64位有符号数最大值
$b = 9223372036854775808; //最大值+1
var_dump($a);
var_dump($b);
</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;">
int(9223372036854775807)
float(9.22337203685E+18)
</pre>
<p>   也就说, PHP在词法分析阶段, 对于一个字面量的数值, 会去判断, 是否超出了当前系统的long的表值范围,  如果不是, 则用lval来保存, zval为IS_LONG, 否则就用dval表示, zval IS_FLOAT.</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
$a = 9223372036854775807;
$b = 9223372036854775808;

var_dump($a === ($b - 1));
</pre>
<p>    输出是false. </p>
<p>    现在接上开头的讨论, 之前说过, PHP的整数, 可能是32位, 也可能是64位, 那么就决定了, 一些在64位上可以运行正常的代码, 可能会因为隐形的类型转换, 发生精度丢失, 从而造成代码不能正常的运行在32位系统上. </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
    echo PHP_INT_MAX;
 ?&gt;
</pre>
<p>    当然, 为了保险起见, 我们应该使用字符串来保存大整数, 并且采用比如<a href="http://www.php.net/manual/en/book.bc.php" >bcmatch</a>这样的数学函数库来进行计算.</p>
<p>    另外, 还有一个关键的配置, 会让我们产生迷惑, 这个配置就是<a href="http://www.php.net/manual/en/ini.core.php#ini.precision" >php.precision</a>, 这配置决定了PHP再输出一个float值的时候, 输出多少有效位. </p>
<p>    最后, 我们再来回头看上面提出的问题,  也就是一个long的整数, 最大的值是多少,  才能保证转到float以后再转回long不会发生精度丢失?</p>
<p>    比如, 对于整数, 我们知道它的二进制表示是, 101, 现在, 让我们右移俩位, 变成1.01, 舍去高位的隐含有效位1, 我们得到在double中存储5的二进制数值为:</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;">
0/*符号位*/ 10000000001/*指数位*/ 0100000000000000000000000000000000000000000000000000
</pre>
<p>    5的二进制表示, 丝毫未损的保存在了尾数部分, 这个情况下, 从double转会回long, 不会发生精度丢失.</p>
<p>    我们知道double用52位表示尾数, 算上隐含的首位1, 一共是53位精度.. 那么也就可以得出, 如果一个long的整数, 值小于:</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;">
2^53 - 1 == 9007199254740991; //牢记, 我们现在假设是64bits的long
</pre>
<p>    那么, 这个整数, 在发生long->double->long的数值转换时, 不会发生精度丢失.
</p>
<p><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><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_php.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_php.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/2011/12/19/2399.html" >2011/12/19</a>, gguoyu writes: IEEE 745的浮点计数法 ==&gt; 应该是IEEE 754 浮点计数法

- -！</li><li><a href="http://www.laruence.com/2011/12/19/2399.html" >2011/12/19</a>, <a href="http://blog.chedushi.com/archives/2578"  rel="external nofollow"  class="url" >关于PHP浮点数你应该知道的(All ‘bogus’ about the float in PHP) | 岭南六少 - 一朵在LAMP架构下挣扎的云</a> writes: [...] 本文地址: http://www.laruence.com/2011/12/19/2399.html [...]</li><li><a href="http://www.laruence.com/2011/12/19/2399.html" >2011/12/30</a>, wclssdn writes: 前不久也发现了这个问题.. 
$n = pow(2, 64);
var_dump($n, $n - 1);
结果一样的- -.. 我用的32位测试机.. 
以为是PHP的bug呢...</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/11/04/2258.html"  rel="bookmark"  title="Permanent Link: 三元式(ternary)性能优化" >三元式(ternary)性能优化</a></li><li><a href="http://www.laruence.com/2009/09/14/1081.html"  rel="bookmark"  title="Permanent Link: CSS让你的IE浏览器崩溃(Crash your IE)" >CSS让你的IE浏览器崩溃(Crash your IE)</a></li><li><a href="http://www.laruence.com/2008/04/21/101.html"  rel="bookmark"  title="Permanent Link: 关于PHP你可能不知道的－PHP的事件驱动化设计" >关于PHP你可能不知道的－PHP的事件驱动化设计</a></li><li><a href="http://www.laruence.com/2008/05/01/106.html"  rel="bookmark"  title="Permanent Link: 汉字和Unicode码(utf-8)之间的转换(Pack/Unpack)" >汉字和Unicode码(utf-8)之间的转换(Pack/Unpack)</a></li><li><a href="http://www.laruence.com/2011/03/29/1949.html"  rel="bookmark"  title="Permanent Link: 深入理解PHP原理之Session Gc的一个小概率Notice" >深入理解PHP原理之Session Gc的一个小概率Notice</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/26/463.html"  title="深入理解PHP原理之变量作用域(Scope in PHP)" >深入理解PHP原理之变量作用域(Scope in PHP)</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/15/274.html"  title="PHP 源代码分析 V0.0.2" >PHP 源代码分析 V0.0.2</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/2010/09/27/1754.html"  title="PHP stream未能及时清理现场导致Core的bug" >PHP stream未能及时清理现场导致Core的bug</a></li><li><a href="http://www.laruence.com/2009/06/01/902.html"  title="HTML 5 令人期待的 5 项功能" >HTML 5 令人期待的 5 项功能</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/02/25/1324.html"  title="NCR与HTML Entities" >NCR与HTML Entities</a></li><li><a href="http://www.laruence.com/2008/11/07/586.html"  title="深入理解PHP原理之文件上传" >深入理解PHP原理之文件上传</a></li><li><a href="http://www.laruence.com/2008/07/21/120.html"  title="PHP Pallas CMS源码公布" >PHP Pallas CMS源码公布</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/19/2399.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>更简单的重现PHP Core的调用栈</title>
		<link>http://www.laruence.com/2011/12/06/2381.html</link>
		<comments>http://www.laruence.com/2011/12/06/2381.html#comments</comments>
		<pubDate>Tue, 06 Dec 2011 13:04:53 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[core]]></category>
		<category><![CDATA[coredump]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[gdbinit]]></category>
		<category><![CDATA[how to gdb a php core]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>
		<category><![CDATA[segment fault]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2381</guid>
		<description><![CDATA[以前, 我曾经介绍过如何通过PHP的Core文件获取信息:<a href="http://www.laruence.com/2011/06/23/2057.html">如何调试PHP的Core之获取基本信息</a>, 对于调用参数这块, 当时介绍的获取方法比较复杂.

   于是今天我为PHP 5.4的.gdbinit做了一个改进, 以后如果你遇到了PHP 5.4的core, 那么就可以简单的得到PHP 5.4发生Core时, 包括参数的函数调用栈的信息.]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/12/06/2381.html"  title="Permanet Link to 更简单的重现PHP Core的调用栈" >http://www.laruence.com/2011/12/06/2381.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    以前, 我曾经介绍过如何通过PHP的Core文件获取信息:<a href="http://www.laruence.com/2011/06/23/2057.html" >如何调试PHP的Core之获取基本信息</a>, 对于调用参数这块, 当时介绍的获取方法比较复杂.</p>
<p>   于是今天我为PHP 5.4的.gdbinit做了一个改进, 以后如果你遇到了PHP 5.4的core, 那么就可以简单的得到PHP 5.4发生Core时, 包括参数的函数调用栈的信息.</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

class Test {
}

function a($i) {
    b(new Test, 2.3432, &quot;reader&quot;);
}
function b($i) {
    c(array(1,2,3));
}
function c($i) {
    d(TRUE);
}
function d($i) {
    $fp = fopen(&quot;/tmp/1.php&quot;, &quot;r&quot;);
    e($fp);
}

function e($i) {
    sleep(1000);
}

a();
</pre>
<p>    使用后台运行以后, PHP5.4会sleep在e函数的sleep中,  这时, 如果我们使用gdb attach上去, </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;">
gdb --pid= xxx //使用ps获得后台运行脚本的pid
</pre>
<p>   然后, source  PHP源代码下面的.gdbinit:</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;">
(gdb) source php54-src/.gdbinit
</pre>
<p>  然后,  让我们尝试调用下zbacktrace, 看看什么结果:</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;">
(gdb) zbacktrace
[0x2a95dac5e0] sleep(1000) /tmp/1.php:21
[0x2a95dac4c0] e(resource(#5)) /tmp/1.php:17
[0x2a95dac3f0] d(true) /tmp/1.php:13
[0x2a95dac300] c(array(3)[0x2a95de7db0]) /tmp/1.php:10
[0x2a95dac1c0] b(object[0x2a95de7840], 2.343200, &quot;reader&quot;) /tmp/1.php:7
[0x2a95dac0e8] a() /tmp/1.php:24
</pre>
<p>    恩, 对于array和object, 因为我们为了保持不要乱屏, 所以没有展开, 不过, 如果我们要查看这个array具体是什么元素, 可以这样做, 注意到上面的:array(3)[0x2a95de7db0]:</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;">
(gdb) print ((zval *)0x2a95de7db0)
$4 = (struct _zval_struct *) 0x2a95de7db0
(gdb) printzv $4
[0x2a95de7db0] (refcount=2) array(3): {
    0 =&gt; [0x2a95de79d0] (refcount=1) long: 1
    1 =&gt; [0x2a95de7b80] (refcount=1) long: 2
    2 =&gt; [0x2a95de7c98] (refcount=1) long: 3
  }
</pre>
<p>类似的, 对于object, 注意到上面的: object[0x2a95de7840]</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;">
(gdb) print ((zval *)0x2a95de7840)
$5 = (struct _zval_struct *) 0x2a95de7840
(gdb) printzv $5
[0x2a95de7840] (refcount=2) object
(Test) #1&quot;no properties found&quot;
</pre>
<p>    要注意的一点是, 对于object,  如果你是在调式Core文件, 而不是attach到一个运行的进程上, 那么上面的尝试会得到一个错误:</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;">
(gdb) printzv $5
[0x2a95de7840] (refcount=2) objectYou can't do that without a process to debug.
</pre>
<p>    不过, 即使这样, 我们还是有办法, 只不过就比较麻烦了.在NTS下面:</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;">
(gdb) p ((zval *)0x2a95de7840)-&gt;value.obj.handle
$6 = 1
//注意, 下面用到了这个$6的值:1
(gdb)  p (zend_object*) executor_globals-&gt;objects_store.object_buckets[1].bucket.obj.object
$7 = (struct _zend_object *) 0x2a95de3ec0
(gdb)  p $9-&gt;ce-&gt;name
$8 = 0x2a95e200b0 &quot;Test&quot;
</pre>
<p>    呵呵, 怎么样, 有了这些信息, 分析Core的原因, 是不是就更简单了呢?   enjoy~</p>
<p>    最后, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>    谢谢</p>
<p>    更多更新信息, 请关注: <a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?view=markup"  target="_blank" >Changelog</a><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_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>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/06/2381.html" >2011/12/06</a>, 66beta writes: 完全看不懂，但是感觉很厉害的样子</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/06</a>, <a href="http://www.freefcw.info"  rel="external nofollow"  class="url" >巫山霏云</a> writes: 依然还是蛮麻烦的，不过确实要方便一些
不过要PHP CORE还真蛮难的</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/06</a>, <a href="http://www.shibeike.net"  rel="external nofollow"  class="url" >treesky</a> writes: 完全看不懂，但是感觉很厉害的样。Php，我才刚上路啊！</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/06</a>, <a href="http://www.cnxct.com"  rel="external nofollow"  class="url" >CFC4N</a> writes: 比起上一篇提到的isset的消息，这是个天大的好事情，调试代码性能简直方便多了，很容易找到执行最耗时的瓶颈所在。感谢PHP开发组。感谢鸟哥，感谢郭嘉。
PS：唠叨一遍，这是个好功能。</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/07</a>, xq262144 writes: 嗯，这个要好用多了，有参数的各种信息，不过我还是纠结于看HashTable的东西要人工计算hash。。。:-)</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/08</a>, chenchaogang writes: 打印那个object还是很不方便啊</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/10</a>, <a href="http://blog.iterse.com"  rel="external nofollow"  class="url" >Iterse's blog</a> writes: c的源码看不明白...</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/15</a>, Nathan writes: 能否写一篇详解apc参数的文章？官方的太简略了，部分参数完全不知道是干什么用的</li><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2011/12/18</a>, pytonic writes: 可否给5.2.* 5.3.*加上此功能？
要用上5.4还要很久呢</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/10/26/1768.html"  rel="bookmark"  title="Permanent Link: AllowEncodedSlashes in Apache" >AllowEncodedSlashes in Apache</a></li><li><a href="http://www.laruence.com/2008/08/14/250.html"  rel="bookmark"  title="Permanent Link: 实现PHP的编译执行分离(separating compilation and execution)" >实现PHP的编译执行分离(separating compilation and execution)</a></li><li><a href="http://www.laruence.com/2011/10/19/2247.html"  rel="bookmark"  title="Permanent Link: Zend Signal in PHP 5.4" >Zend Signal in PHP 5.4</a></li><li><a href="http://www.laruence.com/2009/07/19/1003.html"  rel="bookmark"  title="Permanent Link: 使用gettext来支持PHP的多语言" >使用gettext来支持PHP的多语言</a></li><li><a href="http://www.laruence.com/2011/06/23/2057.html"  rel="bookmark"  title="Permanent Link: 如何调试PHP的Core之获取基本信息" >如何调试PHP的Core之获取基本信息</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/06/23/2057.html"  title="如何调试PHP的Core之获取基本信息" >如何调试PHP的Core之获取基本信息</a></li><li><a href="http://www.laruence.com/2011/10/10/2204.html"  title="JsonSerializable接口" >JsonSerializable接口</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/2011/07/14/2115.html"  title="Zend引擎的优化" >Zend引擎的优化</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/2010/09/27/1754.html"  title="PHP stream未能及时清理现场导致Core的bug" >PHP stream未能及时清理现场导致Core的bug</a></li><li><a href="http://www.laruence.com/2009/12/05/1172.html"  title="PHP5.2.x + APC的一个bug的定位" >PHP5.2.x + APC的一个bug的定位</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/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></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/06/2381.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Yaf 2.1性能测试(Yaf 2.1 Benchmark)</title>
		<link>http://www.laruence.com/2011/12/02/2333.html</link>
		<comments>http://www.laruence.com/2011/12/02/2333.html#comments</comments>
		<pubDate>Fri, 02 Dec 2011 05:39:04 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP Extension]]></category>
		<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[Yaf]]></category>
		<category><![CDATA[Yaf Benchmark]]></category>
		<category><![CDATA[Yaf Performance]]></category>
		<category><![CDATA[Yaf性能]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2333</guid>
		<description><![CDATA[   Thanks to Ruilog agian for his work of second <a href="http://www.ruilog.com/blog/view/b6f0e42cf705.html">benchmark of Yaf 2.1</a>. 

   <a href="http://pecl.php.net/package/yaf">Yaf 2.1</a> did a lot of work to improve performance and reduce memory usage, so let's take a look at the result(Yaf 2.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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/12/02/2333.html"  title="Permanet Link to Yaf 2.1性能测试(Yaf 2.1 Benchmark)" >http://www.laruence.com/2011/12/02/2333.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   Thanks to Ruilog agian for his work of second <a href="http://www.ruilog.com/blog/view/b6f0e42cf705.html" >benchmark of Yaf 2.1</a>. </p>
<p>   <a href="http://pecl.php.net/package/yaf" >Yaf 2.1</a> (<a href="http://www.php.net/manual/en/intro.yaf.php" >docs</a>) did a lot of work to improve performance and reduce memory usage, so let&#8217;s take a look at the result(Yaf 2.1重写了很多逻辑来提升性能, 并且降低内存使用率, 改进结果见测试对比): </p>
<p>   <b> First of all,  I have to say, I am not saying the fastest is the best. every framework list blew is outstanding, and has particular situation to deploy. (首先, 我要申明, 不一定最快的就是最好的, 下面的每一个框架都是优秀的框架, 都有它们适用的场景) </b></p>
<p>   <b>Case</b></p>
<p>Test Simple &#8220;Hello World&#8221; page output, Simple MVC logic(Router -> Controller -> Viewer), No Database Connections, No complex logic. Test scripts can be found <a href="https://github.com/eryx/php-framework-benchmark" >here</a>.
</p>
<p>   <b>Hardware platform</b></p>
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li> CPU: Intel Core i5 750 (2.67GHz x4)</li>
<li> RAM: 4GB</li>
</ul>
<p>   <b>Software Environment</b></p>
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>Debian 6.0.3 x86_64 (2.6.32-39)</li>
<li>apache 2.2.16 (mpm-prefork,mod-php5)</li>
<li>php 5.3.8</li>
<li>php-apc 3.1.9 (Optimization for include/require)</li>
<li>Copy all projects to /dev/shm/* (Optimization for files read/write)</li>
</ul>
<h3>1. Apache Benchmark</h3>
<p>  Requests pre second (-c 100 -n 30000), the bigger is better<br/>
  <div id="attachment_2371"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/ab-c100-n300001.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/ab-c100-n300001.png"  alt=""  title="ab-c100-n30000"  width="600"  class="size-full wp-image-2371" /></a><p class="wp-caption-text" >ab -c100 -n30000</p></div></p>
<p>  Requests pre second (-c 200 -n 50000), the bigger is better<br/>
<div id="attachment_2372"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/ab-c200-n500001.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/ab-c200-n500001.png"  alt=""  title="ab-c200-n50000"  width="600"  class="size-full wp-image-2372" /></a><p class="wp-caption-text" >ab -c200 -n50000</p></div></p>
<h3>2. System LoadAvg</h3>
<p>  System LoadAvg in 1 Minute when Apache Benchmark Complete, the smaller is better (-c 100 -n 30000)<br/>
 <div id="attachment_2373"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/loadavg1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/loadavg1.png"  alt=""  title="loadavg"  width="600"  class="size-full wp-image-2373" /></a><p class="wp-caption-text" >System loadavg</p></div></p>
<h3>3. Memory usage</h3>
<p>   How many memory usage in one &#8220;hello world&#8221; page. the smaller is better.<br/>
   <div id="attachment_2374"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/memory-usage1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/memory-usage1.png"  alt=""  title="memory-usage"  width="600"  class="size-full wp-image-2374" /></a><p class="wp-caption-text" >Memory usage</p></div></p>
<h3>4. Response time</h3>
<p>  The time of page request to response.<br/>
  <div id="attachment_2377"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/response-time1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/response-time1.png"  alt=""  title="response-time"  width="600"  class="size-full wp-image-2377" /></a><p class="wp-caption-text" >Response time</p></div></p>
<h3>5.Number of function calls (Facebook XHProf)</h3>
<p>   The number of functions calls in one &#8220;hello world&#8221; page.<br/>
   <div id="attachment_2376"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/number-of-function-calls1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/number-of-function-calls1.png"  alt=""  title="number-of-function-calls"  width="600"  class="size-full wp-image-2376" /></a><p class="wp-caption-text" >Number of function calls</p></div></p>
<h3>6. Number of included files</h3>
<p>   The number of files included or required in one &#8220;hello world&#8221; page. the fewer is better.<br/>
   <div id="attachment_2340"  class="wp-caption aligncenter"  style="width: 610px" ><a href="http://laruence-wordpress.stor.sinaapp.com/uploads/number-of-files1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/number-of-files1.png"  alt=""  title="number-of-files"  width="600"  class="size-full wp-image-2340" /></a><p class="wp-caption-text" >Number of included files</p></div></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;">
Changelog:
  * v20111201 @2011-12-01
    - release
  * v20111201-2 @2011-12-05
    - bugfix: Fix a stupid logic error in bench.php
    - bugfix: Symfony2, Change running mode from 'dev' to 'prod'
</pre>
<p>&#8211;EOF&#8211;</p>
<p>    For more details, plz refer to: <a href="http://www.ruilog.com/blog/view/b6f0e42cf705.html"  target="_blank" >http://www.ruilog.com/blog/view/b6f0e42cf705.html</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/2011/12/02/2333.html" >2011/12/02</a>, <a href="http://www.laruence.com/2011/11/05/2262.html"  rel="external nofollow"  class="url" >Yaf的性能对比测试 | 风雪之隅</a> writes: [...] 后记(2011-12-02补充), Yaf 2.1做一些性能优化的升级, 基于Yaf 2.1的性能测试报告可以参见: Yaf 2.1性能测试(Yaf 2.1 Benchmark) [...]</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/02</a>, 东爷 writes: 牛</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/02</a>, <a href="http://www.howzhi.com"  rel="external nofollow"  class="url" >Wellming</a> writes: 哇塞，Yaf好快耶！

不过symfony2没这么慢吧，性能测试的时候应该用app.php，app_dev.php是开发用的。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/02</a>, KnightE writes: 目录结构中有提到model层，但文档中似乎并未看到。API里也看不到db操作的代码和例子，能否给些例子参考一下。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/02</a>, <a href="http://www.ruilog.com"  rel="external nofollow"  class="url" >Eryx</a> writes: 解释下 app_dev.php 问题:

刚开始的时候，常识用 app.php 引导，但失败(500 error); 而同时 app_dev.php 正常，为了消除 debug 对性能的影响，在 config_dev.yml 中做了如下修改 ([web_profiler] toolbar: false; intercept_redirects: false). 使其可以输出一个干净的 "hello world".
我想，虽然名称上叫做 "dev"， 但实际配置应该和 "app.php" 等同.

Symfony 是一个历史悠久、成熟的商业框架，但我却是第一次使用，如果你有更优化的配置，期待您提交补丁 :)</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/03</a>, helloyou writes: 关于yaf,记得你说过yaf是仿Zfw的,

如果能有个工具帮助现有的ZFW项目快速转换到yaf上,
或者有一个bridge工具来让现有zfw直接在yaf上运行,

应该会让yaf更容易普及

还有上次说的,要有英文手册</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/03</a>, xiatian writes: win下用nginx+php(fcgi)方式无法加载php_yaf.dll,不管是nts还是zts.

提示错误:
“E:\webServer\php\ext\php_yaf.dll”的激活上下文生成失败。 找不到从属程序集 Microsoft.VC90.DebugCRT,processorArchitecture="x86",publicKeyToken="1fc8b3b9a1e18e3b",type="win32",version="9.0.21022.8"。 请使用 sxstrace.exe 进行详细诊断。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/03</a>, <a href="http://www.btcomic.com/"  rel="external nofollow"  class="url" >kernel</a> writes: symfony2这么差啊,ps: yii的表现还不错啊，于是继续用yii</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/03</a>, <a href="http://www.howzhi.com"  rel="external nofollow"  class="url" >Wellming</a> writes: @Eryx 你看下app.php跟app_dev.php文件，

$kernel = new AppKernel('prod', false);
$kernel = new AppKernel('dev', true);

这里第2个参数是，是否开启debug。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/05</a>, venkman writes: 如果虚拟主机上的php不支持或没有安装这个扩展, 那么推广还是有一定的</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/05</a>, Eryx writes: @Wellming Symfony2 的配置确实存在问题，切换到 prod模式后并发大概是 400+, 介于 ZF 1.11 和 2.0 之间</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/06</a>, Thinklong writes: 非常喜欢你的框架，但我希望能让ZendStudio自动提示Yaf里的方法和类，搞了很久，zend6以上的版本无法添加*.so库，鸟哥有没有抽象出来的code文件，或者其他实现方式？</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/06</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @thinklong 我这边没有, 不过你可以借助reflectclass自己生成一个 :)</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/06</a>, dvaknheo writes: 我现在在给某个框架集成支付，搞得很头大。

后来想想，为什么一定要把支付搞在框架里，直接弄个单独的文件不行么？
再后来想想， 不行， 那样就就搞得系统零碎。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/07</a>, Anonymous writes: @雪候鸟 非常感谢！我已经用ReflectionClass把Yaf扩展里的类都抽象出来了，写的很简单，不过可以用^ ^ 这下在zend里开发就方便多了，有需要的同学可以到下面的链接下载http://code.google.com/p/thinklong/downloads/detail?name=Yaf.php&amp;can=2&amp;q=#makechanges</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/24</a>, <a href="http://adamlu.net"  rel="external nofollow"  class="url" >adam.lu</a> writes: Hi, Laruence.  

我在mac os x 10.7.2 上无法安装yaf-2.1.4。

运行phpzie的时候提示：
configure.in:3: warning: prefer named diversions
configure.in:3: warning: prefer named diversions

运行make的时候提示：
yaf.c:265: warning: initialization makes integer from pointer without a cast
yaf.c:266: warning: initialization makes integer from pointer without a cast
yaf.c:266: error: initializer element is not computable at load time
yaf.c:266: error: (near initialization for ‘yaf_module_entry.module_number’)
make: *** [yaf.lo] Error 1</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/24</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @adam.lu 请问你的PHP的版本是?</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/25</a>, <a href="http://adamlu.net"  rel="external nofollow"  class="url" >adam.lu</a> writes: mac os 中的php版本试5.3.8

我在ubuntu中安装编译没有问题，php版本是5.3.3。可是在php.ini中加入扩展（extension=yaf.so）后，apache就无法启动成功：（</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/25</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >laruence</a> writes: @adam.lu 你可以打开php.ini中的display_startup_error看看有什么错误</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/26</a>, keda writes: gcc (Debian 4.4.5-8) 4.4.5 64bit系统。
跟Adam Lu的error一样。。
yaf.c:265: warning: initialization makes integer from pointer without a cast
yaf.c:266: warning: initialization makes integer from pointer without a cast
yaf.c:266: error: initializer element is not computable at load time
yaf.c:266: error: (near initialization for ‘yaf_module_entry.module_number’)
2.1.3却又没有问题。。
我用另一架32bit的debian编译却没有这个问题。。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/26</a>, <a href="http://www.laruence.com/"  rel="external nofollow"  class="url" >laruence</a> writes: @keda @adam.lu 非常感谢你们的反馈, 问题已经修复. 请使用2.1.5beta http://pecl.php.net/package-info.php?package=yaf&amp;version=2.1.5</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2011/12/31</a>, <a href="http://adamlu.net"  rel="external nofollow"  class="url" >adam.lu</a> writes: Hi, laruence
我已经在mac下成功编译了2.1.5
可是在phpize的时候仍然会有一下的warning信息，不知道会不会影响使用。
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626
configure.in:3: warning: prefer named diversions
configure.in:3: warning: prefer named diversions

另外，http://yaf.laruence.com/manual/这个手册还在维护吗？我看到手册中还有不少地方是使用ap而不是yaf这个叫法。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/01/07</a>, keda writes: 不知道这个算不算是个问题，用于决定YAF application config 的 yaf.environ php value似乎只能通过添加到php 本身的ini文件里面来改变，而不能通过ini_set 或者是 修改local htaccess 文件来改变。
如果在一台机器上需要有几个YAF项目以及不同的env值的话，单个值似乎是个问题。。并且改变需要root access，更是问题。。
如果不实之处，请谅解。。</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/01/31</a>, <a href="http://www.laruence.com/"  rel="external nofollow"  class="url" >laruence</a> writes: @keda Yaf_Application的第二个参数: http://www.php.net/manual/en/yaf-application.construct.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/2011/11/05/2262.html"  rel="bookmark"  title="Permanent Link: Yaf的性能对比测试" >Yaf的性能对比测试</a></li><li><a href="http://www.laruence.com/2011/11/04/2258.html"  rel="bookmark"  title="Permanent Link: 三元式(ternary)性能优化" >三元式(ternary)性能优化</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/11/05/2262.html"  title="Yaf的性能对比测试" >Yaf的性能对比测试</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/12/02/2333.html/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>PHP5.4中一个需要注意的变化(Chained string offsets)</title>
		<link>http://www.laruence.com/2011/11/28/2317.html</link>
		<comments>http://www.laruence.com/2011/11/28/2317.html#comments</comments>
		<pubDate>Mon, 28 Nov 2011 06:56:43 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[Chained string offsets]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2317</guid>
		<description><![CDATA[在PHP5.4中, 对字符串多级取值(offset), 做了一个一致性改进. 比如对于下面的例子:
<coolcode lang="php" linenum="off">
<?php
$str  = "laruence";
echo $str[0][0][0][0];
?> 
</coolcode>

   在PHP5.4之前, 上面的代码会导致一个Fatal error:
<coolcode lang="shell" linenum="off">
PHP Fatal error:  Cannot use string offset as an array 
</coolcode>

   这个错误其实很莫名, 因为$str[0], 是'l',  也是一个字符串, 那么按理来说, $str[0][0]还应该是'l',  于是在PHP5.4中,  对这个不一致性做了改进. 但是也带来了一个需要注意的变化.]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/11/28/2317.html"  title="Permanet Link to PHP5.4中一个需要注意的变化(Chained string offsets)" >http://www.laruence.com/2011/11/28/2317.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   在PHP5.4中, 对字符串多级取值(offset), 做了一个一致性改进. 比如对于下面的例子:</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
$str  = &quot;laruence&quot;;
echo $str[0][0][0][0];
?&gt;
</pre>
<p>   在PHP5.4之前, 上面的代码会导致一个Fatal error:</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;">
PHP Fatal error:  Cannot use string offset as an array
</pre>
<p>   这个错误其实很莫名, 因为$str[0], 是&#8217;l',  也是一个字符串, 那么按理来说, $str[0][0]还应该是&#8217;l',  于是在PHP5.4中,  对这个不一致性做了改进. 但是也带来了一个需要注意的变化.</p>
<p>   对于上面的列子, 在PHP5.4将输出&#8221;l&#8221;.</p>
<p>   <b>但是, 这样就带来一个明显的变化:</b></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
  $arr = array(
        &quot;name&quot; =&gt; &quot;laruence&quot;,  //如果这个值有可能是数组,或者字符串.
   );

   if (isset($arr[&quot;name&quot;][&quot;foo&quot;][&quot;non-exists&quot;])) {
        echo &quot;set&quot;;
   }
</pre>
<p> 注意上面的代码, 因为对arra的数组的元素的值类型不确定(有可能是数组,也有可能是字符串),  那么在PHP5.4之前, 上面的代码, 错误的表现出了正确: 不管数组还是字符串, 都可以返回看似正确的没有isset.</p>
<p> 而从5.4开始, 将会输出&#8221;set&#8221;.</p>
<p> 这是为什么呢? </p>
<p>  因为类型转换, 当$arr["name"]是字符串的时候, 对它做offset取值, 都会把键值转换成interge, 所以, &#8220;foo&#8221;和&#8221;non-exists&#8221;都会转换成0.</p>
<p>  也就是,  $arr["name"][0][0], 所以isset为真. </p>
<p>  当然, 如果你之前一直是使用array_key_exists的话, 这个变化倒也影响不到你. </p>
<p>  这个变化需要以后<b>在你不能保证一个数组中值的类型的(数组,字符串)的时候,  如果做isset操作, 需要增加一些额外的is_array判断.</b>..</p>
<p>  不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>    谢谢</p>
<p>    更多更新信息, 请关注: <a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?view=markup"  target="_blank" >Changelog</a><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_shell.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/11/28/2317.html" >2011/11/28</a>, <a href="http://liuw.net"  rel="external nofollow"  class="url" >liuw</a> writes: 多谢指明，之前也有碰到多维数组中神奇的Cannot use string offset as an array的问题。</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/11/28</a>, <a href="http://www.cnxct.com"  rel="external nofollow"  class="url" >CFC4N</a> writes: 调试bug将更难了。</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/11/28</a>, <a href="http://www.shibeike.net"  rel="external nofollow"  class="url" >treesky</a> writes: 代码要更加仔细了。</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/11/28</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @treesky @CFC4N 没那么夸张了, 主要是保证数据结构的正确性就行了. :)</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/11/28</a>, <a href="http://xiezhenye.com"  rel="external nofollow"  class="url" >神仙</a> writes: 字符串到数字的无缝转换是一个很容易引发bug的地方。

在字符串不是数字表达式的时候，能抛个warning么</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/11/29</a>, <a href="http://bee.glroomy.com/"  rel="external nofollow"  class="url" >Qianfeng</a> writes: 这个还真的是个问题!

如果是字符串的offset 只有纯数字才做转换，数字不做转换就好了~


比如 $arr["name"]["foo"] foo 不会转成0

而 ($arr["name"]['0']  才会转出 0</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/12/01</a>, shaukei writes: 很少用isset。应该这个对我影响不大！</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/12/02</a>, Lisces writes: 这个算feature么 感觉这个变化不但没什么实用价值 而且还会引起很多老代码的潜在问题 为什么要做这样的设计呢？</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/12/02</a>, xiefei writes: 这个问题会引起查找困难，不能让字符串强制转换成int类型才行，否则要给出warning错误。</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/12/10</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/2011/11/28/2317.html" >2011/12/12</a>, <a href="http://liuxd.blog.chinaunix.net"  rel="external nofollow"  class="url" >Liuxd</a> writes: 真心希望PHP把数据类型控制的严格些，弱类型使得很多时候在数据类型上出问题，即使不出问题也要为类型转换伤很多脑筋。虽然不指望能像C那么明确，但是至少错误提示能更想详细些，减少调试成本。

感慨下，PHP这种脚本语言大多松散类型，看似是为了降低学习门槛、提高开发效率。但是当要严格控制代码质量的时候，其实松散类型是最讨厌的，唉～</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/12/14</a>, <a href="http://3haku.net"  rel="external nofollow"  class="url" >princehaku</a> writes: 学习了.</li><li><a href="http://www.laruence.com/2011/11/28/2317.html" >2011/12/19</a>, <a href="http://www.laruence.com/2011/12/19/2409.html"  rel="external nofollow"  class="url" >之前提到的PHP5.4一个注意点的update | 风雪之隅</a> writes: [...] 我曾经介绍过, 在PHP5.4中, PHP5.4中一个需要注意的变化(Chained string offsets) , 后续因为大多数人都表示这个变化很敏感, 容易成为坑.. 于是, [...]</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/12/19/2409.html"  rel="bookmark"  title="Permanent Link: 之前提到的PHP5.4一个注意点的update" >之前提到的PHP5.4一个注意点的update</a></li><li><a href="http://www.laruence.com/2008/09/20/523.html"  rel="bookmark"  title="Permanent Link: PHP5.3 α2初体验" >PHP5.3 α2初体验</a></li><li><a href="http://www.laruence.com/2011/03/29/1949.html"  rel="bookmark"  title="Permanent Link: 深入理解PHP原理之Session Gc的一个小概率Notice" >深入理解PHP原理之Session Gc的一个小概率Notice</a></li><li><a href="http://www.laruence.com/2008/08/19/338.html"  rel="bookmark"  title="Permanent Link: PHP的单引号和双引号" >PHP的单引号和双引号</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  rel="bookmark"  title="Permanent Link: PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</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/12/19/2409.html"  title="之前提到的PHP5.4一个注意点的update" >之前提到的PHP5.4一个注意点的update</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/11/2296.html"  title="PHP5.4新特性-解引用实例化" >PHP5.4新特性-解引用实例化</a></li><li><a href="http://www.laruence.com/2011/11/04/2258.html"  title="三元式(ternary)性能优化" >三元式(ternary)性能优化</a></li><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/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2011/10/10/2229.html"  title="函数类型提示(Callable typehint)" >函数类型提示(Callable typehint)</a></li><li><a href="http://www.laruence.com/2011/10/10/2217.html"  title="上传进度支持(Upload progress in sessions)" >上传进度支持(Upload progress in sessions)</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/2011/10/10/2204.html"  title="JsonSerializable接口" >JsonSerializable接口</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/11/28/2317.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>GBK编码PHP脚本导致语法错误(Zend Multibyte)</title>
		<link>http://www.laruence.com/2011/11/18/2305.html</link>
		<comments>http://www.laruence.com/2011/11/18/2305.html#comments</comments>
		<pubDate>Fri, 18 Nov 2011 09:20:08 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[declare]]></category>
		<category><![CDATA[encoding]]></category>
		<category><![CDATA[gbk]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend multibyte]]></category>
		<category><![CDATA[编码转换]]></category>
		<category><![CDATA[语法错误]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2305</guid>
		<description><![CDATA[   <a href="http://weibo.com/laruence">微薄</a>上有同学问我:
<coolcode lang="bash" linenum="off"> 
     GBK环境下如下php代码：<?php echo("洪仁玕");?> 会引发php的语法错误，如何解决？
</coolcode>

   这个是因为, 在GBK环境下, "玕"的编码是"0xab 0x5c,  所以, 又是一个'5c'引发的问题..

   一般来说, 还是建议大家用unicode作为代码文件的字符集,  如果要使用GBK, 再主动转换下.  

   不过, 就问题说问题,  如果你的脚本非要GBK编码, 那怎么避免这个问题呢?]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/11/18/2305.html"  title="Permanet Link to GBK编码PHP脚本导致语法错误(Zend Multibyte)" >http://www.laruence.com/2011/11/18/2305.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   <a href="http://weibo.com/laruence" >微薄</a>上有同学问我:</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;">
     GBK环境下如下php代码：&lt;?php echo(&quot;洪仁玕&quot;);?&gt; 会引发php的语法错误，如何解决？
</pre>
<p>   这个是因为, 在GBK环境下, &#8220;玕&#8221;的编码是&#8221;0xab 0x5c,  所以, 又是一个&#8217;5c&#8217;引发的问题..</p>
<p>   一般来说, 还是建议大家用unicode作为代码文件的字符集,  如果要使用GBK, 再主动转换下.  </p>
<p>   不过, 就问题说问题,  如果你的脚本非要GBK编码, 那怎么避免这个问题呢?</p>
<p>   从PHP5.3开始,  PHP引入了Zend Multibyte来支持多字符集编码.   对于上面的代码, 我们修改如下:</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
declare(encoding=&quot;cp936&quot;);
echo(&quot;洪仁玕&quot;);
?&gt;
</pre>
<p>    然后, 在php.ini中配置: </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;">
mbstring.internal_encoding=cp936
</pre>
<p>  或者通过如下命令运行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;">
$php  -dmbstring.internal_encoding=cp936 test.php
</pre>
<p>   这样, PHP就会以cp936编码方式来执行test.php了.   关于Zend Multibyte的更多信息请参看:<a href="http://serverfault.com/questions/145413/php-what-is-enable-zend-multibyte-configure-option-for" >PHP: what is &#8211;enable-zend-multibyte configure option for?</a>, <a href="http://php.net/manual/en/control-structures.declare.php" >PHP declare</a></p>
<p>    PS, 我在试验PHP5.4 RC1的时候,  发现了一个BUG,  PHP 5.4 不能正确的转换GBK编码到UTF8编码,  不过现在我已经修复. 大家如果遇到这个问题, 请关注马上要发布的PHP5.4 RC2即可..  谢谢<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_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/2011/11/18/2305.html" >2011/11/18</a>, cute writes: mb_internal_encoding("CP936");</li><li><a href="http://www.laruence.com/2011/11/18/2305.html" >2011/11/19</a>, <a href="http://baidu.com"  rel="external nofollow"  class="url" >maifa</a> writes: 我很想听下，又 一个 5C？
又的解释。谢谢。</li><li><a href="http://www.laruence.com/2011/11/18/2305.html" >2011/11/19</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @maifa http://www.laruence.com/2010/04/12/1396.html</li><li><a href="http://www.laruence.com/2011/11/18/2305.html" >2011/11/23</a>, <a href="http://www.pztai.com"  rel="external nofollow"  class="url" >taylor</a> writes: 好诡异的bug啊
最近碰到个因为转码的原因导致$_GET失败的问题，好诡异，最后是因为前段给的链接给urlencode了,纠结</li><li><a href="http://www.laruence.com/2011/11/18/2305.html" >2011/11/23</a>, eve writes: 我觉得是不是可以先用记事本打开代码，然后另存为utf-8编码，这样问题就解决了.您觉得呢</li><li><a href="http://www.laruence.com/2011/11/18/2305.html" >2011/11/29</a>, <a href="http://www.zhaiduo.com"  rel="external nofollow"  class="url" >zhaiduo</a> writes: 我在用mysql_real_escape_string的时候也遇到5c问题，用mysql_escape_string就不会有5c问题。</li><li><a href="http://www.laruence.com/2011/11/18/2305.html" >2011/12/23</a>, <a href="http://ihacklog.com"  rel="external nofollow"  class="url" >荒野无灯</a> writes: 嗯，以前看过gbk字符集下mysql_escape函数的一个0x5c引起的bug~~</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/2008/08/15/274.html"  rel="bookmark"  title="Permanent Link: PHP 源代码分析 V0.0.2" >PHP 源代码分析 V0.0.2</a></li><li><a href="http://www.laruence.com/2008/07/16/225.html"  rel="bookmark"  title="Permanent Link: Zend Engine幻想" >Zend Engine幻想</a></li><li><a href="http://www.laruence.com/2010/06/21/1608.html"  rel="bookmark"  title="Permanent Link: PHP调试技术手册发布(1.0.0 pdf)" >PHP调试技术手册发布(1.0.0 pdf)</a></li><li><a href="http://www.laruence.com/2011/10/10/2229.html"  rel="bookmark"  title="Permanent Link: 函数类型提示(Callable typehint)" >函数类型提示(Callable typehint)</a></li><li><a href="http://www.laruence.com/2011/10/19/2247.html"  rel="bookmark"  title="Permanent Link: Zend Signal in PHP 5.4" >Zend Signal in PHP 5.4</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/11/16/1147.html"  title="分割GBK中文遭遇乱码的解决" >分割GBK中文遭遇乱码的解决</a></li><li><a href="http://www.laruence.com/2009/05/31/889.html"  title="PHP受locale影响的函数" >PHP受locale影响的函数</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></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/11/18/2305.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>PHP5.4新特性-解引用实例化</title>
		<link>http://www.laruence.com/2011/11/11/2296.html</link>
		<comments>http://www.laruence.com/2011/11/11/2296.html#comments</comments>
		<pubDate>Fri, 11 Nov 2011 04:01:37 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[class member access on instantiation]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>
		<category><![CDATA[T_NEW]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2296</guid>
		<description><![CDATA[    在以前的PHP中, 我们并不能直接去操作一个对象实例化的结果:
<coolcode lang="php" linenum="off">
<?php
(new Foo())->show();  //PHP Parse error:  syntax error, unexpected T_OBJECT_OPERATOR
</coolcode>

   我们只能, 把实例化结果先保存起来, 然后再调用:
<coolcode lang="php" linenum="off">
$a = new Foo();
$a->show();
</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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/11/11/2296.html"  title="Permanet Link to PHP5.4新特性-解引用实例化" >http://www.laruence.com/2011/11/11/2296.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<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
(new Foo())-&gt;show();  //PHP Parse error:  syntax error, unexpected T_OBJECT_OPERATOR
</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;">
$a = new Foo();
$a-&gt;show();
</pre>
<p>   关于这个改进, 已经有很多人提出过request, 但是因为实现的问题, 一直没有加入PHP. </p>
<p>   这点上, 我解释下,  PHP的语法分析系统, 是一个历史悠久的系统, 在这个蛮长的的历史中,  不停的修修补补, 或多或少的会造成一些特定的特性. 而如果要重写, 继耗时, 又耗力, 并且很难做到和现在的完全兼容, 所以我想, 要完全重写, 那也只能是PHP6了(替开发组宣布一下, PHP6目前已经停止开发, 也暂时不会有这种提法)</p>
<p>   而, 如果采用修补的方式, 就会引入一个无法解决的移近/归约冲突,  我之前也尝试过实现这个特性, 但是因为遇到这个问题, 所以没有提交..</p>
<p>   不过, 随着对这个特性要求的增多, 慢慢的, 大家觉得, 即使多一个移近/归约冲突,,,, 也没啥吧. 嘿嘿, 所以呢:</p>
<p>   现在, 这个特性终于在Felipe(<a href="https://wiki.php.net/rfc/instance-method-call"  target="_blank" >Instance and method call/property access</a>)的工作下, 得到了支持,  现在我们就可以书写如下的语法了:</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
(new foo())-&gt;bar()
(new $foo())-&gt;bar
(new $bar-&gt;y)-&gt;x
(new foo)[0]
</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;">
new $bar-&gt;y-&gt;x;
</pre>
<p>  此时, 就会有矛盾, 到底是(new $bar)->y呢, 还是(new $bar->y)->x呢.</p>
<p>  另外一个原因, 也是因为PHP目前的语法系统, 如果采用不加括号的做法, 那么就会更多的引入一个移近/归约冲突.</p>
<p>  不过我相信这个括号也没什么, 起码看起来也更清晰一些.</p>
<p>   说到这里, 插个题外话, 我很好奇, C++的语法分析, 那得有多少已知的无法解决的&#8221;移近/归约&#8221;冲突啊, 有知道的朋友么? 呵呵. (后记, gcc从3.0开始不再使用lex/yacc, 不过从gcc-2.95.1的代码中, 我们可以发现, gcc的已知无法解决的移近/归约冲突为: 51(%expect 51 in gcc-2.95.1/gcc/c-parse.y), 呵呵)</p>
<p>   目前, 5.4RC1已经发布, 大家有兴趣的, 可以提早试用, 也帮PHP做做测试:) <a href="http://www.php.net/archive/2011.php#id2011-11-11-1" >PHP 5.4RC1</a>, enjoy!</p>
<p>   不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>    谢谢</p>
<p>    更多更新信息, 请关注: <a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?view=markup"  target="_blank" >Changelog</a><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/11/11/2296.html" >2011/11/11</a>, <a href="http://weibo.com/pangee"  rel="external nofollow"  class="url" >pangee</a> writes: 嗯~ 又出新东西了</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, venkman writes: 希望php的运行速度更快, 另外就是各个库函数的命名和参数, 返回值要更规范些</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, <a href="http://blog.webfuns.net"  rel="external nofollow"  class="url" >tomheng</a> writes: PHP6停止开发是什么意思，是指开发结束，还是放弃了不开放了？</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @tomheng 是暂时不开发了. 目前要维护5.3和5.4俩个分支.</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, <a href="http://hi.baidu.com/blue5tar_"  rel="external nofollow"  class="url" >blue5tar</a> writes: 有函数支持吗 

function func(){
    return new cls();
    //return array(1,2);
}

func()-&gt;property;
func()[0];

这种！！</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, <a href="http://liuxd.blog.chinaunix.net"  rel="external nofollow"  class="url" >Liuxd</a> writes: 其实相比新特性，我跟期待能把老毛病改改。
PHP6怎么暂停了啊？还指望能像Python3那样抛掉包袱重新开始呢。PHP现在命名太乱，还有一堆函数别名也比较讨厌，其实把这些货搞掉就舒服多了。</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, <a href="http://www.freefcw.info"  rel="external nofollow"  class="url" >巫山霏云</a> writes: 原来只是暂停开发了啊，我说呢……
5.3应该进入成熟期了吧，不知道5.4会怎样</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/11</a>, <a href="http://xiezhenye.com/"  rel="external nofollow"  class="url" >神仙</a> writes: 5.4多的这两特性可以少写一行代码，少个临时变量。

话说，咱换个链接吧。</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/13</a>, Dennis writes: 我希望 "on the fly array dereference" 可以将来实现。

比如所：

function test()
{ return array(1,2,3); }

test()[0]; // 1
test()[1]; // 2</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/13</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @Dennis 这个已经实现了, 看我之前的blog :)</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/14</a>, <a href="http://deloz.net"  rel="external nofollow"  class="url" >deloz</a> writes: 能实现这种吗?
class Foo(){
public function show();
}
$a = new Foo();
$b = 'show';
$a[$b]();</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/14</a>, <a href="http://qitiancom.com"  rel="external nofollow"  class="url" >朱宝祥</a> writes: 囧~我真菜~~~</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/15</a>, <a href="http://levi.cg.am"  rel="external nofollow"  class="url" >李惟</a> writes: 看上去想JS中的闭包，我觉得还是蛮清晰的。</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/24</a>, hzj629206 writes: 如果new和-&gt;都算操作符，根据操作符结合性和优先级是可以解释不加括号的情况吧？</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/28</a>, JunsGo writes: 关于preg_replace这个函数奇怪的东一点
$name = 'Collector g     	 Minerals ';

echo preg_replace('/[\s]+/','-',$name);
//output "Collector-g-Minerals-"这个是正确的,但是用
echo preg_replace('/[\s]*/','-',$name);
//output "-C-o-l-l-e-c-t-o-r--g--M-i-n-e-r-a-l-s--"会在每个字左右都放一个"-"不知道是为什么??</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/11/28</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @JunsGo +:至少一个, *:0个或多个.</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/12/01</a>, <a href="http://yanbingbing.com"  rel="external nofollow"  class="url" >kakalong</a> writes: good job, 啥时候能用上5.4啊</li><li><a href="http://www.laruence.com/2011/11/11/2296.html" >2011/12/08</a>, JunsGo 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/2011/03/29/1949.html"  rel="bookmark"  title="Permanent Link: 深入理解PHP原理之Session Gc的一个小概率Notice" >深入理解PHP原理之Session Gc的一个小概率Notice</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  rel="bookmark"  title="Permanent Link: PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2008/09/20/523.html"  rel="bookmark"  title="Permanent Link: PHP5.3 α2初体验" >PHP5.3 α2初体验</a></li><li><a href="http://www.laruence.com/2011/07/02/2097.html"  rel="bookmark"  title="Permanent Link: PHP5.4的新特性" >PHP5.4的新特性</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  rel="bookmark"  title="Permanent Link: 二进制直接量(binary number format)" >二进制直接量(binary number format)</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/12/19/2409.html"  title="之前提到的PHP5.4一个注意点的update" >之前提到的PHP5.4一个注意点的update</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/28/2317.html"  title="PHP5.4中一个需要注意的变化(Chained string offsets)" >PHP5.4中一个需要注意的变化(Chained string offsets)</a></li><li><a href="http://www.laruence.com/2011/11/04/2258.html"  title="三元式(ternary)性能优化" >三元式(ternary)性能优化</a></li><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/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2011/10/10/2229.html"  title="函数类型提示(Callable typehint)" >函数类型提示(Callable typehint)</a></li><li><a href="http://www.laruence.com/2011/10/10/2217.html"  title="上传进度支持(Upload progress in sessions)" >上传进度支持(Upload progress in sessions)</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/2011/10/10/2204.html"  title="JsonSerializable接口" >JsonSerializable接口</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/11/11/2296.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>PHP原理之内存管理中难懂的几个点</title>
		<link>http://www.laruence.com/2011/11/09/2277.html</link>
		<comments>http://www.laruence.com/2011/11/09/2277.html#comments</comments>
		<pubDate>Wed, 09 Nov 2011 09:50:09 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[zend mm]]></category>
		<category><![CDATA[内存管理]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2277</guid>
		<description><![CDATA[     PHP的内存管理,  分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理.  而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等.

     另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法.  而在我们平时开发扩展, 修复PHP的bug的时候, 却对这一部分的知识需要有一个良好的理解. PHP开发组内的很多朋友也对这块不是很清楚, 所以我觉得有必要专门写一下.

     一些基本的概念, 我就不赘述了, 因为看代码很容易能看懂,  我这里就主要介绍几个看代码没那么容易看懂的点,  为什么这么说呢,  呵呵, 我在写文章之前, 查找了下已有的资料, 已避免重复功,  其中看到了TIPI项目对这部分的描述,  发现其中错误很多.  所以, 我想这部分就是看代码也没那么容易看懂的点 :)]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/11/09/2277.html"  title="Permanet Link to PHP原理之内存管理中难懂的几个点" >http://www.laruence.com/2011/11/09/2277.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
     PHP的内存管理,  分为俩大部分, 第一部分是PHP自身的内存管理, 这部分主要的内容就是引用计数, 写时复制, 等等面向应用的层面的管理.  而第二部分就是今天我要介绍的, zend_alloc中描写的关于PHP自身的内存管理, 包括它是如何管理可用内存, 如何分配内存等.</p>
<p>     另外, 为什么要写这个呢, 因为之前并没有任何资料来介绍PHP内存管理中使用的策略, 数据结构, 或者算法.  而在我们平时开发扩展, 修复PHP的bug的时候, 却对这一部分的知识需要有一个良好的理解. PHP开发组内的很多朋友也对这块不是很清楚, 所以我觉得有必要专门写一下.</p>
<p>     一些基本的概念, 我就不赘述了, 因为看代码很容易能看懂,  我这里就主要介绍几个看代码没那么容易看懂的点,  为什么这么说呢,  呵呵, 我在写文章之前, 查找了下已有的资料, 已避免重复功,  其中看到了TIPI项目对这部分的描述,  发现其中错误很多.  所以, 我想这部分就是看代码也没那么容易看懂的点 <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> </p>
<p>     目前, 英文版的介绍也在撰写中: <a href="https://wiki.php.net/internals/zend_mm" >Zend MM</a></p>
<p>     Zend Memory Manager, 以下简称Zend MM, 是PHP中内存管理的逻辑.  其中有一个关键数据结构: zend_mm_heap:<br/>
<a href="http://laruence-wordpress.stor.sinaapp.com/uploads/zend_mm.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/zend_mm.png"  alt=""  title="zend_mm"  width="597"  height="451"  class="aligncenter size-full wp-image-2278" /></a></p>
<p>     Zend MM把内存非为小块内存和大块内存俩种, 区别对待, 对于小块内存, 这部分是最最常用的, 所以追求高性能. 而对于大块内存, 则追求的是稳妥, 尽量避免内存浪费.</p>
<p>     所以, 对于小块内存, PHP还引入了cache机制:<br/>
<a href="http://laruence-wordpress.stor.sinaapp.com/uploads/zend_mm_cache.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/zend_mm_cache.png"  alt=""  title="zend_mm_cache"  width="521"  height="385"  class="aligncenter size-full wp-image-2284" /></a></p>
<p>     Zend MM 希望通过cache尽量做到, 一次定位就能查找分配.</p>
<p>     而一个不容易看懂的点是free_buckets的申明:</p>
<p>     Q: 为什么free_buckets数组的长度是ZEND_MM_NUMBER_BUCKET个? </p>
<p>     A: 这是因为, PHP在这处使用了一个技巧, 用一个定长的数组来存储ZEND_MM_NUMBER_BUCKET个zend_mm_free_block, 如上图中红色框所示.  对于一个没有被使用的free_buckets的元素, 唯一有用的数据结构就是next_free_block和prev_free_block, 所以, 为了节省内存, PHP并没有分配ZEND_MM_NUMBER_BUCKET * sizeof(zend_mm_free_block)大小的内存, 而只是用了ZEND_MM_NUMBER_BUCKET * (sizeof(*next_free_block) + sizeof(*prev_free_block))大小的内存..</p>
<p>    我们来看ZEND_MM_SMALL_FREE_BUCKET宏的定义:</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 ZEND_MM_SMALL_FREE_BUCKET(heap, index) \
    (zend_mm_free_block*) ((char*)&amp;heap-&gt;free_buckets[index * 2] + \
        sizeof(zend_mm_free_block*) * 2 - \
        sizeof(zend_mm_small_free_block))
</pre>
<p>    之后, Zend MM 保证只会使用prev和next俩个指针, 所以不会造成内存读错..</p>
<p>    那么, 第二个不容易看懂的点, 就是PHP对large_free_buckets的管理, 先介绍分配(TIPI项目组对此部分的描述有些含糊不清):</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;">
static zend_mm_free_block *zend_mm_search_large_block(zend_mm_heap *heap, size_t true_size)
</pre>
<p>   large_free_buckets可以说是一个建树和双向列表的结合:<br/>
<a href="http://laruence-wordpress.stor.sinaapp.com/uploads/zend_mm_large_buckets1.png" ><img src="http://laruence-wordpress.stor.sinaapp.com/uploads/zend_mm_large_buckets1.png"  alt=""  title="zend_mm_large_buckets"  class="aligncenter size-full wp-image-2292" /></a></p>
<p>   large_free_buckets使用一个宏来决定某个大小的内存, 落在什么index上:</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 ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)
</pre>
<p>   zend_mm_high_bit获取true_size中最高位1的序号(zend_mm_high_bit), 对应的汇编指令是bsr(此处, TIPI项目错误的说明为: &#8220;这个hash函数用来计算size的位数，返回值为size二进码中1的个数-1&#8243;).</p>
<p>   也就是说, 每一个在large_free_buckets中的元素, 都保持着指向一个大小为在对应index处为1的size的内存块的指针.  诶, 有点绕口, 举个例子:</p>
<p>   比如对于large_free_buckets[2], 就只会保存, 大小在0b1000到0b1111大小的内存. 再比如: large_free_buckets[6], 就保存着大小为0b10000000到0b11111111大小的内存的指针.</p>
<p>   这样, 再分配内存的时候, Zend MM就可以快速定位到最可能适合的区域来查找. 提高性能.</p>
<p>   而, 每一个元素又同时是一个双向列表, 保持着同样size的内存块, 而左右孩子(child[0]和child[1])分别代表着键值0和1, 这个键值是指什么呢?</p>
<p>   我们来举个例子, 比如我向PHP申请一个true_size为0b11010大小的内存, 经过一番步骤以后, 没有找到合适的内存, PHP进入了zend_mm_search_large_block的逻辑来在large_free_buckets中寻找合适的内存:</p>
<p>1. 首先, 计算true_size对应的index,  计算方法如之前描述的ZEND_MM_LARGE_BUCKET_INDEX</p>
<p>2. 然后在一个位图结构中, 判断是否存在一个大于true_size的可用内存已经存在于large_free_buckets, 如果不存在就返回:</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;">
size_t bitmap = heap-&gt;large_free_bitmap &gt;&gt; index;
if (bitmap == 0) {
   return NULL;
}
</pre>
<p>3. 判断, free_buckets[index]是否存在可用的内存:</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;">
if (UNEXPECTED((bitmap &amp; 1) != 0))
</pre>
<p>4. 如果存在, 则从free_buckets[index]开始, 寻找最合适的内存, 步骤如下:</p>
<p>    4.1.  从free_buckets[index]开始,  如果free_buckets[index]当前的内存大小和true_size相等, 则寻找结束, 成功返回.</p>
<p>    4.2.  查看true_size对应index后(true_size << (ZEND_MM_NUM_BUCKETS - index))的当前最高位, 如果为1.  则在free_buckets[index]->child[1]下面继续寻找, 如果free_buckets[index]->child[1]不存在, 则跳出.  如果true_size的当前最高位为0, 则在free_buckets[index]->child[0]下面继续寻找, 如果free_buckets[index]->child[0]不存在, 则在free_buckets[index]->child[1]下面寻找最小内存(因为此时可以保证, 在free_buckets[index]->child[1]下面的内存都是大于true_size的)</p>
<p>    4.3. 出发点变更为2中所述的child, 左移一位ture_size. </p>
<p>5. 如果上述逻辑并没有找到合适的内存, 则寻找最小的&#8221;大块内存&#8221;:</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;">
   /* Search for smallest &quot;large&quot; free block */
    best_fit = p = heap-&gt;large_free_buckets[index + zend_mm_low_bit(bitmap)];
    while ((p = p-&gt;child[p-&gt;child[0] != NULL])) {
        if (ZEND_MM_FREE_BLOCK_SIZE(p) &lt; ZEND_MM_FREE_BLOCK_SIZE(best_fit)) {
            best_fit = p;
        }
    }
</pre>
<p>注意上面的逻辑,  (p = p->child[p->child[0] != NULL]), PHP在尽量寻找最小的内存.</p>
<p>为什么说, large_free_buckets是个键树呢,  从上面的逻辑我们可以看出, PHP把一个size, 按照二进制的0,1做键, 把内存大小信息反应到了键树上, 方便了快速查找.</p>
<p>另外, 还有一个rest_buckets,  这个结构是个双向列表,  用来保存一些PHP分配后剩下的内存, 避免无意义的把剩余内存插入free_buckets带来的性能问题(此处, TIPI项目错误的描述为: &#8220;这是一个只有两个元素的数组。 而我们常用的插入和查找操作是针对第一个元素，即heap->rest_buckets[0]&#8220;).<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><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><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_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/11/09/2277.html" >2011/11/09</a>, <a href="http://weibo.com/walu"  rel="external nofollow"  class="url" >walu</a> writes: 先mark，慢慢看</li><li><a href="http://www.laruence.com/2011/11/09/2277.html" >2011/11/09</a>, <a href="http://www.pztai.com"  rel="external nofollow"  class="url" >taylor</a> writes: 最近在看php的源代码，觉得好多东西都得再看几遍才能理解</li><li><a href="http://www.laruence.com/2011/11/09/2277.html" >2011/11/09</a>, <a href="http://developerblog.org"  rel="external nofollow"  class="url" >浪</a> writes: 这个必须得顶啊</li><li><a href="http://www.laruence.com/2011/11/09/2277.html" >2011/11/10</a>, <a href="http://mcknight0219.blogspot.com/"  rel="external nofollow"  class="url" >Qiang</a> writes: 大神，你的那个示意图画得不怎么直观啊:)</li><li><a href="http://www.laruence.com/2011/11/09/2277.html" >2011/11/10</a>, liexusong writes: 不太好懂~</li><li><a href="http://www.laruence.com/2011/11/09/2277.html" >2011/12/03</a>, henosteven writes: 估计的看几遍 , 才会懂</li><li><a href="http://www.laruence.com/2011/11/09/2277.html" >2011/12/31</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</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" >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/03/04/1894.html"  title="深入理解PHP内存管理之谁动了我的内存" >深入理解PHP内存管理之谁动了我的内存</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/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></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/11/09/2277.html/feed</wfw:commentRss>
		<slash:comments>7</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>三元式(ternary)性能优化</title>
		<link>http://www.laruence.com/2011/11/04/2258.html</link>
		<comments>http://www.laruence.com/2011/11/04/2258.html#comments</comments>
		<pubDate>Fri, 04 Nov 2011 03:07:33 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>
		<category><![CDATA[ternary]]></category>
		<category><![CDATA[三元式]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2258</guid>
		<description><![CDATA[    PHP 5.4 由Arnaud 引入了一个对三元式的优化方案. 

    我们都知道PHP用<a href="http://www.laruence.com/2008/09/19/520.html">写时复制</a>来对变量复制做性能优化, 而在以前的三元式中, 却每次都会复制, 这在操作数是大数组的情况下, 会造成性能问题:
<coolcode lang="php" linenum="off">
<?php
$a = range(1, 1000);
$i = 0;

$start = microtime(true);
while (++$i < 1000) {
    $b = isset($a)? $a : NULL;
}

var_dump(microtime(true) - $start);
</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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/11/04/2258.html"  title="Permanet Link to 三元式(ternary)性能优化" >http://www.laruence.com/2011/11/04/2258.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    PHP 5.4 由Arnaud 引入了一个对三元式的优化方案. </p>
<p>    我们都知道PHP用<a href="http://www.laruence.com/2008/09/19/520.html" >写时复制</a>来对变量复制做性能优化, 而在以前的三元式中, 却每次都会复制, 这在操作数是大数组的情况下, 会造成性能问题:</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
$a = range(1, 1000);
$i = 0;

$start = microtime(true);
while (++$i &lt; 1000) {
    $b = isset($a)? $a : NULL;
}

var_dump(microtime(true) - $start);
</pre>
<p>    相比, 我们采用if-else来做同样的功能:</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
$a = range(1, 1000);
$i = 0;

$start = microtime(true);
while (++$i &lt; 1000) {
    if (isset($a)) {
        $b = $a;
    } else {
        $b = NULL;
    }
}
var_dump(microtime(true) - $start);
</pre>
<p>    前者在我的机器上, 运行时间为: float(0.0448620319366), 而采用if-else则是: float(0.000280006027222)</p>
<p>    为此, Arnaud提供了一个<a href="http://svn.php.net/viewvc?view=revision&#038;revision=318191" >patch</a>, 来对三元式做了一个优化, 使得三元式不会每次都复制操作数, 在优化以后, 开头给的例子的运行时间降低为: float(0.00029182434082031)</p>
<blockquote><p>
The ternary operator always copies its second or third operand, which is very<br/>
slow compared to an if/else when the operand is an array for example:</p>
<p>$a = range(0,9);</p>
<p>// this takes 0.3 seconds here:</p>
<p>for ($i = 0; $i < 5000000; ++$i) {<br/>
       if (true) {<br/>
               $b = $a;<br/>
       } else {<br/>
               $b = $a;<br/>
       }<br/>
}</p>
<p>// this takes 3.8 seconds:</p>
<p>for ($i = 0; $i < 5000000; ++$i) {<br/>
       $b = true ? $a : $a;<br/>
}</p>
<p>I've tried to reduce the performance hit by avoiding the copy when possible<br/>
(patch attached).</p>
<p>Benchmark:</p>
<p>Without patch: (the numbers are the time taken to run the code a certain<br/>
amount of times)</p>
<p>$int = 0;<br/>
$ary = array(1,2,3,4,5,6,7,8,9);</p>
<p>true ? 1 : 0        0.124<br/>
true ? 1+0 : 0      0.109<br/>
true ? $ary : 0     2.020 !<br/>
true ? $int : 0     0.103<br/>
true ? ${'ary'} : 0 2.290 !<br/>
true ?: 0           0.091<br/>
1+0 ?: 0            0.086<br/>
$ary ?: 0           2.151 !<br/>
${'var'} ?: 0       2.317 !</p>
<p>With patch:</p>
<p>true ? 1 : 0        0.124<br/>
true ? 1+0 : 0      0.195<br/>
true ? $ary : 0     0.103<br/>
true ? $int : 0     0.089<br/>
true ? ${'ary'} : 0 0.103<br/>
true ?: 0           0.086<br/>
1+0 ?: 0            0.159<br/>
$cv ?: 0            0.090<br/>
${'var'} ?: 0       0.089</p>
<p>The array copying overhead is eliminated. There is however a slowdown in some<br/>
of the cases, but overall there is no completely unexpected performance hit as<br/>
it is the case currently.
</p></blockquote>
<p>    不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>    谢谢</p>
<p>    更多更新信息, 请关注:<a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?view=markup"  target="_blank" >Changelog</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></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/04/2258.html" >2011/11/04</a>, <a href="http://www.feiyan.info"  rel="external nofollow"  class="url" >飞晏</a> writes: 没想到此前三元运算的效率会比if/else差这么多
三元运算代码中使用的非常多，这个优化还是很有用的</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/04</a>, 莫北 writes: 不太同意ls的观点，从这里来看确实是效率高好多，但是实际过程中$b总是会被使用的，到时候再复制的效率近乎就一样了，所以我太同意过分强调if/else代替三元操作这种简单的写法，降低代码的简洁性。。。</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/04</a>, mahone writes: 三元确实用的比较多，这个优化需要。。。学习了。。。</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/04</a>, <a href="http://www.cnxct.com"  rel="external nofollow"  class="url" >CFC4N</a> writes: 三元运算居然比if else 效率差，以前都没注意过。颠覆了我对三元运算的认识。</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/04</a>, <a href="http://willko.javaeye.com"  rel="external nofollow"  class="url" >willko</a> writes: 鸟哥，请教下。
如果
$a = bool ? $a : 1;

这样 $a 每次都会赋值吗？</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/06</a>, 小蔡 writes: 真是没想到呀</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/17</a>, 俺是乡下人 writes: 把isset($a)改成isset($a[$i]) 结果就不一样了</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/21</a>, kkjames writes: To 6楼
$b即使被用到也不代表会被写入，所以不一定有复制操作.</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/11/23</a>, <a href="http://qing.thinksaas.cn"  rel="external nofollow"  class="url" >anythink</a> writes: 哈哈 果然， 用if else 还是正解</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2011/12/10</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/2011/11/04/2258.html" >2011/12/14</a>, Jacky writes: 这个优化很好很强大，我也发现这个问题，我都在考虑是不是全部要改成if/else来处理了。希望能早日出release版本。</li><li><a href="http://www.laruence.com/2011/11/04/2258.html" >2012/01/03</a>, zerox 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" >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/19/2409.html"  title="之前提到的PHP5.4一个注意点的update" >之前提到的PHP5.4一个注意点的update</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/28/2317.html"  title="PHP5.4中一个需要注意的变化(Chained string offsets)" >PHP5.4中一个需要注意的变化(Chained string offsets)</a></li><li><a href="http://www.laruence.com/2011/11/11/2296.html"  title="PHP5.4新特性-解引用实例化" >PHP5.4新特性-解引用实例化</a></li><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/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2011/10/10/2229.html"  title="函数类型提示(Callable typehint)" >函数类型提示(Callable typehint)</a></li><li><a href="http://www.laruence.com/2011/10/10/2217.html"  title="上传进度支持(Upload progress in sessions)" >上传进度支持(Upload progress in sessions)</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/2011/10/10/2204.html"  title="JsonSerializable接口" >JsonSerializable接口</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/11/04/2258.html/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Zend Signal in PHP 5.4</title>
		<link>http://www.laruence.com/2011/10/19/2247.html</link>
		<comments>http://www.laruence.com/2011/10/19/2247.html#comments</comments>
		<pubDate>Wed, 19 Oct 2011 03:17:41 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[PHP5.4新特性]]></category>
		<category><![CDATA[timeout]]></category>
		<category><![CDATA[zend signal]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2247</guid>
		<description><![CDATA[  在PHP5.4中, 根据由Rasmus提交的RFC, 引入了一套新的信号处理机制,  目的是为了使得信号屏蔽机制可以应用到任何SAPI中, 并且提高在这个过程中的PHP性能. 

      新的机制, 叫做zend signal, 它的理念, 来自Yahoo的"延迟信号处理"(Yahoo signal deferring mechanism),  而后, facebook把这套理念加入了PHP中, 为了提升PHP+Apache 1.X下PHP调用ap_block/ap_unblock的性能.

       在详细介绍之前, 我想还是先介绍下引入这个新机制的背景]]></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" >Laruence</a>(<a href="http://www.twitter.com/laruence"  target="meme"  title="Twitter" ><img src="/images/ico-twitter.png" /></a> <a href="http://t.sina.com/laruence"  target="meme"  title="新浪微博" ><img src="/images/ico-sina.png" /></a> <a href="http://fusion.google.com/add?feedurl=http://www.laruence.com/feed"  target="meme"  title="Google阅读器" ><img src="/images/ico-google.png" /></a> <a href="mailto:laruence@yahoo.com.cn"  target="meme"  title="邮件" ><img src="/images/ico-mail.png" /></a>)</li>
<li>本文地址: <a href="http://www.laruence.com/2011/10/19/2247.html"  title="Permanet Link to Zend Signal in PHP 5.4" >http://www.laruence.com/2011/10/19/2247.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
      在PHP5.4中, 根据由Rasmus提交的RFC, 引入了一套新的信号处理机制,  目的是为了使得信号屏蔽机制可以应用到任何SAPI中, 并且提高在这个过程中的PHP性能. </p>
<p>      新的机制, 叫做zend signal, 它的理念, 来自Yahoo的&#8221;延迟信号处理&#8221;(Yahoo signal deferring mechanism),  而后, facebook把这套理念加入了PHP中, 为了提升PHP+Apache 1.X下PHP调用ap_block/ap_unblock的性能.</p>
<p>       在详细介绍之前, 我想还是先介绍下引入这个新机制的背景:</p>
<p>      之前我写过俩篇blog, 介绍过因为超时信号导致PHP crash的案例:<a href="http://www.laruence.com/2011/01/27/1854.html" >深入理解PHP内存管理之一个低概率Core的分析</a>和<a href="http://www.laruence.com/2008/12/31/647.html" >一个低概率的PHP Core dump </a>, 在其中, 我说过, 其实PHP在关键操作的时候, 是预留了信号屏蔽机制的:HANDLE_BLOCK和UNBLOCK_INTERRUPTIONS. 但是, 这俩个宏只是Hook, 需要SAPI自己去实现,  目前来说, 也只有Apache 1.x的SAPI实现了这俩个宏, 也就是使用ap_block和ap_unblock. </p>
<p>     而对于&#8221;<a href="http://www.laruence.com/2008/12/31/647.html" >一个低概率的PHP Core dump </a>&#8220;中所描述的情况,  如果我们为了解决它, 而在每次有错误发生的时刻, 都引入一对屏蔽/取消屏蔽的系统调用, 那么这个性能损失将会很明显, 所以一直没有很好的解决这个问题.</p>
<p>     那么zend signal的做法是:</p>
<p>     1. 在zend engine启动时刻, 会为下面的信号注册信号处理函数:  SIGALRM, SIGHUP, SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2, SIGPROF(*nix下), 如果这些信号已经有了处理函数, 那么会把旧的处理函数保存下来.</p>
<p>     2. 当有信号发生时候, zend_signal_handler_defer会首先判断, 当前是否处于block区域, 如果不是, 则信号对应的旧的处理函数将会被调用.   如果是, 那么信号处理函数不会被立即调用, 而是一直等到HANDLE_UNBLOCK_INTERRUPTIONS以后, 退出block区域, 才调用信号处理函数.  如果有多个信号发生, 则信号将会排队等候.</p>
<p>    3.  zend signal使用zend_signal_globals_t.depth计数, 来判断是否处于block区域,  HANDLE_BLOCK递增, HANDLE_UNBLOCK_INTERRUPTIONS递减.当 zend_signal_globals_t.depth大于0, 则表示在block中, 否则就表示不在. 这样就保证了性能(避免以前调用sigaction来屏蔽信号).</p>
<p>    另外,  zend signal为PHP提供了新的信号处理注册接口:  zend_signal.</p>
<p>    更加详细的信息, 可以参看<a href="https://wiki.php.net/rfc/zendsignals" >[RFC]Zend Singal</a></p>
<p>    在zend signal引入的大背景下, 我终于解决了文章开头所说的超时信号可能导致crash的问题:<a href="http://bugs.php.net/60038" >#60038</a>. (only in 5.4)</p>
<p>    不过, 还是要提醒下: PHP 5.4还处于开发阶段, 在最终release之前, 任何新特性都可能被调整或者更改. 如果大家有任何建议, 也欢迎反馈, 帮助我们使得PHP变得更好.</p>
<p>    谢谢</p>
<p>    更多更新信息, 请关注:<a href="http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/NEWS?view=markup"  target="_blank" >Changelog</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/2011/10/19/2247.html" >2011/10/19</a>, 林中的熊宝宝 writes: 虽然不明白，不过好厉害啊</li><li><a href="http://www.laruence.com/2011/10/19/2247.html" >2011/10/20</a>, <a href="http://www.hujuntao.com"  rel="external nofollow"  class="url" >设计蜂巢</a> writes: 博主是PHP高手啊！</li><li><a href="http://www.laruence.com/2011/10/19/2247.html" >2011/10/20</a>, dongdong writes: 可否移驾看下我一个php问题，挺难的，一堆人吵了半天了。
我想用php做个“互相关联的tag”系统。
就是各个tag之间互相关联，整体形成一个图结构。
我的办法是一个mysql表建3个字段，
id,tag内容,tag和其他tag的关联。
数据库存储数据后，生成array结构的tag内容为缓存，前台直接读取，防止tag多了遍历过大数据库承受不住。

现在问题是这个存储tag关系的array结构，我想构建个图结构的数组，网址中我搞了两个，但不知是否能行，博主是中国第一php牛人，可否看下？

http://bbs.phpchina.com/thread-225148-1-1.html
php两种array结构用来逻辑模拟图，那种更好效率更高</li><li><a href="http://www.laruence.com/2011/10/19/2247.html" >2011/10/21</a>, 小白 writes: @.@能否举个列子？</li><li><a href="http://www.laruence.com/2011/10/19/2247.html" >2011/10/23</a>, liexusong writes: 鸟哥的意思是说PHP5.4支持信号，PHP支持信号靠谱吗？</li><li><a href="http://www.laruence.com/2011/10/19/2247.html" >2011/10/27</a>, Newer writes: 哈哈，5.4中修复了好多博主提供的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" >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/19/2409.html"  title="之前提到的PHP5.4一个注意点的update" >之前提到的PHP5.4一个注意点的update</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/28/2317.html"  title="PHP5.4中一个需要注意的变化(Chained string offsets)" >PHP5.4中一个需要注意的变化(Chained string offsets)</a></li><li><a href="http://www.laruence.com/2011/11/11/2296.html"  title="PHP5.4新特性-解引用实例化" >PHP5.4新特性-解引用实例化</a></li><li><a href="http://www.laruence.com/2011/11/04/2258.html"  title="三元式(ternary)性能优化" >三元式(ternary)性能优化</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/10/10/2229.html"  title="函数类型提示(Callable typehint)" >函数类型提示(Callable typehint)</a></li><li><a href="http://www.laruence.com/2011/10/10/2217.html"  title="上传进度支持(Upload progress in sessions)" >上传进度支持(Upload progress in sessions)</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/2011/10/10/2204.html"  title="JsonSerializable接口" >JsonSerializable接口</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/10/19/2247.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

