<?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>Wed, 02 May 2012 02:21:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>让PHP更快的提供文件下载</title>
		<link>http://www.laruence.com/2012/05/02/2613.html</link>
		<comments>http://www.laruence.com/2012/05/02/2613.html#comments</comments>
		<pubDate>Wed, 02 May 2012 02:17:42 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Xsendfile]]></category>
		<category><![CDATA[下载文件]]></category>
		<category><![CDATA[中文文件名]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2613</guid>
		<description><![CDATA[ 一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.
  
   但是, 这样做, 就没办法做一些统计, 权限检查, 等等的工作.  于是,  很多时候,  我们采用让PHP来做转发, 为用户提供文件下载.
  ]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>作者: <a href="http://www.laruence.com" >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/05/02/2613.html"  title="Permanet Link to 让PHP更快的提供文件下载" >http://www.laruence.com/2012/05/02/2613.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   一般来说, 我们可以通过直接让URL指向一个位于Document Root下面的文件, 来引导用户下载文件.</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
    $file = &quot;/tmp/dummy.tar.gz&quot;;
    header(&quot;Content-type: application/octet-stream&quot;);
    header('Content-Disposition: attachment; filename=&quot;' . basename($file) . '&quot;');
    header(&quot;Content-Length: &quot;. filesize($file));
    readfile($file);
</pre>
<p>     但是这个有一个问题, 就是如果文件是中文名的话, 有的用户可能下载后的文件名是乱码.  </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
    $file = &quot;/tmp/中文名.tar.gz&quot;;

    $filename = basename($file);

    header(&quot;Content-type: application/octet-stream&quot;);

    //处理中文文件名
    $ua = $_SERVER[&quot;HTTP_USER_AGENT&quot;];
    $encoded_filename = urlencode($filename);
    $encoded_filename = str_replace(&quot;+&quot;, &quot;%20&quot;, $encoded_filename);
    if (preg_match(&quot;/MSIE/&quot;, $ua)) {
	header('Content-Disposition: attachment; filename=&quot;' . $encoded_filename . '&quot;');
    } else if (preg_match(&quot;/Firefox/&quot;, $ua)) {
	header(&quot;Content-Disposition: attachment; filename*=\&quot;utf8''&quot; . $filename . '&quot;');
    } else {
	header('Content-Disposition: attachment; filename=&quot;' . $filename . '&quot;');
    }

    header('Content-Disposition: attachment; filename=&quot;' . $filename . '&quot;');
    header(&quot;Content-Length: &quot;. filesize($file));
    readfile($file);
</pre>
<p>    恩, 现在看起来好多了, 不过还有一个问题,  那就是readfile,  虽然PHP的readfile尝试实现的尽量高效, 不占用PHP本身的内存, 但是实际上它还是需要采用MMAP(如果支持), 或者是一个固定的buffer去循环读取文件, 直接输出.</p>
<p>    输出的时候, 如果是Apache + PHP mod, 那么还需要发送到Apache的输出缓冲区. 最后才发送给用户. 而对于Nginx + fpm如果他们分开部署的话, 那还会带来额外的网络IO. </p>
<p>    那么, 能不能不经过PHP这层, 直接让Webserver直接把文件发送给用户呢?  </p>
<p>    今天, 我看到了一个有意思的文章: <a href="http://www.jasny.net/articles/how-i-php-x-sendfile/" >How I PHP: X-SendFile</a>.</p>
<p>    我们可以使用Apache的module <a href="https://tn123.org/mod_xsendfile/" >mod_xsendfile</a>, 让Apache直接发送这个文件给用户:</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
    $file = &quot;/tmp/中文名.tar.gz&quot;;

    $filename = basename($file);

    header(&quot;Content-type: application/octet-stream&quot;);

    //处理中文文件名
    $ua = $_SERVER[&quot;HTTP_USER_AGENT&quot;];
    $encoded_filename = urlencode($filename);
    $encoded_filename = str_replace(&quot;+&quot;, &quot;%20&quot;, $encoded_filename);
    if (preg_match(&quot;/MSIE/&quot;, $ua)) {
	header('Content-Disposition: attachment; filename=&quot;' . $encoded_filename . '&quot;');
    } else if (preg_match(&quot;/Firefox/&quot;, $ua)) {
	header(&quot;Content-Disposition: attachment; filename*=\&quot;utf8''&quot; . $filename . '&quot;');
    } else {
	header('Content-Disposition: attachment; filename=&quot;' . $filename . '&quot;');
    }

    header('Content-Disposition: attachment; filename=&quot;' . basename($file) . '&quot;');

    //让Xsendfile发送文件
    header(&quot;X-Sendfile: $file&quot;);
</pre>
<p>    X-Sendfile头将被Apache处理, 并且把响应的文件直接发送给Client. </p>
<p>     Lighttpd和Nginx也有类似的模块,  大家有兴趣的可以去找找看 <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> <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/05/02/2613.html" >2012/05/02</a>, <a href="http://www.shibeike.net"  rel="external nofollow"  class="url" >treesky</a> writes: 不错，以前readfile的时候就总害怕文件太大出问题。回家测试测试。</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, GaRY writes: 为啥PHP不调用系统底层sendfile调用？直接省掉open，read，write的内核上下文切换。相对会好一点, webserver就做了这些。</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, anylzer writes: android系统的浏览器上中文名的文件的下载多有问题</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, <a href="http://www.114chengdu.com"  rel="external nofollow"  class="url" >流氓</a> writes: 大牛哥, 你好

最近遇到一个mysql索引的很离奇的问题

create table t1(x char(10), y char(10), key hs using(x,y))


describe select * from t1 where x&gt;'dfd'

显示查询使用了索引并且type为range


我不明白为什么hash索引会有这样的行为, 去百度, google, 各大论坛仔细找了都没结果


非常希望能得到你的帮助, 谢谢</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, <a href="http://www.shirne.com"  rel="external nofollow"  class="url" >shirne</a> writes: nginx的是这个吧
http://wiki.nginx.org/X-accel
我试了下，可以用
header('Content-Disposition: attachment; filename="test.zip"');
#http://wiki.nginx.org/X-accel
header('X-Accel-Redirect:/test.zip');</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, 轩脉刃 writes: 原来还有这么个好东西，查了下：
nginx的模块是：http://wiki.nginx.org/XSendfile</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, Gang writes: 鸟哥写的很好，小弟在这里也班门弄斧一下，一个从Ruby On Rails中迁移过来的send_file()方法，具体使用参见 http://api.rubyonrails.org/classes/ActionController/DataStreaming.html#method-i-send_file
[code='php']
 'application/octet-stream',
        'disposition' =&gt; 'attachment'
    );
    $options = array_merge($defaults, $options);

    foreach (array('type', 'disposition') as $arg) {
        if (is_null($options[$arg])) {
            throw new InvalidArgumentException("{$arg} option required");
        }
    }

    $disposition = $options['disposition'];
    if (isset($options['filename'])) {
        $disposition .= "; filename=\"{$options['filename']}\"";
    }

    if (! headers_sent()) {
        header("Content-Type: {$options['type']}");
        header("Content-Disposition: {$disposition}");
        header("Content-Transfer-Encoding: binary");
    }

    $x_sendfile_supported = $options['x_sendfile'] &amp;&amp; in_array('mod_xsendfile', apache_get_modules());
    if (! headers_sent() &amp;&amp; $x_sendfile_supported) {
        header("X-Sendfile: {$path}");
    } else {
        @readfile($path);
    }
}
?&gt;
[/code]</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/02</a>, Gang writes: 呃…好吧，不支持代码片段，代码也被截断了，看这里吧 http://pastie.org/3848723</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/03</a>, wamper writes: Apache的Sendfile模块好像是需要另外安装的，所以可能并不是很通用，我之前的框架里边就采用了这种方法， 
$contentType = $contentType ? $contentType : 'application/octet-stream';
        header("Pragma:public");
        header("Expires:0");
        header("Content-type:" . $contentType . ';charset=UTF-8');
        header("Accept-Ranges:bytes");
        $charset = Config::get('charset');
        if ($charset != 'UTF-8') {
            $mbEncodings = array('GBK'=&gt;'CP936', 'GB2312'=&gt;'CP936');
            if(isset($mbEncodings[$charset])) $charset = $mbEncodings[$charset];
            $fileName = mb_convert_encoding($fileName, $charset, 'UTF-8');
        }
        if ('' != $fileCfg['contents']) {
            ob_clean();
            $fileSize = strlen($fileCfg['contents']);
        } else if ('' != $fileCfg['filepath']){
            ob_clean();
            $fileSize = filesize($fileCfg['filepath']);
        }
        if($fileSize &gt; 0)
        header("Accept-Length:".$fileSize);
        $ua = $_SERVER['HTTP_USER_AGENT'];
        if(preg_match('/firefox/i', $ua)) {
            $fileName = str_replace('+', '%20', urlencode($fileName));
            $fileName = "utf8''" . $fileName;
            header("Content-Disposition:attachment; filename*=\"{$fileName}\"");
        } else if(preg_match('/msie/i', $ua)){
            $fileName = str_replace('+', '%20', urlencode($fileName));
            header("Content-Disposition:attachment; filename=\"{$fileName}\"");
        } else {
            header("Content-Disposition:attachment; filename=\"{$fileName}\"");
        }
        if ('' != $fileCfg['contents']) {
            echo $fileCfg['contents'];
        } else if('' != $fileCfg['filepath']) {
            $serverSoft = $_SERVER['SERVER_SOFTWARE'];
            if(preg_match('/apache/i', $serverSoft)) {
                readfile($fileCfg['filepath']);
            } else if (preg_match('/lighttpd/i', $serverSoft)) {
                header('X-LIGHTTPD-Send-file:' . $fileCfg['filepath']);
            } else if (preg_match('/nginx/i', $serverSoft)) {
                $nginxSendfileMaps = Config::get('NGINX_SENDFILE_MAP');
                if(false == $nginxSendfileMaps) {
                    readfile($fileCfg['filepath']);
                } else {
                    $filePath = $fileCfg['filepath'];
                    foreach($nginxSendfileMaps as $map) {
                        if(0 === strpos($filePath, $map[0])) {
                            $filePath = str_replace($map[0], $map[1], $filePath);
                            break;
                        }
                    }
                    header('X-Accel-Redirect:' . $filePath);
                }
            }
        }</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/04</a>, tanglement writes: 呃，不熟悉php,但是这样不会增加产品对环境的依赖么？如果做迁移，就会有代码修改的成本吧。</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/04</a>, 十一文 writes: 请问哈鸟哥，如果这个要求支持断点续传了？怎么改进</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/04</a>, <a href="http://www.stou.info"  rel="external nofollow"  class="url" >stou</a> writes: 恩，非常不错的做法，刚刚尝试可以正常运行。</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/04</a>, <a href="http://blog.phpwind.me/?p=378"  rel="external nofollow"  class="url" >借助X-sendfile模块实现文件下载速度和性能优化方案 &laquo; 技术支持和经验交流分享型博客</a> writes: [...] &nbsp;&nbsp; php5.4新功能Traits &raquo;  借助X-sendfile模块实现文件下载速度和性能优化方案 本文的灵感来自于:让PHP更快的提供文件下载 [...]</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/09</a>, leoliu writes: 鸟哥
foreach($arr AS $i){
    echo &lt;&lt;&lt;HTML
       $i
    HTML;
}
syntax error, unexpected $end
这个报错是什么原因</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/09</a>, <a href="http://yegle.net"  rel="external nofollow"  class="url" >yegle</a> writes: 这个方案的好处是默认就支持断点续传了

另一个好处是，可以实现对静态文件的ACL访问控制

不过悲剧的是手头的虚拟主机不提供mod_xsendfile…</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/09</a>, <a href="http://www.icarsp.com"  rel="external nofollow"  class="url" >lly</a> writes: 学习了。。</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/09</a>, <a href="http://www.aiyeshi.com/archives/62"  rel="external nofollow"  class="url" >[转] 让PHP更快的提供文件下载 | 风中了了也</a> writes: [...] 本文地址: http://www.laruence.com/2012/05/02/2613.html [...]</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/09</a>, wclssdn writes: 如何判断apache是否支持那个X-Sendfile...</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/09</a>, wclssdn writes: 额.. 看到有人说通过PHP函数获取apache模块列表了.
不知道其他服务端软件是不是这种方式..</li><li><a href="http://www.laruence.com/2012/05/02/2613.html" >2012/05/11</a>, <a href="http://wenjun.in/index.php/archives/343"  rel="external nofollow"  class="url" >让PHP更快的提供文件下载 | 花 生</a> writes: [...] 并且把响应的文件直接发送给Client. 本文转自 风雪之隅  标签：PHP文件下载   上一篇：PHP生成ZIP文件 [...]</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/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/05/02/2613.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>如何为PHP贡献代码</title>
		<link>http://www.laruence.com/2012/04/30/2594.html</link>
		<comments>http://www.laruence.com/2012/04/30/2594.html#comments</comments>
		<pubDate>Mon, 30 Apr 2012 08:48:33 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[随笔]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2594</guid>
		<description><![CDATA[  PHP在之前把源代码迁移到了git下管理,  同时也在github(<a href="https://github.com/php/php-src">https://github.com/php/php-src</a>)上做了镜像, 这样一来, 就方便了更多的开发者为PHP来贡献代码.

    今天写这篇文章, 就是为了给在国内的同学们, 愿意为PHP开源社区做贡献的同学们, 做个示例,  如何为PHP来贡献你的智慧.
]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>作者: <a href="http://www.laruence.com" >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/04/30/2594.html"  title="Permanet Link to 如何为PHP贡献代码" >http://www.laruence.com/2012/04/30/2594.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    PHP在之前把源代码迁移到了git下管理,  同时也在github(<a href="https://github.com/php/php-src" >https://github.com/php/php-src</a>)上做了镜像, 这样一来, 就方便了更多的开发者为PHP来贡献代码.</p>
<p>    今天写这篇文章, 就是为了给在国内的同学们, 愿意为PHP开源社区做贡献的同学们, 做个示例,  如何为PHP来贡献你的智慧.</p>
<p>    现在, 假设你要为贡献一个新特性, 那么你除了要做下面的这些步骤以外, 还需要在wiki.php.net上提交一个RFC, 待会我会介绍这个, 现在让我们先简单点, 假设你只是要为PHP修复一个bug(一般来说, 大家可以在这里发现PHP已经报告的bug: <a href="http://bugs.php.net" >PHP Bugs</a>). 现在假设你已经想好了要怎么修复这个Bug.</p>
<p>   1.  首先, 你需要有一个github的账号, 没有的话, 来这里注册: <a href="https://github.com/signup/free" >注册github</a>.</p>
<p>   2.  Fork PHP的源代码,  在<a href="https://github.com/php/php-src" >PHP的Github</a>页面上的右上角有一个fork按钮, 点它</p>
<p>   3. Fork以后, 你就有了一份属于你自己的PHP源代码仓库, 现在你就可以在这个仓库下, 修改PHP的源代码来为它修复Bug了.</p>
<p>      具体开发没什么好说的, 不过如果对于Git的使用有问题的话, 可以参考Git使用手册, 比如这个: <a href="http://progit.org/2010/06/09/pro-git-zh.html" >ProGit</a></p>
<p>      我这里为大家提供一个简单的说明, 如果在Github上开始开发,  在你自己的PHP代码仓库的页面上, 会有一个说明, 比如在我的PHP仓库页面上<a href="https://github.com/laruence/php-src" >https://github.com/laruence/php-src</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;">
ssh  git@github.com:laruence/php-src.git
</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;">
$git clone git@github.com:laruence/php-src.git
</pre>
<p>      然后, 你就得到了一个php-src目录, 进去开发吧, <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> </p>
<p>   4. 等你修复完成以后,  你提交到你属于你自己的这个PHP仓库中,  然后,  在你的PHP源代码仓库的Github页面的右上角, 会有一个pull request按钮. 点它.</p>
<p>      提交的时候, 请注意你的提交说明的格式,  首先第一行应该是个简短的说明(最多79个字符), 说明你做了什么修改.  如果一句话说不完, 就插入一个空行, 然后输入大段的说明(参看<a href="https://wiki.php.net/vcs/gitworkflow#new_commit_message_format" >New Commit Message Format</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;max 79 characters short description&gt;\n
\n
&lt;long description, 79 chars per line&gt;
\n
</pre>
<p>   如果你是修复了一个列在bugs.php.net上的bug, 那么你的简短说明应该类似如下格式:</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;">
Fixed Bug #bug号 (Bug的描述)
</pre>
<p>   5. 然后, 填写相关的信息, Github就会给PHP的pull request邮件组发送一份包含着你的更新的Pull Request邮件(大家不用担心你的英文, 只要你能说出来, 我们就能看懂,  当然, 如果你实在不愿意写英文, 也没关系, 写中文吧, 我看到了会处理, 我处理不了的, 我也会为大家翻译).</p>
<p>   6. 最后, 如果PHP的Committers们认为你的修复正确(有一些为PHP贡献代码要注意的选项, 我留在下面). 就会Merge你的Pull Request到PHP的源代码中.</p>
<p>   现在, 假设你要提交的是, 一个更新(添加新函数, 添加新语法), 那么在你提交了Pull Request的同时, 你还需要往internals@lists.php.net邮件组发送一个邮件, 来说明你为什么要提交这个更新, 让在这个邮件组的人们一起来讨论, 帮助你完善你的想法.</p>
<p>   最后,  在你为PHP贡献了一些更新以后(被Committer接受的更新),  那么你就可以尝试在: <a href="http://pecl.php.net/account-request.php" >Register Svn Accout</a>上来申请一个你自己的PHP Developer账号了. <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" />  </p>
<p>   附录:</p>
<p>   为PHP贡献源代码有几点要注意的(常见的问题):<br/>
   1.  只写C89兼容的代码,  比如, 不要用单行注释(//), 变量的定义一定要在所有语句之前(block的开始)..<br/>
   2.  变量命名, 遵循PHP已有的规范, 不要使用驼峰命名.<br/>
   3.  对于一些非常小的更新, 比如代码中有拼写错误,  还是鼓励大家到bugs.php.net上提交Patch, 毕竟Merge Pull Request有的时候会比较麻烦.</p>
<p>   更多的PHP代码规范, 参看这里: <a href="https://github.com/php/php-src/blob/master/README.SUBMITTING_PATCH" >Submitting patch</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/2012/04/30/2594.html" >2012/04/30</a>, <a href="http://www.azhun.cn"  rel="external nofollow"  class="url" >Azhun</a> writes: 能感受到这是让人振奋的事情</li><li><a href="http://www.laruence.com/2012/04/30/2594.html" >2012/05/02</a>, <a href="http://www.magentochina.org"  rel="external nofollow"  class="url" >Magento中文</a> writes: 用git的越来越多了，不错</li><li><a href="http://www.laruence.com/2012/04/30/2594.html" >2012/05/04</a>, <a href="http://phpcms.org.cn"  rel="external nofollow"  class="url" >老蜗牛</a> writes: 一直希望贡献代码

博主能换个链接么

PHPCMS中国 http://phpcms.org.cn

QQ：860275582</li><li><a href="http://www.laruence.com/2012/04/30/2594.html" >2012/05/13</a>, <a href="http://blog.csdn.net/lixianlin/"  rel="external nofollow"  class="url" >ShineLee</a> writes: 你好，很喜欢你的博客。有个问题，就是PHP的中文帮助手册-&gt;索引列表项目中的中文一直是乱码，你是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/2008/08/11/147.html"  rel="bookmark"  title="Permanent Link: 深入浅出PHP(Exploring PHP)" >深入浅出PHP(Exploring PHP)</a></li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2008/11/19/625.html"  title="让人无语的139邮箱" >让人无语的139邮箱</a></li><li><a href="http://www.laruence.com/2008/09/17/508.html"  title="Thanksgiving" >Thanksgiving</a></li><li><a href="http://www.laruence.com/2008/07/11/108.html"  title="IE下的Javascript调试利器:Companion.js" >IE下的Javascript调试利器:Companion.js</a></li><li><a href="http://www.laruence.com/2011/10/10/2232.html"  title="二进制直接量(binary number format)" >二进制直接量(binary number format)</a></li><li><a href="http://www.laruence.com/2007/10/03/5.html"  title="VIM中文乱码解决方案" >VIM中文乱码解决方案</a></li><li><a href="http://www.laruence.com/2009/11/18/1154.html"  title="automake,autoconf使用详解" >automake,autoconf使用详解</a></li><li><a href="http://www.laruence.com/2011/06/28/2088.html"  title="在Windows下编译Yaf" >在Windows下编译Yaf</a></li><li><a href="http://www.laruence.com/2010/12/14/1816.html"  title="Compilation failed: support for \P, \p, and \X has not been compiled" >Compilation failed: support for \P, \p, and \X has not been compiled</a></li><li><a href="http://www.laruence.com/2008/07/24/206.html"  title="Apache启动过程(PHP_MINIT_FUNCTION的调用)" >Apache启动过程(PHP_MINIT_FUNCTION的调用)</a></li><li><a href="http://www.laruence.com/2009/04/22/687.html"  title="谈谈用户可预感体验" >谈谈用户可预感体验</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/04/30/2594.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PHP对程序员的要求更高</title>
		<link>http://www.laruence.com/2012/04/01/2571.html</link>
		<comments>http://www.laruence.com/2012/04/01/2571.html#comments</comments>
		<pubDate>Sun, 01 Apr 2012 04:27:06 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[随笔]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2571</guid>
		<description><![CDATA[今天是愚人节, 但我这个文章标题可不是和大家开玩笑. :)

    首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译..

    为此, 也就有了一些Opcode Cache, 比如APC, 比如eacc. 还有Zend O+. 

    那么为什么PHP不把编译/执行分开呢? ]]></description>
			<content:encoded><![CDATA[<div class="copyright" >
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li>作者: <a href="http://www.laruence.com" >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/04/01/2571.html"  title="Permanet Link to PHP对程序员的要求更高" >http://www.laruence.com/2012/04/01/2571.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    今天是愚人节, 但我这个文章标题可不是和大家开玩笑. <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> </p>
<p>    首先, 大家都知道, PHP也是一种编译型脚本语言, 和其他的预编译型语言不同, 它不是编译成中间代码, 然后发布.. 而是每次运行都需要编译..</p>
<p>    为此, 也就有了一些Opcode Cache, 比如开源的APC, eacc. 还有商业的Zend O+等. </p>
<p>    那么为什么PHP不把编译/执行分开呢? </p>
<p>    PHP虽然是一种编译型脚本语言,  但是它的编译速度非常快,  它的编译不做任何语义优化, 就是简单的忠实的把你所写的代码翻译成对应的Opcodes.  而其他语言因为在编译器做很多的优化工作, 会造成编译比较重, 也一定程度上要求它们分离.</p>
<p>    所以, 理论上来说, 通过编译执行分离, 想达到源码加密, 是不会有什么太大收效的, 因为它很容易被反向.</p>
<p>    另外, 编译直接分离, 并不会带来特别大的收益,  反而会降低调试部署的效率(想想, 修改, 编译, 发布, 看效果), 并且APC等Opcode Cache工具, 已经很成熟了..</p>
<p>    到这里, 请大家注意这句:&#8221;它的编译不做任何语义优化&#8221;&#8230;.</p>
<p>    这也就是我为什么说, PHP对程序员的要求更高,  不同于其他的编译型语言, 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;">
$j = &quot;laruence&quot;;
for ($i=0;$i&lt;strlen($j);$i++) {
}
</pre>
<p>    如果是其他预编译语言, 它的编译器也许会帮你做优化, 把strlen提取到前面去, 只做一次就够了. 而对于PHP来说, 它在编译的时候不做任何优化,  也就是说, 你的strlen, 会忠实的被调用8次.</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;">
$table = &quot;table&quot;;
while($i++ &lt; 1000) {
  $sql = &quot;select * from &quot; .  $table . &quot; where id = &quot; . $i;
}
</pre>
<p>   没错, &#8220;select * from &#8221; . $table会被concat 1000次..</p>
<p>   可见, PHP的程序员, 需要认真的想好, 你的代码会怎么被执行, 你怎么写代码, 最终的执行效率才最高. 而不像其他的语言, 程序员可以把一部分优化工作交给编译器. </p>
<p>   这也就是我为什么说:&#8221;PHP对程序员的要求更高&#8221; 的原因. 当然, 这个是好是坏, 那就是见仁见智了.<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/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://www.jiunile.com"  rel="external nofollow"  class="url" >xupeng</a> writes: 很有道理</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, qing writes: 就 上述两个例子 您是如何解决的呢?</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://www.leonzhang.com"  rel="external nofollow"  class="url" >hileon</a> writes: 好的语言应该是程序员的好的表达方式,而不是给程序员制造蹩脚的的难点,让人钻进去解决本来该语言解决的问题.

我觉得这些例子只能说明php的实现不好,阴暗一点,怀疑zend故意这样的,Zend O+才有市场.
呵呵,不好意思,在这里乱说了.</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @hileon 目标不同, 编译期间优化, 会带来额外的复杂逻辑和性能损失.</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, vk writes: 因为它很容易被方向。

别字了，鸟哥。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://www.cndong.cn/"  rel="external nofollow"  class="url" >cndong</a> writes: 第一个:
$len = strlen($j);
for ($i=0;$len;$i++) {
}
第二个着实没有看懂题意:
执行时$tableName肯定是不一样的, 还是想说 "select * from " =&gt;  'select * from '</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://66beta.com"  rel="external nofollow"  class="url" >66beta</a> writes: 第二个例子意思，应该是想说where的时候直接指定范围 0&lt; id &lt;1000 而不是做循环</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, Lukin writes: 第二个看懂了，但应该怎么优化那？</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://reeze.cn"  rel="external nofollow"  class="url" >reeze</a> writes: @cndong 鸟哥的意思是字符串的连接操作，每次循环都要执行一次。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, hello writes: 第2个貌似应该是999次吧。
不知道第2个要表达什么意思？</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://blog.wegeek.tk/php%e5%af%b9%e7%a8%8b%e5%ba%8f%e5%91%98%e7%9a%84%e8%a6%81%e6%b1%82%e6%9b%b4%e9%ab%98/"  rel="external nofollow"  class="url" >PHP对程序员的要求更高 | Wegeek</a> writes: [...] 转自：本文地址: http://www.laruence.com/2012/04/01/2571.html [...]</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, wclssdn writes: 汗.. 第二个例子的意思是说.. $table变量既然已经确定了. 那就要在循环外边确定$sql能确定的部分. 而不是去循环里边把$table 放在$sql中.. 
$table = "table";
$sql = "select * from " .  $table . " where id = ";
while(++$i &lt; 1000) {
  $sql .= $i;
}
虽说这个优化的效果不一定有多明显. 但这起码说明了程序员的水平...</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, Bruce writes: 第一个很简单，在循环之前就确定长度。

第二个其实只写出来了部分的算法，while循环中应该还有查询数据库的部分，而不仅仅是生成一个SQL语句。第二个的优化应该是优化SQL语句。
$table = "table";
$i = 1000;
$sql = "SELECT * FROM {$table} WHERE id&lt;{$i} ORDER BY id DESC&quot;;</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, weidian01 writes: 到底是编译型 还是 解释型  ???</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, wait writes: for ($i=0;$i&lt;strlen($j);$i++) {
}
对JAVA来说，会选择性的优化，如果循环的是基础类型的数组，会优化,包装类型的话，会选择性优化。知道这个比简单的知道PHP需要把strlen提到外面来对程序员的功力要求更高，需要熟悉JVM字节码。

所以，就这个例子，恰恰说明文章作者的观点是站不住脚的。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, 杨昆 writes: 顶了再看</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, 农村旺财的主人 writes: 楼主说的这些问题不能体现PHP需要注意的更多。
这些问题你完全可以不关心，知道它真的成为瓶颈。
PHP几乎完全不用关心数据类型和内存分配，语法也比Python还要傻瓜，只需要一个很小的集合就能写出很多有用的程序。
从入门者的水平就看得出来，PHP比C的差很多，比Java和C#的都有所不及。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://www.biaojita.com"  rel="external nofollow"  class="url" >dk01</a> writes: 这。。。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://zyanlu.com"  rel="external nofollow"  class="url" >zyanlu</a> writes: 顶鸟哥</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/01</a>, <a href="http://hi.baidu.com/kxn308/home"  rel="external nofollow"  class="url" >Forever</a> writes: 嗯 有好有坏
这就让程序员要更注意这些
从另一方面看 其他语言 这也是优点哈</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/02</a>, <a href="http://yuetao.org"  rel="external nofollow"  class="url" >hop-pocket</a> writes: 有道理~~</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/02</a>, Qiang writes: 别的语言是讲究效率所以才会让编译器优化，php这种糙不拉极的，没有优化倒成了对程序员的高要求了？！</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/03</a>, csdcit writes: 以上例子，不无道理。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/04</a>, jlake writes: 其实哪种语言都一样，
编译后的代码或是被解释的代码性能再高，
不合理的写法同样导致效率低下。
如同文中的例子，大循环里面执行SQL都会产生问题。
所以说，没有“更高”，只有“同样高”。
需要注意的是语言本身的特性。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/05</a>, <a href="http://pztai.com"  rel="external nofollow"  class="url" >taylortai</a> writes: 作为一个c coder2phper 我觉得带过来好多习惯还不错
上次百度沙龙终于看到心中的php大神您了~</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/05</a>, <a href="http://hi.baidu.com/fc_lamp/home"  rel="external nofollow"  class="url" >fc_lamp</a> writes: “Error establishing a database connection”

大牛你的博客报这个错~~</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/05</a>, <a href="http://www.wuqianfeng.com"  rel="external nofollow"  class="url" >Qianfeng</a> writes: &lt;?php
//Demo
for($i=0;$i&lt;getLen(&#039;test&#039;);$i++){
    //just for
}
function getLen($str)
{
    static $i;
    $i++;
    echo $i;
    return strlen($str);
}

echo &#039;, &#039;;

foreach(getArray() as $item)
{
	//empty
}
function getArray()
{
    static $i;
    $i++;
    echo $i;
	return array(1,2,3,4,5);
}



/* -------------
结果是 12345, 1
为什么 array 能够处理，简单的一个int 却不能记录主呢？
我觉得php 可以优化下~ 
*/</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/05</a>, Replie writes: 需要注意的是语言本身的特性。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/06</a>, dequan writes: 这回让你觉得编译跟你有莫大的关系，不至于，写完代码后，毫不在乎。</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/08</a>, <a href="http://www.aiyeshi.com/archives/59"  rel="external nofollow"  class="url" >[转] PHP对程序员的要求更高 | 风中了了也</a> writes: [...] 本文地址: http://www.laruence.com/2012/04/01/2571.html [...]</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/08</a>, <a href="http://www.dy1977.com"  rel="external nofollow"  class="url" >深圳丝印</a> writes: 都仔细看了文章了，但是看不懂啊，为啥不能给个链接呢?</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/17</a>, rafer writes: 鸟哥据说去新浪微博了？</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/20</a>, w writes: 汇编语言对程序员要求更高.
搞WEB都注重更多框架, 更方便开发的API.</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/24</a>, Anonymous writes: PHP不是解释型脚本吗，怎么是编译型？。
java, c/c++是编译型的。
php脚本实际上经过zend解释器解释后，再编译。也就是每次运行先解释后编译。

所以请大鸟解释这个疑问.</li><li><a href="http://www.laruence.com/2012/04/01/2571.html" >2012/04/28</a>, zkaipm writes: https://wiki.php.net/vcs/gitfaq这个网站上面的
cd ~/php-5.3
git checkout -b 
[edit files]
怎么建立自己的分支？</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/2009/08/09/1036.html"  title="正确使用JS中的正则" >正确使用JS中的正则</a></li><li><a href="http://www.laruence.com/2009/06/14/945.html"  title="深入理解PHP原理之扩展载入过程" >深入理解PHP原理之扩展载入过程</a></li><li><a href="http://www.laruence.com/2009/05/26/871.html"  title="PHP+Gtk实例(求24点)" >PHP+Gtk实例(求24点)</a></li><li><a href="http://www.laruence.com/2010/09/04/1736.html"  title="Yaf-一个PHP扩展实现的PHP框架" >Yaf-一个PHP扩展实现的PHP框架</a></li><li><a href="http://www.laruence.com/2011/10/10/2239.html"  title="让Json更懂中文(JSON_UNESCAPED_UNICODE)" >让Json更懂中文(JSON_UNESCAPED_UNICODE)</a></li><li><a href="http://www.laruence.com/2010/07/16/1648.html"  title="定制自己的PHP语法-在PHP中实现unless" >定制自己的PHP语法-在PHP中实现unless</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/2008/08/10/1.html"  title="个人主页开张" >个人主页开张</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/2012/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/04/01/2571.html/feed</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Taint-0.3.0(A XSS codes sniffer) released</title>
		<link>http://www.laruence.com/2012/02/18/2560.html</link>
		<comments>http://www.laruence.com/2012/02/18/2560.html#comments</comments>
		<pubDate>Sat, 18 Feb 2012 13:39:20 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP Extension]]></category>
		<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[taint]]></category>
		<category><![CDATA[xss code]]></category>
		<category><![CDATA[xss sniffer]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2560</guid>
		<description><![CDATA[
最近几天忙里偷闲, 一直在完善taint,  今天我觉得终于算做到了80%的满意了, 根据80:20原则, 我觉得可以做为一个里程碑的版本了 :).

   什么是Taint? An extension used for detecting XSS codes(tainted string), And also can be used to spot sql injection vulnerabilities, shell inject, etc. 

   经过我实际测试, <a href="http://pecl.php.net/package/taint">Taint-0.3.0</a>能检测出实际的一些开源产品的(别问是什么)隐藏的XSS code, SQL注入, Shell注入等漏洞, 并且这些漏洞如果要用静态分析工具去排查, 将会非常困难, 比如对于如下的例子:
<coolcode lang="php" linenum="off">
<?php
   $name = $_GET["name"];
   $value = strval($_GET["tainted"]);

   echo $$name;
</coolcode>
   对于请求: 
<coolcode lang="bash" linenum="off">
http://****.com/?name=value&#038;tainted=xxx
</coolcode>

   静态分析工具, 往往无能为力,  而Taint却可以准确无误的爆出这类型问题.]]></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/18/2560.html"  title="Permanet Link to Taint-0.3.0(A XSS codes sniffer) released" >http://www.laruence.com/2012/02/18/2560.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
   最近几天忙里偷闲, 一直在完善taint,  今天我觉得终于算做到了80%的满意了, 根据80:20原则, 我觉得可以做为一个里程碑的版本了 <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" /> .</p>
<p>   什么是Taint? An extension used for detecting XSS codes(tainted string), And also can be used to spot sql injection vulnerabilities, shell inject, etc. </p>
<p>   经过我实际测试, <a href="http://pecl.php.net/package/taint" >Taint-0.3.0</a>能检测出实际的一些开源产品的(别问是什么)隐藏的XSS code, SQL注入, Shell注入等漏洞, 并且这些漏洞如果要用静态分析工具去排查, 将会非常困难, 比如对于如下的例子:</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
   $name = $_GET[&quot;name&quot;];
   $value = strval($_GET[&quot;tainted&quot;]);

   echo $$name;
</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;">

http://****.com/?name=value&#038;tainted=xxx
</pre>
<p>   静态分析工具, 往往无能为力,  而Taint却可以准确无误的爆出这类型问题.</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;">
Warning: main() [function.echo]:
     Attempt to echo a string that might be tainted in %s.php on line %d
</pre>
<p>   现在0.3.0已经发布, 我想短时间内, 我不会再添加新功能了. enjoy, <a href="http://pecl.php.net/package/taint" >PHP Taint</a>.</p>
<p>   另外, 多说一句, Taint可以说是, 我完成的扩展中最为复杂的一个,  使用了各种tricky技巧, 大家如果有兴趣做扩展开发, 可以用来作为一个很好的高级教材.</p>
<p>附录:</p>
<p>A. Tainted String</p>
<p>    所有来自$_GET, $_POST, $_COOKIE的变量, 都被认为是Tainted String</p>
<p>B. taint检测的函数/语句列表, 当这些函数使用tainted string参数的时候, taint会给出警告:</p>
<p>1. 输出函数/语句系列</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;">
echo
print
printf
file_put_contents
</pre>
<p>2. 文件系统函数</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;">
fopen
opendir
basename
dirname
file
pathinfo
</pre>
<p>3. 数据库系列函数/方法</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;">
mysql_query
mysqli_query
sqlite_query
sqlite_single_query
oci_parse
Mysqli::query
SqliteDataBase::query
SqliteDataBase::SingleQuery
PDO::query
PDO::prepare
</pre>
<p>4. 命令行系列</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;">
system
exec
proc_open
passthru
shell_exec
</pre>
<p>5. 语法结构</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;">
eval
include(_once)
require(_once)
</pre>
<p>C. 消除tainted信息的函数, 调用这些函数以后, tainted string就会变成合法的string:</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;">
escapeshellcmd
htmlspecialchars
escapeshellcmd
addcslashes
addslashes
mysqli_escape_string
mysql_real_escape_string
mysql_escape_string
sqlite_escape_string
PDO::quote
Mysqli::escape_string
Mysql::real_escape_string
</pre>
<p>D. 调用中保持tainted信息的函数/语句, 调用这些函数/语句时, 如果输入是tainted string, 则输出也为tainted string:</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;">
= (assign)
. (concat)
&quot;{$var}&quot; (variable substitution)
.= (assign concat)
strval
explode
implode
sprintf
vsprintf
trim(as of 0.4.0)
rtrim(as of 0.4.0)
ltrim(as of 0.4.0)
</pre>
<p>E. 链接:</p>
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
<li><a href="http://wiki.php.net/rfc/taint" >RFC:Taint</a> (想法主要来自这个RFC)</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_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_bash.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_php.js" ></script><script type="text/javascript"  src="http://www.laruence.com/wp-content/plugins/shjs-syntax-hiliter/shjs/lang/sh_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><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/18/2560.html" >2012/02/19</a>, <a href="http://www.hostsir.com"  rel="external nofollow"  class="url" >免费域名注册</a> writes: 这个不错，我去检测一下自己的项目</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/19</a>, majl writes: 为什么我用5.3.10报错呢．．
Warning: PHP Startup: Unable to load dynamic library /usr/lib/php/modules/taint.so' - /usr/lib/php/modules/taint.so: undefined symbol: zif_user_sprintf in Unknown on line 0</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/19</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @majl 你的PHP是从哪里下载的, 另外, 是否打了其他的什么patch?</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/20</a>, majl writes: yum安装的,就打了这一个补丁！</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/20</a>, enjoy writes: $username = $_POST['UserName'];	
echo $username;
提示：Attempt to echo a string that might be tainted 
测试后发现，不管magic_quotes_gpc是On还是Off，加个trim就不报错了。
$username = trim($_POST['UserName']);
好像有点不对？</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/20</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @enjoy 恩,, trim应该加入到函数链表中...</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/20</a>, <a href="http://hello.world.com"  rel="external nofollow"  class="url" >hello</a> writes: 有一个测试失败
[root@localhost taint]# make test

Build complete.
Don't forget to run 'make test'.

/usr/local/bin/php: symbol lookup error: /root/Downloads/php-5.3.10/ext/taint/modules/taint.so: undefined symbol: zif_implode

=====================================================================
PHP         : /usr/local/bin/php 
PHP_SAPI    : cli
PHP_VERSION : 5.3.10
ZEND_VERSION: 2.3.0
PHP_OS      : Linux - Linux localhost.localdomain 2.6.33.6-147.fc13.i686 #1 SMP Tue Jul 6 22:30:55 UTC 2010 i686
INI actual  : /root/Downloads/php-5.3.10/ext/taint/tmp-php.ini
More .INIs  :  
CWD         : /root/Downloads/php-5.3.10/ext/taint
Extra dirs  : 
VALGRIND    : Not used
=====================================================================
TIME START 2012-02-20 14:19:14
=====================================================================
PASS Check for taint presence [tests/001.phpt] 
PASS Check Taint function [tests/002.phpt] 
PASS Check Taint with ternary [tests/003.phpt] 
PASS Check Taint with eval [tests/004.phpt] 
PASS Check Taint with separation [tests/005.phpt] 
PASS Check Taint with send_var/send_ref [tests/006.phpt] 
FAIL Check Taint with functions [tests/007.phpt] 
=====================================================================
TIME END 2012-02-20 14:19:15</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/20</a>, <a href="http://www.laruence.com/"  rel="external nofollow"  class="url" >laruence</a> writes: @hello 恩, 看起来有的版本的PHP没有暴露出这些符号, 我换个方法. 回头0.3.1修复这个问题</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/20</a>, <a href="http://www.laruence.com/"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @hello @enjoy @majl 已经在svn修复. 可以在github下载到 https://github.com/laruence/php-ext-taint</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/22</a>, <a href="http://www.114chengdu.com"  rel="external nofollow"  class="url" >toms</a> writes: 高深..........................</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/24</a>, helloki writes: 能否提供5.3.6 nts的.dll呢 ^^</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/28</a>, <a href="http://weibo.com/flyhope"  rel="external nofollow"  class="url" >李枨煊</a> writes: hi~鸟哥：

今天在开发机装了一个试了一下，发现有这么一个问题，如果参数这样接收，taint就不会报错，这算是BUG吗？

$b = isset($_GET['b']) ? $_GET['b'] : '';
echo $b;</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/28</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @李枨煊 你用的是那个版本?  我这里没问题, 试试最新的.</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/28</a>, <a href="http://weibo.com/flyhope"  rel="external nofollow"  class="url" >李枨煊</a> writes: PHP版本： 5.2.14
taint 版本：0.4.1</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/28</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @李枨煊 打开错误日志了么?</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/29</a>, <a href="http://weibo.com/flyhope"  rel="external nofollow"  class="url" >李枨煊</a> writes: 开了，直接这样写就会报错
echo $_GET['b'];</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/02/29</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @李枨煊  奇怪了, 我这边没问题, 等我回头再验证下2.14,(目前我是2.17), thanks</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/02</a>, fifsky writes: 不知道能不能配置某个虚拟机检测，现在打开这个同一台服务器的老系统全都挂掉了，我只想针对新的项目使用，老的项目不关心这些</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/07</a>, glone writes: 这么热闹</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/11</a>, count writes: 很不错的东东

我的理解是这样，这种检测方式是一种线上检测，前提是要知道php文件的所有输入参数url，去触发这个检测逻辑；

静态语法分析没这个问题，但在某些方面没这种方式准确了</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/11</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @count  恩, 是的, 所以建议是在开发/测试的时候启用这个扩展.</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/16</a>, <a href="http://zhuangwang.com"  rel="external nofollow"  class="url" >王相伟</a> writes: 非常好的一个扩展！</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/19</a>, <a href="http://achun.iteye.com"  rel="external nofollow"  class="url" >achun</a> writes: 这种问题够复杂，对于严格的产品，taint 会起到很大作用</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/19</a>, <a href="http://3haku.net/2012/03/09/taint%e7%9a%84%e4%bd%bf%e7%94%a8%e5%92%8c%e6%ba%90%e7%a0%81%e4%bf%ae%e6%94%b9.html"  rel="external nofollow"  class="url" >taint的使用和源码修改 - big bug ban</a> writes: [...] 说明和初步的使用请查看http://www.laruence.com/2012/02/18/2560.html [...]</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/27</a>, Sunny writes: 很多开源系统，对$_GET和$_POST参数的获取，都封装有自己的函数。类似G_GET()，G_POST()这类预转移过的函数。
这样的数据是否也能监控到XSS呢？</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/29</a>, <a href="http://www.muzhiwan.com"  rel="external nofollow"  class="url" >拇指玩</a> writes: 学习一下，强烈关注！</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/03/29</a>, <a href="http://www.joozone.com"  rel="external nofollow"  class="url" >essay</a> writes: 大虾无敌啊！从chinaz过来看到您的blog；内容比较高深，看不大明白。但该顶，呵呵。</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/07</a>, test writes: 在条件error_reporting  =  E_ALL ^ E_NOTICE，display_errors = On下，看不到taint warning，这有问题吗？</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/11</a>, <a href="http://sun190.com"  rel="external nofollow"  class="url" >肖建刚</a> writes: 很给力.!</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/11</a>, <a href="http://liut.cc/blog"  rel="external nofollow"  class="url" >liut</a> writes: 在lion下编译失败：

/Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1056:16: warning: 
      passing 'long *' to parameter of type 'unsigned long *' converts between pointers
      to integer types with different sign [-Wpointer-sign]
  ...switch (zend_hash_get_current_key(ht, &amp;key, &amp;idx, 0)) {
             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/local/include/php/Zend/zend_hash.h:201:52: note: instantiated from:
        zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
                                                          ^
/Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1056:52: note: instantiated from:
  ...switch (zend_hash_get_current_key(ht, &amp;key, &amp;idx, 0)) {
                                                 ^~~~
/opt/local/include/php/Zend/zend_hash.h:179:107: note: passing argument to parameter
      'num_index' here
  ...uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
                              ^
/Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1260:22: error: 
      expression is not assignable
                Z_REFCOUNT_PP(op1) = refcount;
                ~~~~~~~~~~~~~~~~~~ ^
/Users/liutao/.macports/opt/local/var/macports/build/_Users_liutao_DarwinPorts_local-sources_www_php5-taint/php5-taint/work/taint-0.5.1/taint.c:1517:30: warning: 
      'zend_get_parameters_ex' is deprecated [-Wdeprecated-declarations]
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &amp;arg) == FAILURE) {
                                    ^
2 warnings and 1 error generated.
make: *** [taint.lo] Error 1</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/11</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @liut 多谢反馈, 已经在svn修复了. http://svn.php.net/viewvc/pecl/taint/trunk/taint.c?r1=325027&r2=325026&pathrev=325027</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/11</a>, <a href="http://weibo.com/skybyte"  rel="external nofollow"  class="url" >skybyte</a> writes: 这个不能记录日志到文件啊,我这样设置日志里面没得
error_reporting  =  E_ALL &amp; ~E_NOTICE
error_log=php.log
display_errors=Off

改成display_errors=on就直接显示到浏览器了</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/13</a>, <a href="http://pangee.me/"  rel="external nofollow"  class="url" >pangee</a> writes: 赞！</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/04/16</a>, <a href="http://liut.cc/blog"  rel="external nofollow"  class="url" >liut</a> writes: 请问有没有编译好win32 dll，我本人用mac，但组员大部分用windows</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/05/09</a>, <a href="http://www.shirne.com"  rel="external nofollow"  class="url" >shirne</a> writes: 但是，我还是想问问，是什么--!</li><li><a href="http://www.laruence.com/2012/02/18/2560.html" >2012/05/13</a>, <a href="http://none"  rel="external nofollow"  class="url" >virgins</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/2012/02/14/2544.html"  rel="bookmark"  title="Permanent Link: PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2010/04/12/1394.html"  rel="bookmark"  title="Permanent Link: IE下pre标签的InnerHTML问题" >IE下pre标签的InnerHTML问题</a></li><li><a href="http://www.laruence.com/2011/06/19/2047.html"  rel="bookmark"  title="Permanent Link: PLua &#8211; Lua for PHP" >PLua &#8211; Lua for PHP</a></li><li><a href="http://www.laruence.com/2008/11/11/610.html"  rel="bookmark"  title="Permanent Link: 统一信息存储平台(ISP)" >统一信息存储平台(ISP)</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></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/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/18/2560.html/feed</wfw:commentRss>
		<slash:comments>36</slash:comments>
		</item>
		<item>
		<title>PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</title>
		<link>http://www.laruence.com/2012/02/14/2544.html</link>
		<comments>http://www.laruence.com/2012/02/14/2544.html#comments</comments>
		<pubDate>Tue, 14 Feb 2012 06:01:02 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP Extension]]></category>
		<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[taint]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[检测]]></category>
		<category><![CDATA[跨站攻击检测]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2544</guid>
		<description><![CDATA[
之前, 小顿和我提过一个想法, 就是从PHP语言层面去分析,找出一些可能的注入漏洞代码. 当时我一来没时间, 而来也确实不知道从何处下手.. 

    直到上周的时候, 我看到了这个RFC: <a href="https://wiki.php.net/rfc/taint">RFC:Taint</a>.  

    但是这个RFC的问题在于, 它需要为PHP打Patch, 修改了PHP本身的数据结构,  这对于以后维护, 升级PHP来说, 很不方便, 也会有一些隐患.  

    虽然这样, 但这个RFC却给了我一个启发, 于是我就完成了这样的一个扩展:<a href="http://pecl.php.net/package/taint">Taint Extension</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" >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/14/2544.html"  title="Permanet Link to PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >http://www.laruence.com/2012/02/14/2544.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
    之前, 小顿和我提过一个想法, 就是从PHP语言层面去分析,找出一些可能的注入漏洞代码. 当时我一来没时间, 而来也确实不知道从何处下手.. </p>
<p>    直到上周的时候, 我看到了这个RFC: <a href="https://wiki.php.net/rfc/taint" >RFC:Taint</a>.  </p>
<p>    但是这个RFC的问题在于, 它需要为PHP打Patch, 修改了PHP本身的数据结构,  这对于以后维护, 升级PHP来说, 很不方便, 也会有一些隐患.  </p>
<p>    虽然这样, 但这个RFC却给了我一个启发, 于是我就完成了这样的一个扩展:<a href="http://pecl.php.net/package/taint" >Taint Extension</a></p>
<p>    这个扩展使用起来, 很简单(目前只支持5.2.6 ~  5.3.10):</p>
<p>     下载源代码以后, 编译, 安装. 然后在php.ini中要开启这个扩展(<b>建议不要在生产环境开启这个扩展</b>):</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;">
extension=taint.so
taint.enable=1
</pre>
<p>     启用这个扩展以后, 如果在一些关键函数(或者语句: echo, print, system, exec, 等等), 或者输出的地方*直接*(没有经过转义, 安全过滤处理)使用了来自$_GET, $_POST或者$_COOKIE的数据, 则Taint就会提示你:</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 = $_GET['a'];

 $file_name = '/tmp' .  $a;
 $output    = &quot;Welcome, {$a} !!!&quot;;
 $var       = &quot;output&quot;;
 $sql       = &quot;Select *  from &quot; . $a;
 $sql      .= &quot;ooxx&quot;;

 echo $output;
//Warning: main(): Attempt to echo a string which might be tainted in xxx.php on line x

 print $$var;
//Warning: main(): Attempt to print a string which might be tainted  in xxx.php on line x

 include($file_name);
//Warning: include() [function.include]: File path contains data that might be tainted in xxx.php on x

 mysql_query($sql);
//Warning: mysql_query() [function.mysql-query]: First argument contains data that might be tainted in xxx.php on line x
?&gt;
</pre>
<p>    目前因为还没有支持5.4(5.4的实现方法, 要依赖于我将要和Dmitry讨论的一个新需求), 所以目前还没有发布一个下载包, 大家可以先直接从源代码下载: <a href="https://github.com/laruence/php-ext-taint" >Taint on Github</a>.</p>
<p>   上面的例子显示了简单的用法, 回头我会再完善下文档&#8230;. </p>
<p>   enjoy~<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></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/14/2544.html" >2012/02/14</a>, Kenny writes: 为什么无法下载啊？</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/14</a>, <a href="http://weibo.com/pangee"  rel="external nofollow"  class="url" >pangee</a> writes: 过滤输入，转义输出……</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/14</a>, leijuly writes: 每天上来看一看， 进阶学习。  博主造福广大基层PHPer啊</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/14</a>, KnightE writes: 已在开发环境上安装，体验一下看看</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/14</a>, Ckai writes: 鸟哥v5</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/14</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</a> writes: 给PHP写插件真是必备技能。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/15</a>, cnwill writes: 博主一直是我们的解困导师！</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/15</a>, 匿名 writes: //Warning: main() [function.echo]

如果输出没有转义， 这种提示main() 这个可能要找一下，echo貌似是语法结构，不是function</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/15</a>, wclssdn writes: 不错 赞一个~~~</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, xinbe writes: 真是一个不错的套件
之前都是写regexp来搜寻源码
把这个纳入到开发、测试环境中应该挺不错的</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, Anonymous writes: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/taint.so' - /usr/lib64/php/modules/taint.so: undefined symbol: zend_error_noreturn in Unknown on line 0</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, rookie writes: PHP Warning:  PHP Startup: Unable to load dynamic library '/usr/lib64/php/modules/taint.so' - /usr/lib64/php/modules/taint.so: undefined symbol: zend_error_noreturn in Unknown on line 0</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @rookie PHP version?</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, jekhy writes: @rookie 我手动改了下taint.c，把zend_error_noreturn改为zend_error就可以了，参考：http://stackoverflow.com/questions/2556113/swig-generated-code-fails-to-run-on-php-5-3-2-undefined-symbol-zend-error-noret</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, rookie writes: PHP 5.3.6 (cli)</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @rookie 没道理啊, zend_error_noreturn是在zend.h定义的, 被php.h包含, 你是怎么编译的?</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, rookie writes: taint-0.0.1.tgz

#phpize
#./configure --enable-taint
#make
#cp modules/taint.so /usr/lib64/php/modules/

#cat /etc/php.d/taint.ini 
; Enable taint extension module
extension=taint.so

#tail /etc/php.ini
;XSS code sniffer
[taint]
taint.enable=1</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @rookie 我在5.3.6下无法复现.</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/16</a>, <a href="http://3haku.net/2012/02/16/php%e6%89%a9%e5%b1%95%e5%bc%80%e5%8f%91%e4%b8%80.html"  rel="external nofollow"  class="url" >php扩展开发(一) - big bug ban</a> writes: [...] = =.本来打算做这个xsscheck插件的。 发现超级大牛已经做了一个taint。 [...]</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/17</a>, airwin writes: 谁给个win版dll？~~</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/17</a>, <a href="http://www.hostsir.com"  rel="external nofollow"  class="url" >免费域名注册</a> writes: 漏洞太多，补不过来了</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/17</a>, rookie writes: ＠雪候鸟

可能跟我的环境有关系，终于安装好了，我改一下
vim taint.c                /*zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");*/
                zend_error(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets");

效果相当好，太感谢，你太给力了</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/17</a>, <a href="http://www.114chengdu.com"  rel="external nofollow"  class="url" >venkman</a> writes: 下个来看看效果, 嘿嘿</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/02/17</a>, <a href="http://www.114chengdu.com"  rel="external nofollow"  class="url" >toms</a> writes: 好像不能回复呢</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/03/09</a>, hm writes: 推荐的做法应该是后台吐原文、统一由前台（JS）转义输出吧，鸟哥怎么看呢</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/03/09</a>, <a href="http://www.laruence.com/"  rel="external nofollow"  class="url" >laruence</a> writes: @hm 多管齐下, 前台转义只是XSS, taint还关注于sql注入, 命令注入等.</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/03/12</a>, <a href="http://flykobe.com/index.php/2012/03/12/php-taint%e6%89%a9%e5%b1%95%e5%ad%a6%e4%b9%a0/"  rel="external nofollow"  class="url" >flykobe的技术与生活杂谈 &raquo; Blog Archive &raquo; php taint扩展学习</a> writes: [...] taint是大牛风雪之隅写的一个php扩展，用来检测GET、POST、COOKIE等中可能有的漏洞。其中用了很多php扩展开发必须的知识，简单记录代码逻辑如下。 [...]</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/04/18</a>, frank writes: 有没有相应的工程说明和代码解释文档啊，大牛</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/05</a>, <a href="http://www.w3hacker.org"  rel="external nofollow"  class="url" >包头网站建设</a> writes: 永远支持楼主~~</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/08</a>, chiotis writes: BUG太多了，各种诡异现象。误报也很多，真实项目中完全没用。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/08</a>, Laruence writes: @chioits 你能说说具体是什么bug么， taint目前是beta版本，可能会有些bug</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/08</a>, chiotis writes: @Laruence  目前遇到的有，1、数组中的变量（原值为'/'）经过一系列传递后，成了一个*RECURSION*； 2、autoload偶尔失效。 误报倒没什么，可以忽略，反正结果只是参考。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/09</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @chioits, 你可以试用下最新版的, 修复了一个dim连接的时候导致引用计数出错, 从而可能引起你说的情况的bug: http://pecl.php.net/package/taint ,最新版是0.5.3. 
thanks</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/10</a>, @Laruence writes: 好的，我今天试下。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/10</a>, Chiotis writes: 感谢，初步验证已经好了。后续再试用一阵，如果有问题及时反馈给您。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/10</a>, Chiotis writes: 发现autoload失败的问题还是存在，在自定义的loader 函数里，include会被误报有安全问题，导致加载不到不到文件。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/10</a>, Chiotis writes: sorry....autoload可能是是我这边用来记录taint错误的set_error_handler的函数在auto定义之前被触发了导致。</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/10</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @Chiotis  :), 多谢反馈~</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/12</a>, phpairspace writes: 在测试是遇到类似的代码
$q = $_GET['q'];
$controller = dirname(__FILE__);

if ($q) {
    $controller .= '/controller/'.$q;

    if (realpath($controller) != $controller) {
        exit('Access Denied');
    }
}

require $controller;

当访问q=index.php时会报Warning: require() [function.require]: File path contains data that might be tainted
请教下鸟哥什么情况下会有注入的风险？</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/12</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @phpairspace 代码中没看到require啊?</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/12</a>, phpairspace writes: 就是说只要有require 变量的话就都会报warning么？变量做过限制的话也不行么？</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/12</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @phpairspace, taint在发现你在关键函数使用了来自$_REQUEST的参数就会提示你可能会有问题,  它默认提示的是warning~</li><li><a href="http://www.laruence.com/2012/02/14/2544.html" >2012/05/13</a>, phpairspace writes: 那比如说这个来自$_REQUEST的参数已经做过过滤了，能否有方法取消这个warning的输出呢？一直输出warning对页面的js/ajax等效果有影响。</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/2012/02/18/2560.html"  rel="bookmark"  title="Permanent Link: Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</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/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/14/2544.html/feed</wfw:commentRss>
		<slash:comments>42</slash:comments>
		</item>
		<item>
		<title>PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</title>
		<link>http://www.laruence.com/2012/02/08/2528.html</link>
		<comments>http://www.laruence.com/2012/02/08/2528.html#comments</comments>
		<pubDate>Wed, 08 Feb 2012 03:58:03 +0000</pubDate>
		<dc:creator>雪候鸟</dc:creator>
				<category><![CDATA[PHP应用]]></category>
		<category><![CDATA[PHP源码分析]]></category>
		<category><![CDATA[Ddos]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHP 5.3.9]]></category>
		<category><![CDATA[Remote Code Execution]]></category>

		<guid isPermaLink="false">http://www.laruence.com/?p=2528</guid>
		<description><![CDATA[     还记得我之前说的<a href="http://www.laruence.com/2011/12/29/2412.html">PHP Hash Collisions Ddos</a>漏洞吧? 最初的时候, 开发组给出的修复方案, 采用的是如果超过max_input_vars, 就报错(E_ERROR), 继而导致PHP出错结束.  而后来, 为了更加轻量级的解决这个问题, 我们又改善了一下, 变成了如果超过max_input_vars, 就发出警告(E_WARNING), 并且不再往目的数组添加, 但是流程继续. 然后我们发布了5.3.9.

     这个新的修复方法初衷是好的, 但是却带来一个严重的问题(5.3.10中已经修复),  这个问题最初是由Stefan Esser发现的. 请看之前(5.3.9)最终的修复方案(php_register_variable_ex):]]></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/08/2528.html"  title="Permanet Link to PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >http://www.laruence.com/2012/02/08/2528.html</a></li>
</li>
<li>转载请注明出处 </li>
</ul></div>
<p>
     还记得我之前说的<a href="http://www.laruence.com/2011/12/29/2412.html" >PHP Hash Collisions Ddos</a>漏洞吧? 最初的时候, 开发组给出的修复方案, 采用的是如果超过max_input_vars, 就报错(E_ERROR), 继而导致PHP出错结束.  而后来, 为了更加轻量级的解决这个问题, 我们又改善了一下, 变成了如果超过max_input_vars, 就发出警告(E_WARNING), 并且不再往目的数组添加, 但是流程继续. 然后我们发布了5.3.9.</p>
<p>     这个新的修复方法初衷是好的, 但是却带来一个严重的问题(5.3.10中已经修复),  这个问题最初是由Stefan Esser发现的. 请看之前(5.3.9)最终的修复方案(php_register_variable_ex):</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;">
while (1) {
	if (zend_symtable_find(symtable1, escaped_index, index_len + 1, (void **) &amp;gpc_element_p) == FAILURE
		|| Z_TYPE_PP(gpc_element_p) != IS_ARRAY) { //(3)
		if (zend_hash_num_elements(symtable1) &lt;= PG(max_input_vars)) {  // (4)
			if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, &quot;Input variables exceeded %ld. ...&quot;, PG(max_input_vars)); // (1)
			}
			MAKE_STD_ZVAL(gpc_element);
			array_init(gpc_element);
			zend_symtable_update(symtable1, escaped_index, index_len + 1, &amp;gpc_element, sizeof(zval *), (void **) &amp;gpc_element_p);
		}
		//......
	}
	//.....
	symtable1 = Z_ARRVAL_PP(gpc_element_p);  // (2)
	goto plain;
}
</pre>
<p>     注意到, 如果此时注册一个数组变量(在GET中类似于: a[]=2), 并且此时这个变量刚好是第max_input_vars个变量的时候, 会触发一个警告(1), 此时一切正常.</p>
<p>     但是, 如果此时还是注册一个数组变量,但是这个变量已经是第max_input_vars + 1个变量的时候,  那么此时gpc_element_p将成为一个未初始化的指针, 而因为现在逻辑会继续走, 也就会走到(2)号位置,  导致解引用了一个未初始化的指针. 于是, Boomb~</p>
<p>     那么, 到目前位置, 我们就可以使用这样的特性来对5.3.9做Ddos了. 如果Server开启了Core Dump的话, 这个效果会非常明显.</p>
<p>     然而, 这个问题还会导致一个更严重的问题:</p>
<p>     还是上面的代码, 在最外层有一个循环,  这个循环起作用的时刻在注册类似于a[b]=2的pair对的时候, 循环将会执行俩次, 第一次插入a[], 第二次往a[]中插入b. 然后再让我们注意下(3),  如果在目的数组中找不到一个想要的元素, **或者这个元素不为数组**, 则也会直接导致流程留到(2), 于是问题就出现了.</p>
<p>     对于这样的POST串(默认max_input_vars是1000):</p>
<pre name="code"  class="sh_bash"  linenum="off"   style="background: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:Monacobackground: #333; color: #d9d9d9; border-left: 15px solid #c9c9c9; padding: 9px; font-size: 1em; overflow-x: auto;font-family:MonacoConsolasConsolasCourierCouriermonospace;monospace;">
 1=1&amp;1=2&amp;..........&amp;999=1&amp;x=&quot;我是恶意的string&quot;&amp;x[0]=0
</pre>
<p>    会发生什么事情呢? </p>
<p>    让我来一步一步描述下:</p>
<p>     1. 从1到999没什么问题,  都被正常插入</p>
<p>     2. x是1000个元素, 所以触发警告, 也没有问题, x被插入</p>
<p>     3. x[0]插入的时候, (3)号语句判断发现不是Arrary于是进入if体, 但是此时(4)号语句失败, 于是流程最终流到了(2)</p>
<p>     4. 此时, gpc_element_p指向x, 也就是那个我们伪造的字符串&#8230;.</p>
<p>  现在让我们看看关键的数据结构, zval:</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__gc;
    zend_uchar type;    /* active type */
    zend_uchar is_ref__gc;
};
</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>    zvalue_value是一个联合体, 于是我们构造的字符串区域的内存, 就会被当做一个Hashtable结构体:</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 struct _hashtable {
    uint nTableSize;
    uint nTableMask;
    uint nNumOfElements;
    ulong nNextFreeElement;
    Bucket *pInternalPointer;   /* Used for element traversal */
    Bucket *pListHead;
    Bucket *pListTail;
    Bucket **arBuckets;
    dtor_func_t pDestructor;  //注意这个
    zend_bool persistent;
    unsigned char nApplyCount;
    zend_bool bApplyProtection;
#if ZEND_DEBUG
    int inconsistent;
#endif
} HashTable;
</pre>
<p>   在Hashtable结构体中, 有一个pDestructor,  这个指针指向一个函数, 当这个Hashtable中有元素要被清除的时候, 就会调用它&#8230;</p>
<p>   也就是说, 你可以随心所欲的设置一个地址(pDestructor),  然后让PHP去调用它(诱使一个元素被删除).</p>
<p>   <b>但是, 到目前位置, 因为我们的大多数操作系统都有ASLR+NX保护, 所以这个只是理论上可以执行任意代码,  但实际上到目前为止还不能实际利用这个漏洞.</b></p>
<p>   最后, 我之前为5.2提供的Patch, 因为采用的是触发E_ERROR, 所以不存在这个漏洞, 大家已经使用了我之前Patch的同学可以放心. 也谢谢<a href="http://www.weibo.com/wofeiwo" >Wingary</a>同学在我了解这个漏洞过程中给予的帮助 <img src="http://www.laruence.com/wp-includes/images/smilies/icon_smile.gif"  alt=":)"  class="wp-smiley" />  </p>
<p>   最最后: 原理我介绍完了, 对于POC的介绍或者讨论, 就超出我写此文的意图了. 我就不再介绍了, 有兴趣的同学可以自己寻找.</p>
<ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;">
   参考:</p>
<li><a href="http://thexploit.com/sec/critical-php-remote-vulnerability-introduced-in-fix-for-php-hashtable-collision-dos/" >http://thexploit.com/sec/critical-php-remote-vulnerability-introduced-in-fix-for-php-hashtable-collision-dos/</a></li>
<li><a href="http://auntitled.blogspot.com/2012/02/mini-poc-for-php-rce-cve-2012-0830.html" >http://auntitled.blogspot.com/2012/02/mini-poc-for-php-rce-cve-2012-0830.html</a></li>
</ul>
<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_bash.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></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/08/2528.html" >2012/02/08</a>, mahone writes: 一个bug导致的另一个bug。。。学习。。。</li><li><a href="http://www.laruence.com/2012/02/08/2528.html" >2012/02/08</a>, mafia writes: 虽然看的不是太懂。但是看到老哥用中文标识“注意这个”倍受感动，有种内牛满面的感觉。
我要好好学习。</li><li><a href="http://www.laruence.com/2012/02/08/2528.html" >2012/02/09</a>, <a href="http://thexploit.com/"  rel="external nofollow"  class="url" >Dustin Schultz</a> writes: Nice write up. I've been trying to exploit it as well but haven't been successful yet.</li><li><a href="http://www.laruence.com/2012/02/08/2528.html" >2012/02/09</a>, <a href="http://lidashuang.sinaapp.com/?p=58"  rel="external nofollow"  class="url" >lidashuang &raquo; 我们什么时候应该使用异常?</a> writes: [...] PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830) [...]</li><li><a href="http://www.laruence.com/2012/02/08/2528.html" >2012/02/12</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</a> writes: 请问，首页文章内容截断是通过什么插件来实现的？</li><li><a href="http://www.laruence.com/2012/02/08/2528.html" >2012/02/13</a>, Anonymous writes: ERROR: unable to read what child say: Bad file descriptor 
鸟哥您好，我在从php-5.3.8升级到php-5.3.10后 php-fpm在关闭时 遇到了这个问题，google后无果，希望能您能指点下 谢谢</li><li><a href="http://www.laruence.com/2012/02/08/2528.html" >2012/05/15</a>, a writes: Write in english man!:)</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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</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></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/08/2528.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<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在里面.  我一直认为, 构建一个交流平台, 让同学们能顺畅, 简单的沟通, 是营造积极的技术学习氛围的基础和前提. 让每个人的问题不会成为别人的问题, 则是最直接的利益. (后记: 不少人都问邮件组地址, 实在不好意思, 这个邮件组是公司内部的邮件组, Hi也是公司内部的. 谢谢)</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><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/04</a>, phper writes: 求hi群号</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/06</a>, <a href="http://blog.iterse.com"  rel="external nofollow"  class="url" >Iterse's blog</a> writes: 支持下，两边都做分析了，哈哈。奢望一下哦，希望能加入您的php邮件组。</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/06</a>, <a href="http://www.w3hacker.com"  rel="external nofollow"  class="url" >万维网黑客联盟</a> writes: 万维网黑客联盟 求友情链接</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/07</a>, likemeng writes: 希望能加入邮件组！</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/07</a>, xiatian writes: 我一直有个困惑,通常情况下某个函数或方法只返回true和false,在特定条件下需要抛出一个异常(当然也就没有返回值了),当抛出异常后,原先调用这个函数或者方法的流程自然就没有继续执行了,程序通常会由set_exception_handler定义的处理方式去处理异常了,而此前调用的流程就被阻断,而我又不想对它单独定义try/catch.
演示伪代码:
function is_ok(xxx){
    if (not xxx){throw new Exception('xxx is not ok')}
    return true OR false;
}

...
if (is_ok())
{
    :)
}
else
{
    :(
}

//抛出异常后上面的就不会执行了,有没有不在这里try/catch的解决办法,我想总是用set_exception_handler去处理所有异常</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/07</a>, <a href="http://iptohost.net"  rel="external nofollow"  class="url" >Peter</a> writes: 博主你平时用的zend是上面的颜色主题吗？？</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/07</a>, <a href="http://pdfdog.org"  rel="external nofollow"  class="url" >pdfdog</a> writes: 博主你的zend主题叫什么啊，好顺眼，麻烦给偶百度下啦~</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/08</a>, <a href="http://china.com"  rel="external nofollow"  class="url" >dulidong</a> writes: 支持下laruence,希望能加入邮件组</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/08</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @pdfdog 这是vim, 不过好像zend ide也有类似的配色方案, 只是我不知道 :)</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/08</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</a> writes: 请问，这个vim的配色方案叫什么名字？</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/08</a>, <a href="http://waibo.net/"  rel="external nofollow"  class="url" >Rhythm</a> writes: 能否发起，成立一个中国PHP的邮件组。</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/08</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >laruence</a> writes: @Rhythm 好注意, 我试着问问Rasmus. 另外这个配色方案好像叫做ir_black..</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/09</a>, <a href="http://lidashuang.sinaapp.com/?p=58"  rel="external nofollow"  class="url" >lidashuang &raquo; 我们什么时候应该使用异常?</a> writes: [...] 本文地址: http://www.laruence.com/2012/02/02/2515.html [...]</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/02/29</a>, owen writes: hey,鸟哥.

请问你的hi群是只对公司内部同事交流么?

我可以加入么</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/03/14</a>, tokimeki writes: 大部分的時候我都是用異常來處理，不過我的工作是寫中間的元件，有時候必須吃掉異常來讓調用的一方繼續執行，可是當這種情況發生時，我並不確知錯誤的訊息調用方需不需要，不知道碰到這種情況有沒有甚麼模式可以參考？</li><li><a href="http://www.laruence.com/2012/02/02/2515.html" >2012/05/14</a>, <a href="http://tmkook.com/blog"  rel="external nofollow"  class="url" >tmkook</a> writes: http://tmkook.com/blog/archives/php-exception
呵呵，扩展阅读。。

我看到很多框架包括ZF异常都是去继承Exception
有什么好处？

我比较喜欢全部都使用系统的Exception</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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/02/2515.html/feed</wfw:commentRss>
		<slash:comments>24</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><li><a href="http://www.laruence.com/2012/02/01/2503.html" >2012/03/15</a>, Lukin writes: 请问退出之后的code是11是怎么回事？</li><li><a href="http://www.laruence.com/2012/02/01/2503.html" >2012/04/12</a>, deven 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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/02/01/2503.html/feed</wfw:commentRss>
		<slash:comments>6</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><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/02/05</a>, <a href="http://www.sklinux.com"  rel="external nofollow"  class="url" >sk</a> writes: 同样的祝福你也送给你！</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/02/05</a>, <a href="http://www.pcyoyo.com"  rel="external nofollow"  class="url" >localtest</a> writes: 龙年大吉！</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/03/01</a>, 娟儿 writes: 。。有差距啊  订阅 永远健康  不经意进来的比较健康。。。这。。</li><li><a href="http://www.laruence.com/2012/01/24/2494.html" >2012/04/03</a>, 十一文 writes: 永远健康</li></ul><hr/><small  style="font-size:85%;font-size:85%;">Copyright &copy; 2010 <a href="http://www.laruence.com"  target="_blank" >风雪之隅</a> 版权所有, 转载务必注明. 该Feed只供个人使用, 禁止未注明的转载或商业应用. 非法应用的, 一切法律后果自负. 如有问题, 可发E-mail至my at laruence.com.(Digital Fingerprint: 73540ba0a1738d7d07d4b6038d5615e2)</small><h2 class="related_post_title" >Random Posts:</h2><ul class="related_post"   style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/10/05/2192.html"  title="mysqlnd插件mysqlnd_ms的介绍" >mysqlnd插件mysqlnd_ms的介绍</a></li><li><a href="http://www.laruence.com/2007/11/15/10.html"  title="一个误区（关于javascript的字符串拼接)" >一个误区（关于javascript的字符串拼接)</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2009/01/07/656.html"  title="Mess it up!" >Mess it up!</a></li><li><a href="http://www.laruence.com/2011/01/20/1840.html"  title="Expect:100-continue" >Expect:100-continue</a></li><li><a href="http://www.laruence.com/2011/01/27/1854.html"  title="深入理解PHP内存管理之一个低概率Core的分析" >深入理解PHP内存管理之一个低概率Core的分析</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li><li><a href="http://www.laruence.com/2008/07/11/108.html"  title="IE下的Javascript调试利器:Companion.js" >IE下的Javascript调试利器:Companion.js</a></li><li><a href="http://www.laruence.com/2010/12/14/1816.html"  title="Compilation failed: support for \P, \p, and \X has not been compiled" >Compilation failed: support for \P, \p, and \X has not been compiled</a></li><li><a href="http://www.laruence.com/2011/09/22/2152.html"  title="回答下在bugs.php上的一个问题" >回答下在bugs.php上的一个问题</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/01/24/2494.html/feed</wfw:commentRss>
		<slash:comments>17</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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li></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><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/02/05</a>, <a href="http://www.sklinux.com"  rel="external nofollow"  class="url" >sk</a> writes: 非常好的文章哦，博主加油！</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/02/23</a>, <a href="http://jasongian.com"  rel="external nofollow"  class="url" >Jason</a> writes: 鸟哥太淫荡啦</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/02/25</a>, <a href="http://yuetao.org"  rel="external nofollow"  class="url" >hop-pocket</a> writes: good!</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/03/22</a>, callme小刀 writes: 我一般用第三种方案，对用第四种方案，个人认为可以解决问题，仅仅是可以解决问题而已～～</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/04/11</a>, <a href="http://www.837i.com"  rel="external nofollow"  class="url" >hwz</a> writes: 您的第三种方法，跟使用缓存时，是缓存主动过期很相似，看来编程思想很重要啊</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/04/14</a>, <a href="http://cogiestudio.net/?p=40"  rel="external nofollow"  class="url" >如何设置一个严格30分钟过期的Session | Cogie工作室</a> writes: [...] http://www.laruence.com/2012/01/10/2469.html    此条目由 admin 发表在 php 分类目录，并贴了 php、session [...]</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/04/17</a>, Jagger Wang writes: 2. 那设置一个大概率的清理机会呢? 还是不妥, 为什么? 因为PHP使用stat Session文件的修改时间来判断是否过期

如果Session文件在创建后又被修改了，那Session的过期时间从这个修改时间段算起？好怪异，为什么不从创建时间算起。</li><li><a href="http://www.laruence.com/2012/01/10/2469.html" >2012/04/23</a>, Zachary writes: 不根据session文件的创建时间来判断是必需的. 因为session本身的主要职责就是维持这个会话的活动性. 他的本意就是只要这个会话在我规定的时间段内有一次活动那他就是活得. 如果从创建时间算起. 那上面的这个主要职责就被推翻了.

一般不会把session存在实体文件里面. 多服务器之间这是个大问题. 多数的做法是直接使用cookie. 或者把session的处理设置到memcache之类的分布式载体上. 既然自定义了php的session处理函数. 那这个题目就easy了. 我的地盘我做主..</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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2012/01/10/2469.html/feed</wfw:commentRss>
		<slash:comments>22</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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2011/12/30/2440.html"  title="PHP5.2.*防止Hash冲突拒绝服务攻击的Patch" >PHP5.2.*防止Hash冲突拒绝服务攻击的Patch</a></li></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><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/05</a>, <a href="http://www.sklinux.com"  rel="external nofollow"  class="url" >sk</a> writes: 已经使用。非常不错
5.2.17使用还比较广泛</li><li><a href="http://www.laruence.com/2011/12/30/2440.html" >2012/02/12</a>, <a href="http://www.ywjt.org/index/archives/351.html"  rel="external nofollow"  class="url" >运维军团——运维技术与开源架构交流 &raquo; Hash冲突实现各种拒绝服务攻击</a> writes: [...] http://www.laruence.com/2011/12/30/2440.html [...]</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/2011/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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li><li><a href="http://www.laruence.com/2012/01/07/2453.html"  title="2012年1月全球www网站技术报告" >2012年1月全球www网站技术报告</a></li><li><a href="http://www.laruence.com/2011/12/30/2435.html"  title="PHP数组的Hash冲突实例" >PHP数组的Hash冲突实例</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/30/2440.html/feed</wfw:commentRss>
		<slash:comments>30</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><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2012/02/17</a>, <a href="http://blog.biaojita.com/index.php/2011/12/the-php-the-hashtable-denial-of-service-attacks/"  rel="external nofollow"  class="url" >标记它！博客 &raquo; Blog Archive &raquo; PHP hashtable拒绝服务攻击</a> writes: [...] 主要参考这里，hashtable实现的时候，都有冲突检测和冲突解决的机制，攻击者利用这个机制来构造一个超大的POST GET参数，这个参数恰好造成hashtable 也即php array在存储值的时候产生冲突，造成性能低下，占用系统资源，造成服务宕机。解决的方式必须得深入到PHP 内核里面来解决，比如控制解析POST GET参数的数量，或者控制解析这些外部变量构造的时候需要解析时间来降低拖慢服务器的问题。 [...]</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2012/03/05</a>, <a href="http://blog.admin8.us/?p=17832"  rel="external nofollow"  class="url" >绝尘博客 &raquo; Hash冲突构造拒绝服务攻击例子(PHP5.3.10以下版本)</a> writes: [...] PHP数组的Hash冲突实例 [...]</li><li><a href="http://www.laruence.com/2011/12/30/2435.html" >2012/04/08</a>, <a href="http://www.iirr.info/blog/?p=899"  rel="external nofollow"  class="url" >开发中遵循或自创标准所衍生的安全问题杂想 &raquo; HorseLuke@微碌</a> writes: [...] [7] http://www.laruence.com/2011/12/30/2435.html [...]</li></ul><hr/><h2>Related posts:</h2><ul  style="padding-left:1em;font-size:85%;padding-left:1em;font-size:85%;"><li><a href="http://www.laruence.com/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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</a></li><li><a href="http://www.laruence.com/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2012/02/02/2515.html"  title="我们什么时候应该使用异常?" >我们什么时候应该使用异常?</a></li><li><a href="http://www.laruence.com/2012/02/01/2503.html"  title="使用exit(-1)为什么得到255退出码?" >使用exit(-1)为什么得到255退出码?</a></li><li><a href="http://www.laruence.com/2012/01/11/2482.html"  title="PHP的历史" >PHP的历史</a></li><li><a href="http://www.laruence.com/2012/01/10/2469.html"  title="如何设置一个严格30分钟过期的Session" >如何设置一个严格30分钟过期的Session</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/30/2435.html/feed</wfw:commentRss>
		<slash:comments>15</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><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/02/04</a>, <a href="http://www.1x3x.net/blog/linux-vps/2012/02/using-php-fpm-in-lighttpd.html"  rel="external nofollow"  class="url" >IT民工的坐井观天 &raquo; Lighttpd下安装PHP5.3.10（使用PHP-FPM）</a> writes: [...] 最近安全领域出了很多新闻，从CSDN密码外泄开始，接踵而至。其中通过构造HASH冲突来拒绝服务涉及了大部分WEB开发语言（具体可以看 Laruence的文章），所以有必要将PHP更新到最新版本（目前是5.3.10）。不过这个过程并不怎么顺利，记录一下。 [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/02/08</a>, <a href="http://www.laruence.com/2012/02/08/2528.html"  rel="external nofollow"  class="url" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830) | 风雪之隅</a> writes: [...] 还记得我之前说的PHP Hash Collisions Ddos漏洞吧? 最初的时候, 开发组给出的修复方案, 采用的是如果超过max_input_vars, 就报错(E_ERROR), 继而导致PHP出错结束. 而后来, 为了更加轻量级的解决这个问题, 我们又改善了一下, 变成了如果超过max_input_vars, 就发出警告, 并且不再往目的数组添加, 但是流程继续. 然后我们发布了5.3.9. [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/02/09</a>, <a href="http://lidashuang.sinaapp.com/?p=58"  rel="external nofollow"  class="url" >lidashuang &raquo; 我们什么时候应该使用异常?</a> writes: [...] 通过构造Hash冲突实现各种语言的拒绝服务攻击 [...]</li><li><a href="http://www.laruence.com/2011/12/29/2412.html" >2012/02/09</a>, <a href="http://www.ywjt.org/index/archives/351.html"  rel="external nofollow"  class="url" >运维军团——运维技术与开源架构交流 &raquo; Hash冲突实现各种拒绝服务攻击</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/02/29</a>, <a href="http://blog.me4399.com/index/archives/112.html"  rel="external nofollow"  class="url" >运维技术交流 &raquo; Hash冲突实现各种拒绝服务攻击</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/04/04</a>, <a href="http://www.iirr.info/blog/?p=899"  rel="external nofollow"  class="url" >开发中遵循或自创标准所衍生的安全问题杂想 &raquo; HorseLuke@微碌</a> writes: [...] [6] 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/2012/02/08/2528.html"  title="PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)" >PHP-5.3.9远程执行任意代码漏洞(CVE-2012-0830)</a></li><li><a href="http://www.laruence.com/2008/07/24/206.html"  title="Apache启动过程(PHP_MINIT_FUNCTION的调用)" >Apache启动过程(PHP_MINIT_FUNCTION的调用)</a></li><li><a href="http://www.laruence.com/2012/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li><li><a href="http://www.laruence.com/2012/02/14/2544.html"  title="PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展" >PHP Taint &#8211; 一个用来检测XSS/SQL/Shell注入漏洞的扩展</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></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/29/2412.html/feed</wfw:commentRss>
		<slash:comments>34</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><li><a href="http://www.laruence.com/2011/12/19/2409.html" >2012/02/11</a>, webxu writes: var_dump(isset($a["foo"]));php执行出来是true
而
var_dump(empty($a["foo"]));php执行出来是false

怎么解释？</li><li><a href="http://www.laruence.com/2011/12/19/2409.html" >2012/02/11</a>, webxu writes: php版本问题？</li><li><a href="http://www.laruence.com/2011/12/19/2409.html" >2012/04/27</a>, test writes: var_dump(isset($a["foo"]));
//false

已经定义的变量，为什么会是false?</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>5</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 754]]></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 754</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 754</a>规定, 是定长的, 一定是64bits.</p>
<p>    请记住这一点, 造就了PHP的一些代码的&#8221;非平台无关性&#8221;. <b>我们接下来的讨论, 除了特别指明, 都是假设long为64bits</b></p>
<p>    IEEE 754的浮点计数法, 我这里就不引用了, 大家有兴趣的可以自己查看,  关键的一点是,  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/2011/11/09/2277.html"  title="PHP原理之内存管理中难懂的几个点" >PHP原理之内存管理中难懂的几个点</a></li><li><a href="http://www.laruence.com/2010/01/21/1254.html"  title="IE下var的重要性的又一佐证" >IE下var的重要性的又一佐证</a></li><li><a href="http://www.laruence.com/2011/03/18/1916.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/2011/06/28/2088.html"  title="在Windows下编译Yaf" >在Windows下编译Yaf</a></li><li><a href="http://www.laruence.com/2010/06/08/1579.html"  title="深悉正则(pcre)最大回溯/递归限制" >深悉正则(pcre)最大回溯/递归限制</a></li><li><a href="http://www.laruence.com/2008/11/11/606.html"  title="图解aclocal、autoconf、automake、autoheader、configure" >图解aclocal、autoconf、automake、autoheader、configure</a></li><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/07/18/124.html"  title="Dom事件的srcTarget,strElement探幽" >Dom事件的srcTarget,strElement探幽</a></li><li><a href="http://www.laruence.com/2008/04/16/98.html"  title="使用fscok实现异步调用PHP " >使用fscok实现异步调用PHP </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><li><a href="http://www.laruence.com/2011/12/06/2381.html" >2012/05/04</a>, yang writes: 那其实代表着什么？这样不是一个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/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/05/02/2613.html"  title="让PHP更快的提供文件下载" >让PHP更快的提供文件下载</a></li><li><a href="http://www.laruence.com/2012/02/18/2560.html"  title="Taint-0.3.0(A XSS codes sniffer) released" >Taint-0.3.0(A XSS codes sniffer) released</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.laruence.com/2011/12/06/2381.html/feed</wfw:commentRss>
		<slash:comments>10</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><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/02/08</a>, cindy ming writes: 您好,

请问yaf有layout的这个概念吗？我们应该怎么扩展可以达到layout的效果，因为当用户的角色不同的时候我们的layout是不一样的。

谢谢</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/02/08</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >laruence</a> writes: @cindy ming 暂时没有, 你可以使用不同的模板来实现, 或者使用自定义的视图引擎. 

不过, Yaf的视图引擎将会支持layout, 预计在2.2版本中</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/03/14</a>, michael writes: 和doophp比较呢？有测试结果吗？</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/03/16</a>, Anonymous writes: 2.1.8
/usr/bin/phpize ./configure --with-php-config=/usr/bin/php-config
Configuring for:
PHP Api Version:         20090626
Zend Module Api No:      20090626
Zend Extension Api No:   220090626</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/05/02</a>, <a href="http://www.pakey.net"  rel="external nofollow"  class="url" >pakey</a> writes: 请问是否有yaf框架的一个小项目具体实例
可以便于参照</li><li><a href="http://www.laruence.com/2011/12/02/2333.html" >2012/05/05</a>, <a href="http://www.laruence.com"  rel="external nofollow"  class="url" >雪候鸟</a> writes: @pakey 看这里: http://yafphp.com/forum.php?mod=viewthread&tid=21#lastpost</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>30</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取值, 都会把键值转换成integer, 所以, &#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>
	</channel>
</rss>

