<?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>CNXCT小组的博客 &#187; PHP</title>
	<atom:link href="http://www.cnxct.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cnxct.com</link>
	<description>技术这个东西如同一个圆 ,刚开始的时候我们就如同站在圆心,一旦投入学习下去 ,圆就慢慢变大 ,圆的边缘以外也就会越来越大,接触的多了 知道的多了, 就会发现自己真的很无知!</description>
	<lastBuildDate>Tue, 31 Jan 2012 07:56:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>php5.3.8中编译pdo_mysql的艰难历程</title>
		<link>http://www.cnxct.com/some-errors-on-compile-php-5-3-8-with-pdo_mysql-and-mysqlnd/</link>
		<comments>http://www.cnxct.com/some-errors-on-compile-php-5-3-8-with-pdo_mysql-and-mysqlnd/#comments</comments>
		<pubDate>Fri, 25 Nov 2011 05:33:26 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[mysqlnd]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[拓展]]></category>
		<category><![CDATA[编译]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/?p=788</guid>
		<description><![CDATA[<a href="http://www.cnxct.com/wp-content/uploads/2011/11/macro_photos_9.jpg"><img src="http://www.cnxct.com/wp-content/uploads/2011/11/macro_photos_9-150x150.jpg" alt="" title="程序要严谨、细心" width="150" height="150" class="alignleft sided inline" /></a>1，以官方文档为准，一切跟着官方文档来，不轻易采信网络上网友提供的编译参数，包括这边博文。不论对方是老手、大牛，还是其他什么什么有威望的人。他们提供的方法或许跟你当前的环境不一致，时间也相差很大，或许相隔好几年了；2，确认得到的结果是准确的，怎么说呢，文中的例子中php-i的路径不是我们新编译的，而是之前编译，或者yum安装的，一定要到自己编译的程序目录下，用自己新编译的脚本去执行测试，获得测试结果，下结论，不为了偷懒，不敲路径，直接写程序名进行测试；]]></description>
			<content:encoded><![CDATA[<p>我们的一个项目，用了<a href="http://pecl.php.net/package/PDO_MYSQL">PDO_MYSQL</a>拓展，准备迁移服务器，新环境需要编译安装环境。昨天，运维同事抽空编译了一下，一直编译不上pdo_mysql，同时，公司的一款新webgame临近上线，他们实在太忙，我这个三流运维技术的程序员来试试吧。</p>
<p>运维同事描述：<br />
服务器系统版本：Linux version 2.6.32-71.el6.x86_64 (mockbuild@c6b6.centos.org) (gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) ) #1 SMP Fri May 20 03:51:51 BST 2011</p>
<p>编译PHP的参数</p>
<pre class="brush: bash; title: ; notranslate">
...
tar zxvf $soft_dir/php-5.3.8.tar.gz -C $soft_tmp
cd  $soft_tmp/php-5.3.8
 ./configure  --prefix=$soft_install/php --with-config-file-path=$soft_install/php/etc --with-mysql=$soft_install/mysql --with-mysqli=mysqlnd  --with-gd=$soft_install/gd --with-jpeg-dir=$soft_install/jpeg --with-png-dir=$soft_install/png --with-freetype-dir=$soft_install/freetype --enable-bcmath --with-mcrypt  &amp;&amp; make &amp;&amp; make install
...
</pre>
<p>之后再次编译 pdo_mysql 拓展</p>
<pre class="brush: bash; title: ; notranslate">
...
cd $soft_tmp/PDO_MYSQL-1.0.2/
$soft_install/php/bin/phpize
./configure --with-php-config=$soft_install/php/bin/php-config  --with-pdo-mysql=$soft_install/mysql/  &amp;&amp; make &amp;&amp; make install
...
</pre>
<p>之后， shell里执行 php -i 和 php -m都没有看到 pdo_mysql拓展。搜pdo_mysql，在将路径添加到php.ini中，仍找不到这个扩展，判断为编译失败。</p>
<p>这里是将pdo_mysql作为一个拓展引入使用的。在php5.3中，PHP开发组把mysqlnd作为默认的连接MYSQL的数据库驱动来使用，据官方描述，节省内存40%，速度更快，当然或许是为了解决许可协议的问题。之前PHP连接MYSQL，是调用MYSQL官方提供的C/C++编写的lib_mysql的dll/so,来实现。这个类库同样可以给PYTHON等脚本语言调用，只要按照API规范来。我们改用mysqlnd之后，就不用再为了lib_mysql去安装mysql client了。详情见：<a href="http://www.laruence.com/2011/10/05/2192.html" title="mysqlnd插件mysqlnd_ms的介绍" target="_blank">mysqlnd插件mysqlnd_ms的介绍</a>。<br />
两种方法都可以，运维同事都尝试了，由于时间关系，他们没做过多的尝试研究，就转向更紧急的项目了。</p>
<p>运维同事下载使用的PDO_MYSQL拓展的地址是 <a href="http://pecl.php.net/package/PDO_MYSQL">http://pecl.php.net/package/PDO_MYSQL</a> ，里面用很耀眼的颜色，标注如下几行字</p>
<blockquote><p>This package is not maintained anymore and has been superseded. Package has moved to channel http://svn.php.net/viewvc/php/php-src/trunk/ext/pdo_mysql/, package ext/pdo_mysql.</p></blockquote>
<p>也就是说，早在2006年5月1(我是根据最后一个打包文件日期猜的，或许不准)之后，PHP已经将这个pdo拓展放到PHP源码的 ext/pdo_mysql下内置了。这里的这个包，将不会在更新维护了。</p>
<p>在PHP官方文档上对<a href="http://www.php.net/pdo_mysql" title="pdo_mysql" target="_blank">pdo_mysql</a>使用<a href="http://www.php.net/manual/zh/mysqlnd.install.php" title="mysqlnd" target="_blank">mysqlnd</a>的时候，是这么描述的<br />
在php5.3中，已经支持mysqlnd作为数据库连接驱动了。而在将来的php5.4中，将变为默认的连接驱动。如图：<br />
<div id="attachment_793" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2011/11/mysqlnd-pdo_mysql.jpg" rel="lightbox[788]"><img src="http://www.cnxct.com/wp-content/uploads/2011/11/mysqlnd-pdo_mysql-150x150.jpg" alt="" title="mysqlnd-pdo_mysql" width="150" height="150" class="size-thumbnail wp-image-793" /></a><p class="wp-caption-text">mysqlnd-pdo_mysql</p></div></p>
<p>开启这个类库的</p>
<pre class="brush: bash; title: ; notranslate">
./configure --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd
</pre>
<p>之后，我的编译参数如下</p>
<pre class="brush: bash; title: ; notranslate">
./configure  --prefix=/usr/local/services/php --with-config-file-path=/usr/local/services/php/etc --with-pdo-mysql=mysqlnd --with-mysql=mysqlnd --with-mysqli=mysqlnd  --with-iconv-dir=/usr/local/services/libiconv --disable-phar --with-gd=/usr/local/services/gd --with-jpeg-dir=/usr/local/services/jpeg --with-png-dir=/usr/local/services/png --with-freetype-dir=/usr/local/services/freetype --enable-bcmath --with-mcrypt
</pre>
<p>区别是使用php内置的pdo_mysql类库，使用mysqlnd作为连接驱动。</p>
<p>make之后，提示如下错误</p>
<pre class="brush: bash; title: ; notranslate">
soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1070: undefined reference to `mysql_eof'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1070: undefined reference to `mysql_fetch_row'
ext/mysql/php_mysql.o: In function `zif_mysql_error':
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1727: undefined reference to `mysql_error'
ext/mysql/php_mysql.o: In function `zif_mysql_errno':
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1758: undefined reference to `mysql_errno'
ext/mysql/php_mysql.o: In function `php_mysql_do_connect':
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:705: undefined reference to `mysql_get_client_version'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:963: undefined reference to `mysql_init'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:976: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:980: undefined reference to `mysql_real_connect'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:1002: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:706: undefined reference to `mysql_get_client_version'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:844: undefined reference to `mysql_init'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:850: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:853: undefined reference to `mysql_real_connect'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:871: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:989: undefined reference to `mysql_error'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:992: undefined reference to `mysql_errno'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:898: undefined reference to `mysql_ping'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:899: undefined reference to `mysql_errno'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:901: undefined reference to `mysql_real_connect'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:911: undefined reference to `mysql_options'
/data/sa/suse-soft/soft_tmp/php-5.3.8/ext/mysql/php_mysql.c:862: undefined reference to `mysql_error'
</pre>
<p>这种错误，让我手足无措，GOOGLE搜了下，也没找到相关案例，而且，一直被墙，打不开国外网页。百度搜的结果，还是算了。(中文还行，E文的话，百度确实不行，尤其是程序相关)<br />
之后，尝试make clean，清除之前的编译结果缓存之类。<br />
再次make，有个小意外</p>
<pre class="brush: bash; title: ; notranslate">
ERROR: invalid PHP executable specified by TEST_PHP_EXECUTABLE  = .....
</pre>
<p>再次搜索，这倒是很多网友遇到过，大部分的建议就是无视这个错误，不影响编译。照做。make install ，一路挺顺畅。</p>
<p>接着，php -i / php -m 也没发现pdo_mysql模块。<br />
郁闷无比，决定看下web下的phpinfo结果，发现居然有了。问题终于解决了。。。万岁。。</p>
<p>可是！！！<br />
1，为啥php -i 、php -m 的结果里看不到呢？ 思考，为什么呢？<br />
结合刚刚的报错，联想到CLI 模式下的php 脚本(以及相关的php.ini)跟刚刚从web下访问的php程序不是同一个。检查环境变量，以及切换到编译好的目录下执行php -i，发现pdo_mysql、mysqlnd等相关添加的模块了。</p>
<p>2，php.ini里没启用pdo_mysql拓展，为什么还能看的到呢？<br />
这次使用的是PHP内置的类库，不是以新拓展方式加载运行的，所以，不用更改php.ini，再添加相关so路径。</p>
<p>综上所述，文章没有高深的东西，只是有几个需要细心的点。<br />
1，以官方文档为准，一切跟着官方文档来，不轻易采信网络上网友提供的编译参数，包括这边博文。不论对方是老手、大牛，还是其他什么什么有威望的人。他们提供的方法或许跟你当前的环境不一致，时间也相差很大，或许相隔好几年了。<br />
2，确认得到的结果是准确的，怎么说呢，文中的例子中php-i的路径不是我们新编译的，而是之前编译，或者yum安装的，一定要到自己编译的程序目录下，用自己新编译的脚本去执行测试，获得测试结果，下结论，不为了偷懒，不敲路径，直接写程序名进行测试。<br />
3，遇到诡异的错误，我总会想要一个全新的系统，进行安装，以确保不被各种冗余、缓存等垃圾文件干扰。例子中用了make clean进行清除相关缓存，来解决文件缓存问题。(感谢<a href="http://weibo.com/ivonlee">@ivon_lee</a> 的帮助)<br />
4，自动安装脚本要及时更新，当然，不是意味着追求最新版本。例子中的pdo_mysql的拓展，官方提供了更好的方式，不论是效率，资源占用，都有更好的提升，为啥不使用呢。</p>
<p>备注：mysqlnd 的相关有点对比见<a href="http://developer.51cto.com/art/200903/115995.htm">http://developer.51cto.com/art/200903/115995.htm</a></p>
<p>PS:文中出现的我搜索无果两次错误，如果有人知道，请告诉我，谢谢。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/some-errors-on-compile-php-5-3-8-with-pdo_mysql-and-mysqlnd/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WEB开发安全与运维安全浅见</title>
		<link>http://www.cnxct.com/web-development-security-ppt/</link>
		<comments>http://www.cnxct.com/web-development-security-ppt/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 06:16:33 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[开发]]></category>
		<category><![CDATA[招聘]]></category>
		<category><![CDATA[正则]]></category>
		<category><![CDATA[网络安全]]></category>
		<category><![CDATA[运维]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/?p=764</guid>
		<description><![CDATA[<a href="http://www.cnxct.com/wp-content/uploads/2011/09/62ca611cjw1dlaijihpjaj.jpg"><img src="http://www.cnxct.com/wp-content/uploads/2011/09/62ca611cjw1dlaijihpjaj-150x150.jpg" alt="" title="62ca611cjw1dlaijihpjaj" width="150" height="150" class="alignleft sided inline" /></a>SESSION与COOKIE到底哪个更安全?去年80sec公布关于NGINX+php的漏洞，跟今年的这次是同一个漏洞？有关系吗？http keep-alive超时时间过长，会带来安全问题吗？设置多少秒合适？腾讯QQ群文件包含漏洞又是怎么一回事呢？借用网友的一句话，作为程序员，尽量要做到“知其然，知其所以然”，多多关注web安全，不要给安全工程师添麻烦，不能丢了程序员的脸。]]></description>
			<content:encoded><![CDATA[<p>前段时间，同事<a href="http://weibo.com/qxsxysxd" title="LeeQueen" target="_blank">LeeQueen</a>为公司同事做了个《安全意识防护》的PPT，效果很好，各位新同事也知道日常公工作中，不太注意到的隐私保护问题。PPT中也提到了一些社会工程学的案例，提到了某团购网站前台人员被声称是新开礼品公司的工作人员，以填写信息就送礼品为由，获取到此团购网站的所有员工联系方式。后此团购网站的高层打电话回访，得知对方是猎头公司[详情见<a href="http://www.wooyun.org/bugs/wooyun-2010-01370" target="_blank">乌云网</a>的链接]。此案例非常典型，讨论也尤为激烈，可谓是非常成功的培训。</p>
<p>此次培训之后，职业欠钱[<a href="http://weibo.com/zyqq" target="_blank">sina微博</a>][<a href="http://t.qq.com/zhiyeqianqian" target="_blank">腾讯微博</a>]让我给我们开发部门的PHP程序员同事们做一次PHP开发、运维时候一些安全注意事项。由于我在安全这块资历较浅，没有经验，我了解的大家都懂，这个话题太高深，我的水平完全不够，没法写这个PPT。而且，同事里有好几位安全界的前辈，我怎可关公面前耍大刀呢。上次写过一次关于<a href="http://www.cnxct.com/regularexpressions-pptx-pdf-share/">正则表达式PPT</a>，也就是一个月之前，深刻的体会到写PPT的痛苦，尤其是排版。实在不想写了。</p>
<p>后来，经常看到网上的安全工程师提到程序员安全意识较差，以至于同样的危险代码，危险程序，却屡次不改。当然，不是程序员不想改，而是程序员不太理解代码形成安全漏洞的原因。为此，我也觉得有必要提高一下我们程序员的安全意识了。</p>
<p>PPT中写了网络上常见的漏洞，形成原因，漏洞原理，防护建议等；也列举了近年来跟WEB相关的安全漏洞，以程序员的视角理解漏洞原理，并给出修复建议。这些建议仅供参考，不是正确答案。  由于本人水平原因，PPT中难免有错误，请见谅。也请安全界工程师指正。</p>
<p>借用网友的一句话，作为程序员，尽量要做到<strong>“知其然，知其所以然”</strong>，多多关注web安全，不要给安全工程师添麻烦，不能丢了程序员的脸。<br />
<div id="attachment_768" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2011/09/shengxie.jpg" rel="lightbox[764]"><img src="http://www.cnxct.com/wp-content/uploads/2011/09/shengxie-150x50.jpg" alt="" title="做人要有气节，不能丢了我们弄PHP的脸" width="150" height="50" class="size-thumbnail wp-image-768" /></a><p class="wp-caption-text">做人要有气节，不能丢了我们弄PHP的脸</p></div></p>
<p>同时，公司招聘PHP程序员，地点上海，公司规模为150人+，做网络游戏研发、运营。招聘条件以及待遇之类的，可以通过以下方式联系我，我们私聊。</p>
<p><a href="http://weibo.com/cfc4nx">http://weibo.com/cfc4nx</a><br />
<a href="http://t.qq.com/cfc4nx">http://t.qq.com/cfc4nx</a><br />
邮箱：cfc4n@博客域名点COM</p>
<p>最后，PPT是周末两天写的，这两天老婆挺着6个月的大肚子，为我做饭，老婆实在是太辛苦了，感谢我老婆。<br />
PS：讨厌写PPT[流泪]。</p>
<p>在线阅读：</p>
<div style="width:425px" id="__ss_9330286"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/cfc4n/web-9330286" title="Web开发与运维安全浅见">Web开发与运维安全浅见</a></strong><object id="__sse9330286" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=web-110919213025-phpapp02&#038;stripped_title=web-9330286&#038;userName=cfc4n" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse9330286" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=web-110919213025-phpapp02&#038;stripped_title=web-9330286&#038;userName=cfc4n" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/cfc4n">cfc4n</a>.</div>
</div>
<p>下载到本地：<br />
<strong>PPT下载：<a href='http://www.cnxct.com/wp-content/uploads/2011/09/web-development-security-ppt.zip'>web开发与运维安全浅见PPT下载，猛点这里</a></strong><br />
<strong>更多亮点在PPT的备注里，各位一定要看备注。转载的朋友麻烦保留PPT完整，包括招人信息。尤其是备注要保留。</strong><br />
&#8212;&#8212;-<br />
PPT在2011/09/19 更新了，更换匹配NGINX 对URI中PHP脚本的正则，考虑到了拓展名为 .phpa .phpb .phpc之类的情况。主要是更换了正则匹配的图，更改了正则内容。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/web-development-security-ppt/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>编译xhprof时的一个小意外</title>
		<link>http://www.cnxct.com/you-do-not-have-dot-image-generation-utility-installed/</link>
		<comments>http://www.cnxct.com/you-do-not-have-dot-image-generation-utility-installed/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 08:19:55 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[graphviz]]></category>
		<category><![CDATA[libpng]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[php优化]]></category>
		<category><![CDATA[png]]></category>
		<category><![CDATA[xhprof]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/?p=709</guid>
		<description><![CDATA[<img src="http://www.cnxct.com/wp-content/uploads/2011/03/xihu-150x150.jpg" alt="you do not have &#039;dot&#039; image generation utility installed. " title="you do not have &#039;dot&#039; image generation utility installed. " width="150" height="150" class="alignleft sided inline" /></a>当我查看[View Full Callgraph]的时候，却提示如下：<strong>Error: either we can not find profile data for run_id 4d7f0bd99a12f or the threshold 0.01 is too small or you do not have 'dot' image generation utility installed.</strong>，这TMD神马玩意？是什么错呢？]]></description>
			<content:encoded><![CDATA[<p>新项目基本开发完毕，剩余收尾工作。趁美工调整新UI的时间，赶紧在测试机上安装PHP的性能检测利器xhprof。<br />
下载地址<a href="http://pecl.php.net/get/xhprof-0.9.2.tgz">http://pecl.php.net/package/xhprof</a>，这里有tar包，我下了<a href="http://pecl.php.net/get/xhprof-0.9.2.tgz">http://pecl.php.net/get/xhprof-0.9.2.tgz</a>，</p>
<pre class="brush: bash; title: ; notranslate">
tar zxvf xhprof-0.9.2.tgz
cd xhprof-0.9.2
cp -r xhprof_html xhprof_lib &lt;directory_for_htdocs&gt; # 应用程序所在目录，其中xhprof_lib是生成统计数据用到的类库。xhprof_html是查看统计数据的时候，用到的类库。
cd extension
/usr/local/php/bin/phpize
./configure
make
make install
</pre>
<p>之后，遍完成了。一路很“顺利”。<br />
php.ini如下设置</p>
<p>extension=xhprof.so<br />
; 存放目录，这个目录用来存放统计程序性能生成的数据。要有读写权限。<br />
xhprof.output_dir=/var/xhprof_data</p>
<p>代码中，程序头部如下设置：</p>
<pre class="brush: php; title: ; notranslate">
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
</pre>
<p>程序最下面：</p>
<pre class="brush: php; title: ; notranslate">
$xhprof_data = xhprof_disable();
include_once &quot;./xhprof_lib/utils/xhprof_lib.php&quot;;
include_once &quot;./xhprof_lib/utils/xhprof_runs.php&quot;;
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs-&gt;save_run($xhprof_data, 'xhprof');
echo 'http://&lt;xhprof-ui-address &gt;/index.php?run='.$run_id.'&amp;source=xhprof';//source的值就是save_run的第二个参数的值。其中，网址就是上面保存xhprof_html的路径。
</pre>
<p>之后遍看到统计数据结果了。</p>
<p>可是，当我查看[View Full Callgraph]的时候，却提示如下：<strong>Error: either we can not find profile data for run_id 4d7f0bd99a12f or the threshold 0.01 is too small or you do not have &#8216;dot&#8217; image generation utility installed.</strong>，这TMD神马玩意？是什么错呢？<br />
关于dot的介绍，xhprof在这里写出来了：<br />
<a href="http://mirror.facebook.net/facebook/xhprof/doc.html">http://mirror.facebook.net/facebook/xhprof/doc.html</a></p>
<blockquote><p>dot (image generation utility): The callgraph image visualization ([View Callgraph]) feature relies on the presence of Graphviz “dot” utility in your path. “dot” is a utility to draw/generate an image for a directed graph. </p></blockquote>
<p>GOOGLE了半天，也没找到可用的信息。问了下群里的同学，大牛<a href="http://huoding.com/" title="火丁笔记" target="_blank">老王</a>告诉俺，xhprof绘制的是png图，系统(graphviz-2.24.0)不支持。才知道绘图的dot拓展没装成功。我的操作系统是UBUNTU 10.10 SERVER版的，也就是dot 不支持PNG。赶紧再次编译下graphviz，看看提示信息有什么缺少的。果然：</p>
<pre class="brush: plain; title: ; notranslate">
options:
  cgraph:        No (disabled by default - experimental)
  codegens:      No (disabled by default - deprecated)
  digcola:       Yes
  expat:         No (missing library)
  fontconfig:    No (missing fontconfig-config)
  freetype:      No (missing freetype-config)
  glut:          No (missing GL/glut.h)
  gts:           No (gts library not available)
  ipsepcola:     No (disabled by default - C++ portability issues)
  ltdl:          Yes
  ortho:         No (disabled by default - experimental)
  png:           No (missing png.h)
</pre>
<p>  <strong>png:           No (missing png.h)</strong>果然。。。。<br />
赶紧到libpng官网down分源码，再次编译一下。<br />
SF.NET上地址是 <a href="http://sourceforge.net/projects/libpng/files/libpng15/1.5.1/">http://sourceforge.net/projects/libpng/files/libpng15/1.5.1/</a>,我下的是http://sourceforge.net/projects/libpng/files/libpng15/1.5.1/libpng-1.5.1.tar.gz/download ，一气呵成，很顺利。<br />
再次编译graphviz的时候，提示如下：</p>
<pre class="brush: plain; title: ; notranslate">
 ortho:         No (disabled by default - experimental)
  png:           Yes
</pre>
<p>好了，内牛满面。之后就是 make&#038;make install了。<br />
当打开[View Full Callgraph]的时候，果然是性感的资源占用统计图了。<br />
展示下效果图：<br />
优化前：<br />
<div id="attachment_721" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2011/03/1.png" rel="lightbox[709]"><img src="http://www.cnxct.com/wp-content/uploads/2011/03/1-150x150.png" alt="xhprof性能监控图优化前" title="xhprof性能监控图优化前" width="150" height="150" class="size-thumbnail wp-image-721" /></a><p class="wp-caption-text">xhprof性能监控图优化前</p></div></p>
<p>找到问题所在，稍微调试：<br />
<div id="attachment_722" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2011/03/2.png" rel="lightbox[709]"><img src="http://www.cnxct.com/wp-content/uploads/2011/03/2-150x150.png" alt="xhprof性能监控图找到问题，调试中" title="xhprof性能监控图找到问题，调试中" width="150" height="150" class="size-thumbnail wp-image-722" /></a><p class="wp-caption-text">xhprof性能监控图找到问题，调试中</p></div></p>
<p>最终代码优化结果：<br />
<div id="attachment_723" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2011/03/3.png" rel="lightbox[709]"><img src="http://www.cnxct.com/wp-content/uploads/2011/03/3-150x150.png" alt="xhprof性能监控图优化结果" title="xhprof性能监控图优化结果" width="150" height="150" class="size-thumbnail wp-image-723" /></a><p class="wp-caption-text">xhprof性能监控图优化结果</p></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/you-do-not-have-dot-image-generation-utility-installed/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>广发英雄帖-招聘广告（DBA、PHP开发、运维工程师、BI专员）</title>
		<link>http://www.cnxct.com/%e5%b9%bf%e5%8f%91%e8%8b%b1%e9%9b%84%e5%b8%96-%e6%8b%9b%e8%81%98%e5%b9%bf%e5%91%8a%ef%bc%88dba%e3%80%81php%e5%bc%80%e5%8f%91%e3%80%81%e8%bf%90%e7%bb%b4%e5%b7%a5%e7%a8%8b%e5%b8%88%e3%80%81bi%e4%b8%93/</link>
		<comments>http://www.cnxct.com/%e5%b9%bf%e5%8f%91%e8%8b%b1%e9%9b%84%e5%b8%96-%e6%8b%9b%e8%81%98%e5%b9%bf%e5%91%8a%ef%bc%88dba%e3%80%81php%e5%bc%80%e5%8f%91%e3%80%81%e8%bf%90%e7%bb%b4%e5%b7%a5%e7%a8%8b%e5%b8%88%e3%80%81bi%e4%b8%93/#comments</comments>
		<pubDate>Fri, 12 Nov 2010 11:53:19 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[生活]]></category>
		<category><![CDATA[dba]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[sa]]></category>
		<category><![CDATA[招聘]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/?p=655</guid>
		<description><![CDATA[<a href="http://www.cnxct.com/wp-content/uploads/2010/11/wanxia.jpg"><img src="http://www.cnxct.com/wp-content/uploads/2010/11/wanxia-150x150.jpg" alt="" title="英雄帖" width="150" height="150" class="alignleft sided inline" /></a>首先，我已经改行了，因此这个招聘和安全无关，不是招安全工程师的。其次，我现在所在的团队，是一个比较年轻的团队，无论是同事的平均年龄，还是公司的成立时间，或者是公司的收入状况。所以，如果你现在觉得自己充满激情，渴望学习和成长，耐得住性子，能做好在小公司待2年以上的准备，不太在乎加班多（不一定有加班费），不太计较眼前得失，希望和公司一起成长，渴望自己的努力在公司的成功道路上占据重要的比重（相对于大公司比较细分化的工作岗位），并且有志于往下列岗位发展，欢迎投递简历至 cfc4n # cnxct ｛dot｝ com ，最好来信注明薪资期望]]></description>
			<content:encoded><![CDATA[<p>首先，我已经改行了，因此这个招聘和安全无关，不是招安全工程师的。</p>
<p>其次，我现在所在的团队，是一个比较年轻的团队，无论是同事的平均年龄，还是公司的成立时间，或者是公司的收入状况。</p>
<p>所以，如果你现在觉得自己充满激情，渴望学习和成长，耐得住性子，能做好在小公司待2年以上的准备，不太在乎加班多（不一定有加班费），不太计较眼前得失，希望和公司一起成长，渴望自己的努力在公司的成功道路上占据重要的比重（相对于大公司比较细分化的工作岗位），并且有志于往下列岗位发展，欢迎投递简历至 cfc4n # cnxct ｛dot｝ com ，<strong>最好来信注明薪资期望</strong></p>
<p><strong>公司性质：</strong>网游<br />
<strong>规模：</strong> 100人左右<br />
<strong>工作地点：</strong>上海<br />
<strong>待遇：</strong>根据个人能力而定，本次招聘主要面向中、基层岗位</p>
<p>除BI专员外，其余岗位无学历限制<br />
<strong>职位：</strong>运维工程师<br />
<strong>招聘人数：</strong>3-4人<br />
<strong>职位描述：<br />
</strong>1. 负责生产网络、服务器、数据库与支撑系统的建设、运维和监控，保证各业务系统正常运营；<br />
2. 负责突发性事件的快速响应和处理，解决服务器和网络故障；<br />
3. 研究运维相关技术，制定运维技术方案、部署统一化、集中化的运维系统和工具；<br />
4. 负责对现有运维系统的性能改善。</p>
<p><strong>职位要求：<br />
</strong>1. 计算机或相关理工科专业专科或以上学历，为人真诚正直；<br />
2. 熟悉Linux操作系统，熟悉Linux脚本编程；<br />
3. 熟悉Apache、nginx、Mysql等应用的配置与维护；<br />
4. 熟悉防火墙，交换机等网络设备的安装、配置；<br />
5. 2年以上相关工作经验，深入理解Linux系统的和部署，有系统调优经验者优先；<br />
6. 具备良好的沟通能力和强烈的责任心，热爱运维技术，有良好的文字表达能力和自学能力，有良好的团队合作意识。<br />
<strong>职位：</strong>PHP开发工程师<br />
<strong>招聘人数：</strong>3人<br />
<strong>职位描述：<br />
</strong>负责如下系统的设计，编码，测试，文档记录，开发优化维护等：<br />
1. passport中心<br />
2. 支付平台<br />
3. 论坛整合插件(discuz!)<br />
4. 在线活动项目<br />
5. 资产管理系统<br />
6. 广告统计系统<br />
7. 服务器监控系统<br />
8. 周边产品的<br />
<strong>职位要求：<br />
</strong>1. 精通PHP5开发（2年以上工作经验,有WebGame或者社区开发经验优先）<br />
2. 扎实的编程基础。代码构造清晰，易读。擅长代码和算法优化。<br />
3. 熟悉MySql数据库设计，了解Memcached优化。<br />
4. 了解PHP与FLASH（或者其它非浏览器客户端）的常用通信方式。（如AMFPHP）了解HTTP协议。<br />
5. 熟悉javascript,善用ajax等技术，熟悉Jason数据格式。<br />
6. 熟悉各浏览器的安全机制上的差异，能够解决兼容性问题，如：iframe,cookies,ajax。<br />
7. 熟悉PHP（APC之类）缓存技术，对异步机制下的状态维持、更新有一定的了解<br />
8. 熟悉SVN等版本控制开发环境。</p>
<p><strong>职位：</strong>数据库管理员/DBA<br />
<strong>招聘人数：</strong>1-2人<br />
<strong>职位描述：<br />
</strong>1. 负责公司游戏产品、支撑平台的数据库日常维护和监控；<br />
2. 负责数据库的更新和运营相关数据的统计分析。</p>
<p><strong>职位要求：<br />
</strong>1. 熟悉MySQL,Oracle的体系结构,复制,高可用,监控和备份机制；<br />
2. 具备较强的数据库故障解决能力；<br />
3. 至少熟悉Shell或Python脚本语言之一；<br />
4. 熟练使用PL/SQL,对大数据量下的数据处理有一定经验，有PL/SQL, SQL调优经验者优先；<br />
5. 熟悉数据仓库的ETL开发和数据建模优先；<br />
6. 能阅读各类英语文档。</p>
<p><strong>职位：</strong>BI&amp;UCD专员<br />
<strong>招聘人数：</strong>1<br />
<strong>职位描述：<br />
</strong>1. 辅助运营流程建设；<br />
2. 辅助运营数据统计、分析、挖掘；<br />
3. 参与实施BE/UCD管理及团队建设；<br />
4. 数据化衡量运营质量、提供决策参考依据；<br />
<strong>职位要求：<br />
</strong>1. 本科学历是必须条件，计算机及相关专业优先；<br />
2. 学习能力强，具有较强的沟通与领悟能力；<br />
3. 具备自我驱动能力，抗压能力强，服务意识及团队合作精神佳；</p>
<p>说明：招聘详情是我直接从我同事BLOG上复制过来的，只改了邮箱地址，别的都照搬。文中头部描述也是我的现状，我也不做安全了，回归到开发上来了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/%e5%b9%bf%e5%8f%91%e8%8b%b1%e9%9b%84%e5%b8%96-%e6%8b%9b%e8%81%98%e5%b9%bf%e5%91%8a%ef%bc%88dba%e3%80%81php%e5%bc%80%e5%8f%91%e3%80%81%e8%bf%90%e7%bb%b4%e5%b7%a5%e7%a8%8b%e5%b8%88%e3%80%81bi%e4%b8%93/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>apache RewriteMap MapSource自定义规则使用手记</title>
		<link>http://www.cnxct.com/apache-rewritemap-%e4%bd%bf%e7%94%a8%e6%89%8b%e8%ae%b0/</link>
		<comments>http://www.cnxct.com/apache-rewritemap-%e4%bd%bf%e7%94%a8%e6%89%8b%e8%ae%b0/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 02:59:37 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[MapSource]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[rewrite]]></category>
		<category><![CDATA[RewriteMap]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/?p=623</guid>
		<description><![CDATA[<a href="http://www.cnxct.com/wp-content/uploads/2010/10/The_Meteor_by_ready2freeze.jpg"><img src="http://www.cnxct.com/wp-content/uploads/2010/10/The_Meteor_by_ready2freeze-150x150.jpg" alt="" title="apache rewrite rewriteMap使用手记" width="150" height="150" class="alignleft sided inline"/></a>10.1期间，一位朋友问我一个apache的 Rewrite规则中一个高级语法RewriteMap的用法问题。其想要实现的是这个功能，有个多用户的blog，用户访问的时候，是用三级域名访问的。比如http://cfc4n1.blog.cnxct.com，http://cfc4n2.blog.cnxct.com这种三级域名。在服务器上，是对三级域名做泛解析。每个三级域名都生成了一个静态的html主页文件。由于用户数量较多，linux ext硬盘格式上同一目录文件太多，检索文件的速度会有折扣，遂将文件打散到不同的目录下。打散方式是以用户名【三级域名中的cfc4n1，cfc4n2等】的MD5值的每隔两位作为一个目录。]]></description>
			<content:encoded><![CDATA[<p>10.1期间，一位朋友问我一个apache的 Rewrite规则中一个高级语法RewriteMap的用法问题。其想要实现的是这个功能，有个多用户的blog，用户访问的时候，是用三级域名访问的。比如http://cfc4n1.blog.cnxct.com，http://cfc4n2.blog.cnxct.com这种三级域名。在服务器上，是对三级域名做泛解析。每个三级域名都生成了一个静态的html主页文件。由于用户数量较多，linux ext硬盘格式上同一目录文件太多，检索文件的速度会有折扣，遂将文件打散到不同的目录下。打散方式是以用户名【三级域名中的cfc4n1，cfc4n2等】的MD5值的每隔两位作为一个目录。MD5的默认长度是32位，每隔两位分一次目录的话，那就有16级目录。每级目录的目录名是2个字符，每个字符的有16种可能【0-9a-f】，那么每级目录的目录数为256个目录，16级的话就有4096个目录。每个目录存1000个文件的话，可以存放4096000个文件，这样做，即可以把文件均匀打散到各个小目录中，同时，每个目录下的文件数又不是很多。当用户访问的时候，取目录里的用户名，计算MD5hash，做字符分割，重写到对应的目录下的文件中，如果文件不存在，则重写到生成这个文件的动态页面中。</p>
<p>到apache手册里找了下RewriteMap的用法</p>
<blockquote><p>
RewriteMap MapName MapType:MapSource
</p></blockquote>
<p>遂顺手在.htaccess里这么写了</p>
<pre class="brush: plain; title: ; notranslate">
RewriteMap cfc prg:/var/www/1.php
RewriteRule ^([a-f0-9-]+)\.blog\.cnxct\.com ${cfc:$1} [L,PT]
</pre>
<p>然后访问一个三级域名试试。结果提示500 http 错误。到apache日志里看到如下</p>
<blockquote><p>
/var/www/.htaccess: RewriteMap not allowed here
</p></blockquote>
<p>搜了半天，不知道是什么错误，只好再次看手册，这时候，才发现rewritemap的作用域却是<strong>server config, virtual host</strong>，真汗了一下。自己没认真看手册。<br />
改到virtual host里之后，重启apache，结果，还是http 500。再到错误日志里查个究竟。里面记录的确实<strong>(13)Permission denied: mod_rewrite: could not start RewriteMap program /var/www/1.php</strong>。呃，权限，权限。。赶紧chmod了一下。再次启动，却提示404。。。 /0a/c1/&#8230;./&#8230;html那种MD5字符串切割之后的文件找不到。但目录里确实是存在的啊。又到日志里查看，原来却是/0a/c1/&#8230;../&#8230;html\r  文件无法找到了。为什么地址后面多个\r呢？打开MapSource的脚本文件，才看到里面PHP操作流的结束字符里是“\r\n”了，去掉\r 才可以。</p>
<p>总结一下使用APACHE URL REwrite的RewriteMap方法要注意以下几点：</p>
<ul>
<li>作用域-server config, virtual host，其他配置里无效。</li>
<li>自定义规则MapSource中流的结束符要跟操作系统符合，linux的要用“\n”，同时，切记在win平台编辑脚本传到linux上的时候，文件换行符要用linux格式的，不然，同样会出现问题。</li>
<li>要给apache赋予对脚本的读权限。</li>
<li>apache会在启动的时候，将自定义规则的脚本读取到内存中，之后，再次修改脚本时，不会立刻生效，需要重启 apache</li>
<li>apache 的error.log中会记录<strong>[warn] mod_rewrite: Running external rewrite maps without defining a RewriteLock is DANGEROUS!</strong>这样的错误日志，在apache2.conf【我的系统是ubuntu，其他linux在httpd.conf中】中添加RewriteLock /etc/apache2/script/cfc.lock来指定RewriteLock的文件位置。记得给apache对script目录下有读写权限。</li>
</ul>
<p>自定义脚本的代码格式如下：</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php
while($in = trim(fgets(STDIN)))
        fputs(STDOUT, getfile($in).&quot;\n&quot;);
function getfile($str)
{
//函数判断文件是否存在等逻辑
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/apache-rewritemap-%e4%bd%bf%e7%94%a8%e6%89%8b%e8%ae%b0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP中正则表达式对UNICODE字符码的匹配</title>
		<link>http://www.cnxct.com/php%e4%b8%ad%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e5%af%b9unicode%e5%ad%97%e7%ac%a6%e7%a0%81%e7%9a%84%e5%8c%b9%e9%85%8d/</link>
		<comments>http://www.cnxct.com/php%e4%b8%ad%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e5%af%b9unicode%e5%ad%97%e7%ac%a6%e7%a0%81%e7%9a%84%e5%8c%b9%e9%85%8d/#comments</comments>
		<pubDate>Sat, 03 Jul 2010 16:47:27 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[ascii]]></category>
		<category><![CDATA[PCRE]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[unicode]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/php%e4%b8%ad%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e5%af%b9unicode%e5%ad%97%e7%ac%a6%e7%a0%81%e7%9a%84%e5%8c%b9%e9%85%8d/</guid>
		<description><![CDATA[<a href="http://www.cnxct.com/wp-content/uploads/2010/07/lily_of_the_valley.jpg"><img src="http://www.cnxct.com/wp-content/uploads/2010/07/lily_of_the_valley-150x150.jpg" alt="" title="PHP正则表达式匹配UNICODE字符" width="150" height="150" class="alignleft sided inline" /></a>
我们在来分析一下这个网友写的正则表达式【[chr(128)-chr(256)]+】，正则表达式的PCRE引擎是如何解释这个正则的呢？首先，我们要知道，在正则表达式中，中括号【[]】表示字符组，字符组中除了连接符【-】只外，都不是元字符，也就是说，都是普通字符，当然，如果连字符出现在第一个，或者不是标识两个字符之间范围的，都是普通的字符横杠“-”罢了。这里的chr(128)只是标识ASCII码为128（确切的说，ASCII码只是0-127个，128到其他的，应该不叫ASCII码了。），但是在正则里，他仍然代表【c、h、r、(、1、2、8、)】（顿号不是，只是区分易读的）这八个字符罢了。这个正则里的连接字符，是哪些范围呢？很明显，这里的连接字符的范围是【)-c】，“)”ASCII码为0x29，也就是十进制的41；“c”的ASCII码为0x63，也就是十进制的99，那么，他这个连接字符的范围就是ASCII 41（chr(41)）到ASCII 99（chr(99)）之间的字符。]]></description>
			<content:encoded><![CDATA[<p>酷暑难耐，又在家宅一整天。天气热或许是借口，尽管不热，我也喜欢宅在家。晚上看新三国83集（插一句，最近世界杯很火，可是我不看世界杯。来鄙视我吧），一直看到10点半，突然觉得肚子痛，赶紧直奔厕所。如厕之后，觉得精神抖擞，容光焕发，年轻了二十多岁，打开QQ，看到N多条消息，其中有条是生命如蓝同学留的。打开一看，是PPC的链接，突然觉得我好久没登陆PPC了，想当年&#8230;&#8230;..算了，看链接吧。</p>
<p> 打开链接，看到标题是“请教PHP 一个正则匹配的问题”，又是正则表达式，好吧，看下，谁让俺比较喜欢鼓捣正则呢。下面开始正题。<br />
网友ainiaa的问题是</p>
<blockquote><p>
PHP代码如下</p>
<pre class="brush: php; title: ; notranslate">
$words = &quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSRUVWXYZ!@#$%^&amp;*()_+-=[]\\,./{}|&lt;&gt;?'\&quot;你好啊我们&quot;;
$otherStr=preg_replace(&quot;/[chr(128)-chr(256)]+/is&quot;,&quot; &quot;,$words);
echo 'otherStr:',$otherStr;
</pre>
<p>为什么打印的结果会是：<br />
otherStr: ! #$% &#038; {}| &#8216;”你好啊我们</p>
<p>麻烦问下其中正则表达式 /[chr(128)-chr(256)]+/is 代表什么意思？<br />
如果/[chr(128)-chr(256)]+/is 指的是ascii码在128到256的字符，为什么a-zA-Z这样的字符也被替换掉了，他们的ascii码是小于127的。<br />
最令人郁闷的是为什么ascii码同在0-127区间”#”,”$”,”%”,”&#038;”, “!”,” {“,”}”,”|”,” &#8216;”,”确没有被替换掉？？？？<br />
更令人感觉神奇的是 如果把正则表达式修改为”/[chr(128)-chr(256)]+/s”的话，输出的结果就变成了：  otherStr:  defg ijklmnopq stuvwxyz ! #$% &#038; {}| &#8216;”你好啊我们<br />
只是把正则表达式中的符号‘i’给去掉，结果缺失这样的。 完全的令我理解不了。<br />
不知各位 有何见解？？？？<br />
另附ascii 码 对照表<br />
（这个ASCII码表的图我就不贴了）
</p></blockquote>
<p>回帖中，有个网友说没解析chr(128)这些，并给出了新的解决方法。首先说下此网友回答的是正确的，先不评论他是否“知其然，且知其所以然”，这位网友没有给出错误的原因。</p>
<p><strong>CFC4N来回答一下这位网友：</strong></p>
<p>PHP的正则的preg_match函数用的是PCRE正则引擎，这位网友的代码中，PCRE引擎处理的正则表达式为【/[chr(128)-chr(256)]+/is】，后面的is是什么呢？<br />
在PHP的正则里，边界字符后面的叫模式修饰符。它会告诉引擎如何解析，处理正则。其中i修饰符表示不区分大小写。s表示“点号通配模式”，用来让正则里的元字符点号【.】可以匹配换行符，这个修饰符仅对点号【.】起作用。在这位网友的问题中，修饰符s并不起作用的。</p>
<p><strong>查找原因：</strong><br />
我们在来分析一下这个网友写的正则表达式【[chr(128)-chr(256)]+】，正则表达式的PCRE引擎是如何解释这个正则的呢？首先，我们要知道，在正则表达式中，中括号【[]】表示字符组，字符组中除了连接符【-】只外，都不是元字符，也就是说，都是普通字符，当然，如果连字符出现在第一个，或者不是标识两个字符之间范围的，都是普通的字符横杠“-”罢了。这里的chr(128)只是标识ASCII码为128（确切的说，ASCII码只是0-127个，128到其他的，应该不叫ASCII码了。），但是在正则里，他仍然代表【c、h、r、(、1、2、8、)】（顿号不是，只是区分易读的）这八个字符罢了。这个正则里的连接字符，是哪些范围呢？很明显，这里的连接字符的范围是【)-c】，“)”ASCII码为0&#215;29，也就是十进制的41；“c”的ASCII码为0&#215;63，也就是十进制的99，那么，他这个连接字符的范围就是ASCII 41（chr(41)）到ASCII 99（chr(99)）之间的字符。也就是说，这位网友的正则的范围是【[hr)-c(]】，就是chr(41)到chr(99)外加hr这两个字母和前面的“(”。<br />
网友第一次测试的时候，有修饰符i，意思就是说，不区分大小写，那么在chr(41)到chr(99)之间的字符，以及这些字符如果有大小写，则包括他们的大小写都符合匹配。都会被替换成空。其第二次测试的时候，去掉了修饰符i，进行了不区分大小写的匹配，由于其范围只到c，但突然，再除了小写字母的“h”、“r”，所以，测试结果会多出“defgijklmnopqstuvwxyz”。所以，他的结果出现了这些差别。<br />
<div id="attachment_544" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2010/07/reg1.jpg" rel="lightbox[543]"><img src="http://www.cnxct.com/wp-content/uploads/2010/07/reg1-150x150.jpg" alt="" title="PHP正则表达式匹配UNICODE字符" width="150" height="150" class="size-thumbnail wp-image-544" /></a><p class="wp-caption-text">PHP正则表达式匹配UNICODE字符</p></div><br />
网友的表达式等同于如下图所示<br />
<div id="attachment_545" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2010/07/reg2.jpg" rel="lightbox[543]"><img src="http://www.cnxct.com/wp-content/uploads/2010/07/reg2-150x150.jpg" alt="" title="PHP正则表达式匹配UNICODE字符" width="150" height="150" class="size-thumbnail wp-image-545" /></a><p class="wp-caption-text">PHP正则表达式匹配UNICODE字符</p></div></p>
<p><strong>解决办法：</strong><br />
错误的原因找出来了，那么，解决的办法呢？<br />
我们先来看看这位网友的需求，他的需求是将unicode（ASCII只是0-127位的，128之后的，应该叫UNICODE码）的chr(128)到chr(255)之间的字符匹配，替换为空罢了。正则表达式里，对十六进制的字符匹配的表示方式有两种，【\u】和【\x{}】，前者只能表示【\u】后面4位的十六进制数值，而后者【\x{}】则可以表示任意多的十六进制位数（写在大括号中）。<br />
那么，这个正则表达式该如何写？？？？</p>
<p>网友的目的是chr(128)到chr(255)，那么就是【[\u0080-\u00FF]】或者【[\x{0080}-\x{00FF}]】。<br />
其目的是匹配下图中的红框内字符<br />
<div id="attachment_546" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2010/07/mudi.jpg" rel="lightbox[543]"><img src="http://www.cnxct.com/wp-content/uploads/2010/07/mudi-150x150.jpg" alt="" title="UNICODE字符128到255字符集图" width="150" height="150" class="size-thumbnail wp-image-546" /></a><p class="wp-caption-text">UNICODE字符128到255字符集图</p></div><br />
提醒一下，PHP里正则匹配unicode字符时，需要使用u修饰符。<br />
根据网友需求，更改正则之后的PHP代码如下：</p>
<pre class="brush: php; title: ; notranslate">
$words = &quot;0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSRUVWXYZ!@#$%^&amp;*()_+-=[]\\,./{}|&lt;&gt;?'\&quot;你好啊我们&quot;;
$otherStr=preg_replace(&quot;//[\x{0080}-\x{00FF}]+/iu&quot;,&quot; &quot;,$words);
echo 'otherStr:',$otherStr;
</pre>
<p>其运行结果是仍然输出那段字符串，为什么呢？因为哪些字符串都不在chr(128)到chr(255)的范围之内。<br />
（测试时，注意文件编码为UTF-8）<br />
以上为鄙人愚见，欢迎批评指正。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/php%e4%b8%ad%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e5%af%b9unicode%e5%ad%97%e7%ac%a6%e7%a0%81%e7%9a%84%e5%8c%b9%e9%85%8d/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>PHP正则表达式的效率：回溯与固化分组</title>
		<link>http://www.cnxct.com/php%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e7%9a%84%e6%95%88%e7%8e%87%ef%bc%9a%e5%9b%9e%e6%ba%af%e4%b8%8e%e5%9b%ba%e5%8c%96%e5%88%86%e7%bb%84/</link>
		<comments>http://www.cnxct.com/php%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e7%9a%84%e6%95%88%e7%8e%87%ef%bc%9a%e5%9b%9e%e6%ba%af%e4%b8%8e%e5%9b%ba%e5%8c%96%e5%88%86%e7%bb%84/#comments</comments>
		<pubDate>Mon, 21 Jun 2010 07:39:52 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[回溯]]></category>
		<category><![CDATA[固化分组]]></category>
		<category><![CDATA[效率]]></category>
		<category><![CDATA[正则表达式]]></category>
		<category><![CDATA[环视]]></category>
		<category><![CDATA[贪婪]]></category>
		<category><![CDATA[零宽断言]]></category>

		<guid isPermaLink="false">http://www.cnxct.com/php%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e7%9a%84%e6%95%88%e7%8e%87%ef%bc%9a%e5%9b%9e%e6%ba%af%e4%b8%8e%e5%9b%ba%e5%8c%96%e5%88%86%e7%bb%84/</guid>
		<description><![CDATA[<a href="http://www.cnxct.com/wp-content/uploads/2010/06/hua.jpg"><img src="http://www.cnxct.com/wp-content/uploads/2010/06/hua-150x150.jpg" alt="" title="PHP正则表达式的回溯与固化分组" width="150" height="150" class="alignleft sided inline" /></a>上文中，我们聊到了一点关于PHP中（NFA PCRE）正则表达式匹配优先量词，忽略优先量词的匹配原理了。那么上文留下的问题，您的答案是什么呢？
对于第一种贪婪匹配的匹配规则，回溯的9次是正则【</script>】对字符串“</script>”匹配时，构成的回溯，回溯的次数，恰好是字符串的长度。
第二种非攀谈匹配规则，回溯5次，是正则【.+?】对字符串“123456”匹配时构成的回溯。回溯的次数，为字符串长度减去最小次数。也就是6-1=5次。如果正则表达式为【.*?】那么，回溯次数就是6次了。
第三种正则是零宽断言，或者叫环视。（暂且不说。）
]]></description>
			<content:encoded><![CDATA[<p><div id="attachment_498" class="wp-caption aligncenter" style="width: 160px"><a href="http://www.cnxct.com/wp-content/uploads/2010/06/hua.jpg" rel="lightbox[491]"><img src="http://www.cnxct.com/wp-content/uploads/2010/06/hua-150x150.jpg" alt="" title="PHP正则表达式的回溯与固化分组" width="150" height="150" class="size-thumbnail wp-image-498" /></a><p class="wp-caption-text">PHP正则表达式的回溯与固化分组</p></div><br />
上文中，我们聊到了一点关于PHP中（NFA PCRE）正则表达式匹配优先量词，忽略优先量词的匹配原理了。那么上文留下的问题，您的答案是什么呢？<br />
先来看下问题。</p>
<blockquote><p>
字符串</p>
<pre class="brush: php; title: ; notranslate">
$str = '&lt;script&gt;123456&lt;/script&gt;';
</pre>
<p>正则表达式为</p>
<pre class="brush: php; title: ; notranslate">
$strRegex1 = '%&lt;script&gt;.+&lt;\/script&gt;%';
$strRegex2 = '%&lt;script&gt;.+?&lt;\/script&gt;%';
$strRegex3 = '%&lt;script&gt;(?:(?!&lt;\/script&gt;).)+&lt;\/script&gt;%';
</pre>
<p>这三个正则，分别会造成几次回溯呢？？
</p></blockquote>
<p>答案：</p>
<pre class="brush: php; title: ; notranslate">
$strRegex1 = '%&lt;script&gt;.+&lt;\/script&gt;%';    //9次，记得区别转义符号。
$strRegex2 = '%&lt;script&gt;.+?&lt;\/script&gt;%';  //5次
$strRegex3 = '%&lt;script&gt;(?:(?!&lt;\/script&gt;).)+&lt;\/script&gt;%';  //7次
</pre>
<p>对于第一种贪婪匹配的匹配规则，回溯的9次是正则【</script>】对字符串“</script>”匹配时，构成的回溯，回溯的次数，恰好是字符串的长度。<br />
第二种非贪婪匹配规则，回溯5次，是正则【.+?】对字符串“123456”匹配时构成的回溯。回溯的次数，为字符串长度减去最小次数。也就是6-1=5次。如果正则表达式为【.*?】那么，回溯次数就是6次了。<br />
第三种正则是零宽断言，或者叫环视。（暂且不说。）<br />
在NFA正则引擎中，回溯是他的灵魂，所以，不管是贪婪，非贪婪，环视等写法中肯定会有回溯的出现的，这个我们无法避免（用词不太准确），但是，我们可以减少回溯的次数，或者保护其中一部分匹配的规则不进行回溯。</p>
<p>对于<a href="http://www.cnxct.com/%e5%b0%8f%e8%ae%ae%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e6%95%88%e7%8e%87%ef%bc%9a%e8%b4%aa%e5%a9%aa%e3%80%81%e9%9d%9e%e8%b4%aa%e5%a9%aa%e4%b8%8e%e5%9b%9e%e6%ba%af/">上篇BLOG</a>上提到的鸟哥谈到一个非贪婪引起的大量回溯问题，大家可以知道，回溯，确实是浪费资源的罪魁祸首，那么，我们能否不让其回溯呢？<br />
答案是肯定的，NFA引擎中，有个概念，叫固化分组。引用一下书上的概念</p>
<blockquote><p>
具体来说，使用「(?>…)」的匹配与正常的匹配并无差别，但是如果匹配进行到此结构之后（也就是，进行到闭括号之后），那么此结构体中的所有备用状态都会被放弃。也就是说，在固化分组匹配结束时，它已经匹配的文本已经固化为一个单元，只能作为整体而保留或放弃。括号内的子表达式中未尝试过的备用状态都不复存在了，所以回溯永远也不能选择其中的状态（至少是，当此结构匹配完成时，“锁定（locked in）”在其中的状态）。
</p></blockquote>
<p>那么，固化分组到底有什么用处呢？我们来举个例子。（找不到合适的例子，俺只好借用一下书上的例子了）<br />
比如要处理一批数据，原来格式为123.456，后来因为浮点数显示问题，部分数据格式变为123.456000000789这种，，要求做到只保留小数点后面2-3位，但是，最后一位不能为0，这个正则如何写呢？（下面直接考虑小数点后面的数字），写出正则之后，我们还要用这个正则去匹配数据，把原来的数据替换成匹配的结果。<br />
首先，我们可以立刻写出这样的正则【\.\d\d[1-9]?\d*】，PHP代码为</p>
<pre class="brush: php; title: ; notranslate">
$str = preg_replace('\.(\d\d[1-9]?)\d*','\\1',$str);  //匹配结果的group1进行反向引用
</pre>
<p>很明显，这种写法，对于部分数据格式为123.456的这种格式，白白的处理了一遍，为了提高效率，我们还要对这个正则进行处理。从123.456这个字符串跟其他的比较一下，我们发现，是疑问123.456这个数据后面没数字了，所以，白白处理一遍。那好办，我们对这个正则改造一下，把后面的量词*改成+，这样对于123.45 小数点后面1，2位数字的，不会去白白处理，而且，对三位以上数字的，处理正常。其PHP代码为</p>
<pre class="brush: php; title: ; notranslate">
$str = preg_replace('\.(\d\d[1-9]?)\d+','\\1',$str);
</pre>
<p>好了，这个正则真的没问题吗？？确定吗？上篇博文，我们了解了匹配原理，那么，我们也分析一下这个正则的匹配过程吧。<br />
字符串"123.456",正则表达式为【\.(\d\d[1-9]?)\d+】，我们来看下<br />
首先（小数点前123不说了），【\.】匹配"."，匹配成功，把控制权给下一个【\d】，【\d】匹配“4”成功，把控制权给第二个【\d】，这个【\d】匹配“5”成功，然后，把控制权给了【[1-9]?】，由于量词是【?】，正则表达式遵循“量词优先匹配”，而且，此处是【?】，还会留下一个回溯点。然后匹配"6"成功，然后把控制权给【\d+】，【\d+】发现后面没字符了，最遵循“后进先出”规则，回到上一个回溯点，进行匹配，这时，【[1-9]?】会交还出其匹配的字符“6”，【[1-9]?】匹配“6”成功。匹配完成了。大家发现【(\d\d[1-9]?)】匹配的结果确是"45",并不是我们想要的“456”，“6”被【\d+】匹配去了。那么，我们该如何办呢？ 能否让【[1-9]?】匹配一旦成功，不进行回溯呢？这就用到了我们上面说的"固化分组", PHP（preg_replace函数）中使用的正则引擎支持固化分组，我们根据固化分组的写法，可以把代码改成如下方式</p>
<pre class="brush: php; title: ; notranslate">
$str = preg_replace('\.(\d\d(?&gt;[1-9]?))\d+','\\1',$str);
</pre>
<p>改成这样的话，那字符串“123.456“是不符合要求，不会被匹配的。那我们就可以实现我们的要求了。</p>
<p>从上面的例子中，知道了固化分组的作用，那么对于鸟哥BLOG上写的那个非贪婪的回溯问题，我们能否也对其改造，使得其不回溯呢？<br />
先看下鸟哥给的答案</p>
<blockquote>
<pre class="brush: plain; title: ; notranslate">/&lt;script&gt;[^&lt;]*&lt;\/script&gt;/is
</pre>
</blockquote>
<p>鸟哥写的很精悍。排除“<”之外的所有字符都符合，而且，中间部分不回溯，效率高。可是，如果中间有字符“<“的话（如下代码）</p>
<pre class="brush: plain; title: ; notranslate">
&lt;script&gt;
if a &lt; b
&lt;/script&gt;
</pre>
<p>那鸟哥的这个正则就不能匹配，就不能实现我们想要的功能了。<br />
那我们可以根据 固化分组、环视(零宽断言)来实现这个要求，最后，CFC4N给出的正则以及PHP代码事例如下</p>
<pre class="brush: php; title: ; notranslate">
$reg = '%&lt;script&gt;(?&gt;[^&lt;]*)(?&gt;(?!&lt;/?script&gt;)&lt;[^&lt;]*)*&lt;/script&gt;%is';
$str = str_pad(&quot;&lt;script&gt;&quot;, 111111, &quot;*&quot;);    //字符长度大于PHP回溯限制的100000
$str .= 'if a &lt; b ; if b &gt; c;&lt;/script&gt;';    //随便加几个包含 &lt; &gt; 的测试字符
$ret = preg_replace($reg, &quot;OK&quot;, $str);
print_r($ret);                              //打印结果 OK，证明匹配正确
var_dump(preg_last_error());                //上一次匹配错误。其输出为 int(0)
</pre>
<p>嗨，同学，你看明白了吗？</p>
<p>以上为小菜CFC4N的愚文，如有错误，欢迎指出。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/php%e6%ad%a3%e5%88%99%e8%a1%a8%e8%be%be%e5%bc%8f%e7%9a%84%e6%95%88%e7%8e%87%ef%bc%9a%e5%9b%9e%e6%ba%af%e4%b8%8e%e5%9b%ba%e5%8c%96%e5%88%86%e7%bb%84/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>在PHP中执行系统外部命令</title>
		<link>http://www.cnxct.com/%e5%9c%a8php%e4%b8%ad%e6%89%a7%e8%a1%8c%e7%b3%bb%e7%bb%9f%e5%a4%96%e9%83%a8%e5%91%bd%e4%bb%a4/</link>
		<comments>http://www.cnxct.com/%e5%9c%a8php%e4%b8%ad%e6%89%a7%e8%a1%8c%e7%b3%bb%e7%bb%9f%e5%a4%96%e9%83%a8%e5%91%bd%e4%bb%a4/#comments</comments>
		<pubDate>Mon, 12 Jun 2006 00:38:21 +0000</pubDate>
		<dc:creator>CFC4N</dc:creator>
				<category><![CDATA[所谓技术]]></category>
		<category><![CDATA[passthru]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[webshell]]></category>
		<category><![CDATA[安全]]></category>

		<guid isPermaLink="false">http://test.cnxct.com/?p=17</guid>
		<description><![CDATA[HP作为一种服务器端的脚本语言，象编写简单，或者是复杂的动态网页这样的任务，它完全能够胜任。但事情不总是如此，有时为了实现某个功能，必须借助于操作系统的外部程序（或者称之为命令），这样可以做到事半功倍。
　　那么，是否可以在PHP脚本中调用外部命令呢？如果能，如何去做呢？有些什么方面的顾虑呢？相信你看了本文后，肯定能够回答这些问题了。

　　是否可以？
　　答案是肯定的。PHP和其它的程序设计语言一样，完全可以在程序内调用外部命令，并且是很简单的：只要用一个或几个函数即可。]]></description>
			<content:encoded><![CDATA[<p>PHP作为一种服务器端的脚本语言，象编写简单，或者是复杂的动态网页这样的任务，它完全能够胜任。但事情不总是如此，有时为了实现某个功能，必须借助于操作系统的外部程序（或者称之为命令），这样可以做到事半功倍。</p>
<p>那么，是否可以在PHP脚本中调用外部命令呢？如果能，如何去做呢？有些什么方面的顾虑呢？相信你看了本文后，肯定能够回答这些问题了。</p>
<p><strong>是否可以？</strong></p>
<p>答案是肯定的。PHP和其它的程序设计语言一样，完全可以在程序内调用外部命令，并且是很简单的：只要用一个或几个函数即可。</p>
<p><strong>前提条件</strong></p>
<p>由于PHP基本是用于WEB程序开发的，所以安全性成了人们考虑的一个重要方面。于是PHP的设计者们给PHP加了一个门：安全模式。如果运行在安全模式下，那么PHP脚本中将受到如下四个方面的限制：</p>
<p><strong>执行外部命令</strong></p>
<p>在打开文件时有些限制</p>
<p>连接MySQL数据库</p>
<p>基于HTTP的认证</p>
<p>在安全模式下，只有在特定目录中的外部程序才可以被执行，对其它程序的调用将被拒绝。这个目录可以在php.ini文件中用safe_mode_exec_dir指令，或在编译PHP是加上&#8211;with-exec-dir选项来指定，默认是/usr/local/php/bin。</p>
<p>如果你调用一个应该可以输出结果的外部命令（意思是PHP脚本没有错误），得到的却是一片空白，那么很可能你的网管已经把PHP运行在安全模式下了。</p>
<p>如何做？</p>
<p>在PHP中调用外部命令，可以用如下三种方法来实现：</p>
<p>1） 用PHP提供的专门函数</p>
<p>PHP提供共了3个专门的执行外部命令的函数：<strong>system()，exec()，passthru()</strong>。</p>
<p><strong>system()</strong></p>
<p>原型：<span style="text-decoration: underline;">string system (string command [, int return_var])</span></p>
<p>system()函数很其它语言中的差不多，它执行给定的命令，输出和返回结果。第二个参数是可选的，用来得到命令执行后的状态码。</p>
<p>例子：</p>
<blockquote></blockquote>
<p><strong>exec()</strong></p>
<p>原型：<span style="text-decoration: underline;">string exec (string command [, string array [, int return_var]])</span></p>
<p>exec()函数与system()类似，也执行给定的命令，但不输出结果，而是返回结果的最后一行。虽然它只返回命令结果的最后一行，但用第二个参数array可以得到完整的结果，方法是把结果逐行追加到array的结尾处。所以如果array不是空的，在调用之前最好用unset()最它清掉。只有指定了第二个参数时，才可以用第三个参数，用来取得命令执行的状态码。</p>
<p>例子：</p>
<pre class="brush: php; title: ; notranslate">&lt;?

exec(&quot;/bin/ls -l&quot;);

exec(&quot;/bin/ls -l&quot;, $res);

#$res是一个数据，每个元素代表结果的一行

exec(&quot;/bin/ls -l&quot;, $res, $rc);

#$rc的值是命令/bin/ls -l的状态码。成功的情况下通常是0

?&gt;</pre>
<p><strong> passthru()</strong></p>
<p>原型：<span style="text-decoration: underline;">void passthru (string command [, int return_var])</span></p>
<p>passthru()只调用命令，不返回任何结果，但把命令的运行结果原样地直接输出到标准输出设备上。所以passthru()函数经常用来调用象pbmplus（Unix下的一个处理图片的工具，输出二进制的原始图片的流）这样的程序。同样它也可以得到命令执行的状态码。</p>
<p>例子：</p>
<pre class="brush: php; title: ; notranslate">&lt;?

header(&quot;Content-type: image/gif&quot;);

passthru(&quot;./ppmtogif hunte.ppm&quot;);

?&gt;</pre>
<p>2） 用popen()函数打开进程</p>
<p>上面的方法只能简单地执行命令，却不能与命令交互。但有些时候必须向命令输入一些东西，如在增加Linux的系统用户时，要调用su来把当前用户换到root才行，而su命令必须要在命令行上输入root的密码。这种情况下，用上面提到的方法显然是不行的。</p>
<p>popen()函数打开一个进程管道来执行给定的命令，返回一个文件句柄。既然返回的是一个文件句柄，那么就可以对它读和写了。在PHP3中，对这种句柄只能做单一的操作模式，要么写，要么读；从PHP4开始，可以同时读和写了。除非这个句柄是以一种模式（读或写）打开的，否则必须调用pclose()函数来关闭它。</p>
<p>例子1：</p>
<pre class="brush: php; title: ; notranslate">&lt;?

$fp=popen(&quot;/bin/ls -l&quot;, &quot;r&quot;);

?&gt;</pre>
<p>例子2（本例来自PHP中国联盟网站http://www.phpx.com/show.php?d=col&amp;i=51）：</p>
<pre class="brush: php; title: ; notranslate">&lt;?

/* PHP中如何增加一个系统用户

下面是一段例程，增加一个名字为james的用户,

root密码是 verygood。仅供参考

*/

$sucommand = &quot;su --login root --command&quot;;

$useradd = &quot;useradd &quot;;

$rootpasswd = &quot;verygood&quot;;

$user = &quot;james&quot;;

$user_add = sprintf(&quot;%s &quot;%s %s&quot;&quot;,$sucommand,$useradd,$user);

$fp = @popen($user_add,&quot;w&quot;);

@fputs($fp,$rootpasswd);

@pclose($fp);

?&gt;</pre>
<p>3） 用反撇号（`，也就是键盘上ESC键下面的那个，和~在同一个上面）</p>
<p>这个方法以前没有归入PHP的文档，是作为一个秘技存在的。方法很简单，用两个反撇号把要执行的命令括起来作为一个表达式，这个表达式的值就是命令执行的结果。如：</p>
<pre class="brush: php; title: ; notranslate">&lt;?php

$res=`/bin/ls -l`;

echo '&lt;b&gt;&lt;pre&gt;'.$res.'&lt;/pre&gt;&lt;/b&gt;';

?&gt;</pre>
<p>这个脚本的输出就象：</p>
<p>hunte.gif<br />
hunte.ppm<br />
jpg.htm<br />
jpg.jpg<br />
passthru.php</p>
<p>要考虑些什么？<br />
要考虑两个问题：安全性和超时。</p>
<p>先看安全性。比如，你有一家小型的网上商店，所以可以出售的产品列表放在一个文件中。你编写了一个有表单的HTML文件，让你的用户输入他们的EMAIL地址，然后把这个产品列表发给他们。假设你没有使用PHP的mail()函数（或者从未听说过），你就调用Linux/Unix系统的mail程序来发送这个文件。程序就象这样：</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

system(&quot;mail $to &lt; products.txt&quot;);

echo &quot;我们的产品目录已经发送到你的信箱：$to&quot;;

?&gt;</pre>
<p>用这段代码，一般的用户不会产生什么危险，但实际上存在着非常大的安全漏洞。如果有个恶意的用户输入了这样一个EMAIL地址：</p>
<p><span style="text-decoration: underline;"><strong> &#8216;&#8211;bla ; mail someone@domain.com &lt; /etc/passwd ;&#8217;</strong></span></p>
<p>那么这条命令最终变成：</p>
<p><strong><span style="text-decoration: underline;">&#8216;mail &#8211;bla ; mail someone@domain.com &lt; /etc/passwd ; &lt; products.txt&#8217;</span></strong></p>
<p>我相信，无论哪个网络管理人员见到这样的命令，都会吓出一身冷汗来。</p>
<p>幸好，PHP为我们提供了两个函数：<strong>EscapeShellCmd()</strong>和<strong>EscapeShellArg()</strong>。<br />
函数EscapeShellCmd把一个字符串中所有可能瞒过Shell而去执行另外一个命令的字符转义。这些字符在Shell中是有特殊含义的，象分号（），重定向（&gt;）和从文件读入（&lt;）等。函数EscapeShellArg是用来处理命令的参数的。它在给定的字符串两边加上单引号，并把字符串中的单引号转义，这样这个字符串就可以安全地作为命令的参数。</p>
<p>再来看看超时问题。如果要执行的命令要花费很长的时间，那么应该把这个命令放到系统的后台去运行。但在默认情况下，象system()等函数要等到这个命令运行完才返回（实际上是要等命令的输出结果），这肯定会引起PHP脚本的超时。解决的办法是把命令的输出重定向到另外一个文件或流中，如：</p>
<pre class="brush: php; title: ; notranslate">&lt;?php
system(&quot;/usr/local/bin/order_proc &gt; /tmp/null &amp;&quot;);
?&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cnxct.com/%e5%9c%a8php%e4%b8%ad%e6%89%a7%e8%a1%8c%e7%b3%bb%e7%bb%9f%e5%a4%96%e9%83%a8%e5%91%bd%e4%bb%a4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

