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

<channel>
	<title>五四陈科学院-坚信科学，分享技术 &#187; php</title>
	<atom:link href="http://www.54chen.com/category/php-tech/feed" rel="self" type="application/rss+xml" />
	<link>http://www.54chen.com</link>
	<description>PHP、JAVA、缓存、架构、经验、分享</description>
	<lastBuildDate>Sat, 11 Feb 2012 17:09:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>年终攻击hashDos-哈希表多碰撞实现拒绝服务-破解办法</title>
		<link>http://www.54chen.com/php-tech/hashdos.html</link>
		<comments>http://www.54chen.com/php-tech/hashdos.html#comments</comments>
		<pubDate>Fri, 30 Dec 2011 09:24:33 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[hashdos]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/hashdos.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>起因： Wed, 28 Dec 2011 22:28:16 GMT apache tomcat公布了一个安全漏洞。 http://mail-archives.apache.org/mod_mbox/www-announce/201112.mbox/%3C4EFB9800.5010106@apache.org%3E 漏洞原理： 依靠相应语言的hashtable/hashmap实现过程（request多为此结构），当不同的key存入时如果hash值相等则以链表方式连接在前面。此漏洞利用碰撞相同的hash值得到一个长链表，重新get时，map的计算过程会将时间复杂度巨增，原来一个简单的过程将变成一个很费cpu的过程。 影响到的： 最快时间tomcat公布了解决办法。 php进行了升级。 ms也发了公告http://technet.microsoft.com/en-us/security/bulletin/ms11-100。 解决办法： tomcat 临时办法： 默认大小2097152，当maxPostSize=0时，不限制；maxPostSize=20971520时，为20M，改为一个小于10k的值，所有版本可用，会影响用户。 持久办法： 用新的版本，maxParameterCount默认值1000。 nginx 临时办法： 默认的最大请求body大小为8m，修改设置client_max_body_size=10k；此招为各种情况下万金油，会影响用户。 持久办法： 暂无，应该很快会有max_request_count的参数。 php 持久办法： php升级到5.3.9，5.2需要打patch。详细见：http://www.laruence.com/2011/12/30/2440.html 后记 54chen人肉构造打到php，php立马100%，转到java（resin+spring+rose），轻松化解，没有反应。<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><strong>起因：</strong><br />
Wed, 28 Dec 2011 22:28:16 GMT apache tomcat公布了一个安全漏洞。</p>
<p>http://mail-archives.apache.org/mod_mbox/www-announce/201112.mbox/%3C4EFB9800.5010106@apache.org%3E</p>
<p><strong>漏洞原理：</strong><br />
依靠相应语言的hashtable/hashmap实现过程（request多为此结构），当不同的key存入时如果hash值相等则以链表方式连接在前面。此漏洞利用碰撞相同的hash值得到一个长链表，重新get时，map的计算过程会将时间复杂度巨增，原来一个简单的过程将变成一个很费cpu的过程。</p>
<p><strong>影响到的：</strong><br />
最快时间tomcat公布了解决办法。<br />
php进行了升级。<br />
ms也发了公告http://technet.microsoft.com/en-us/security/bulletin/ms11-100。</p>
<p><strong>解决办法：</strong><br />
<strong>tomcat</strong><br />
<strong>临时办法：</strong><br />
默认大小2097152，当maxPostSize=0时，不限制；maxPostSize=20971520时，为20M，改为一个小于10k的值，<strong>所有版本可用</strong>，会影响用户。<br />
<strong>持久办法：</strong><br />
用新的版本，maxParameterCount默认值1000。<br />
<strong>nginx</strong><br />
<strong>临时办法：</strong><br />
默认的最大请求body大小为8m，修改设置client_max_body_size=10k；此招为各种情况下万金油，会影响用户。<br />
<strong>持久办法：</strong><br />
暂无，应该很快会有max_request_count的参数。<br />
<strong>php</strong><br />
<strong>持久办法：</strong><br />
php升级到5.3.9，5.2需要打patch。详细见：http://www.laruence.com/2011/12/30/2440.html</p>
<p><strong>后记</strong><br />
54chen人肉构造打到php，php立马100%，转到java（resin+spring+rose），轻松化解，没有反应。</p>
<p><img src="http://img05.taobaocdn.com/bao/uploaded/i5/T1.RRAXjVDXXX7OsE8_070026.jpg" alt="hashDos,important" /></p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/hashdos.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>quercus记录：php使用连接池访问数据库</title>
		<link>http://www.54chen.com/php-tech/quercus-php-connect-pool.html</link>
		<comments>http://www.54chen.com/php-tech/quercus-php-connect-pool.html#comments</comments>
		<pubDate>Fri, 04 Nov 2011 02:29:30 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[quercus]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/quercus-php-connect-pool.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>上周记录了如何用quercus建立混合型项目。 http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html 这里来说说与数据库的访问，使用jndi得到连接池的好处。 JNDI (Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口，JNDI提供统一的客户端API，通过不同的访问提供者接口JNDI SPI的实现，由管理者将JNDI API映射为特定的命名服务和目录系统，使得Java应用程序可以和这些命名服务和目录服务之间进行交互。 正题 在quercus中可以随意使用mysql_connect与mysql_pconnect两个方法来连接数据库。 当在web.xml定义得有database相关的消息时，mysql_connect与mysql_pconnect都会自动忽略里面的参数设置，直接使用web.xml的定义。 添加jndi设置： vim WEB-INF/web.xml &#60;?xml&#160;version="1.0"&#160;encoding="utf-8"?&#62;&#160;&#160; &#60;web-app&#160;&#160;xmlns="http://caucho.com/ns/resin"&#62;&#160;&#160; &#160;&#160;&#60;description&#62;truth&#160;application&#60;/description&#62;&#160;&#160; &#160;&#160;&#60;database&#160;jndi-name="jdbc/mysql"&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;driver&#160;type="com.mysql.jdbc.Driver"&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;url&#62;jdbc:mysql://192.168.1.5:3306/truth?useUnicode=true&#38;amp;characterEncoding=utf-8&#60;/url&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;user&#62;你的用户名&#60;/user&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;password&#62;你的密码&#60;/password&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#60;init-param&#160;useUnicode="true"/&#62;&#160;&#60;!--实践证明这个是不管用的，因为quercus写土了，全用的latin1字符集，后面再说--&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/driver&#62;&#160;&#160; &#160;&#160;&#60;/database&#62;&#160;&#160; 使用的是resin4，需要继续在web.xml的servlet段里增加： &#60;init-param&#62;&#160;&#160; &#160;&#160;&#60;param-name&#62;database&#60;/param-name&#62;&#160;&#160; &#160;&#160;&#60;param-value&#62;jdbc/mysql&#60;/param-value&#62;&#160;&#160; &#60;/init-param&#62;&#160;&#160; 这里注意，param-value与上面的jndi-name对应，mysql_connnect函数在web.xml里有这个init-param的定义的时候，将使用对应的jndi的设置。由此可得到连接池的好处。 上面的例子只使用了jdbc的基础驱动，如果向下面的配置，自然就得到了pool: 例子1: &#60;database&#62;&#160;&#160; &#160;&#160;&#60;jndi-name&#62;jdbc/mysql&#60;/jndi-name&#62;&#160;&#160; &#160;&#160;&#60;driver&#62;&#160;&#60;type&#62;com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource&#60;/type&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;url&#62;jdbc:mysql://localhost:3306/dbname&#60;/url&#62;&#160;&#160; &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://www.caucho.com/wp-content/themes/caucho/images/caucho-logo.png" alt="java php quercus" /><br />
上周记录了如何用quercus建立混合型项目。<br />
<a href="http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html">http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html</a><br />
这里来说说与数据库的访问，使用jndi得到连接池的好处。</p>
<p><strong>JNDI</strong><br />
(Java Naming and Directory Interface)是SUN公司提供的一种标准的Java命名系统接口，JNDI提供统一的客户端API，通过不同的访问提供者接口JNDI SPI的实现，由管理者将JNDI API映射为特定的命名服务和目录系统，使得Java应用程序可以和这些命名服务和目录服务之间进行交互。</p>
<p><strong>正题</strong><br />
在quercus中可以随意使用mysql_connect与mysql_pconnect两个方法来连接数据库。<br />
当在web.xml定义得有database相关的消息时，mysql_connect与mysql_pconnect都会自动忽略里面的参数设置，直接使用web.xml的定义。</p>
<p><strong>添加jndi设置：</strong><br />
vim WEB-INF/web.xml</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"utf-8"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span><span class="tag">&lt;</span><span class="tag-name">web-app</span><span>&nbsp;&nbsp;</span><span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://caucho.com/ns/resin"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">description</span><span class="tag">&gt;</span><span>truth&nbsp;application</span><span class="tag">&lt;/</span><span class="tag-name">description</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">database</span><span>&nbsp;</span><span class="attribute">jndi-name</span><span>=</span><span class="attribute-value">"jdbc/mysql"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">driver</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"com.mysql.jdbc.Driver"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>jdbc:mysql://192.168.1.5:3306/truth?</span><span class="attribute">useUnicode</span><span>=</span><span class="attribute-value">true</span><span>&amp;amp;</span><span class="attribute">characterEncoding</span><span>=</span><span class="attribute-value">utf</span><span>-8</span><span class="tag">&lt;/</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>你的用户名</span><span class="tag">&lt;/</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>你的密码</span><span class="tag">&lt;/</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">init-param</span><span>&nbsp;</span><span class="attribute">useUnicode</span><span>=</span><span class="attribute-value">"true"</span><span class="tag">/&gt;</span><span>&nbsp;</span><span class="comments">&lt;!--实践证明这个是不管用的，因为quercus写土了，全用的latin1字符集，后面再说--&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>使用的是resin4，需要继续在web.xml的servlet段里增加：</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>database</span><span class="tag">&lt;/</span><span class="tag-name">param-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>jdbc/mysql</span><span class="tag">&lt;/</span><span class="tag-name">param-value</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span><span class="tag">&lt;/</span><span class="tag-name">init-param</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>这里注意，param-value与上面的jndi-name对应，mysql_connnect函数在web.xml里有这个init-param的定义的时候，将使用对应的jndi的设置。由此可得到连接池的好处。</p>
<p>上面的例子只使用了jdbc的基础驱动，如果向下面的配置，自然就得到了pool:<br />
<strong>例子1:</strong></p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>jdbc/mysql</span><span class="tag">&lt;/</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">type</span><span class="tag">&gt;</span><span>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</span><span class="tag">&lt;/</span><span class="tag-name">type</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>jdbc:mysql://localhost:3306/dbname</span><span class="tag">&lt;/</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>username</span><span class="tag">&lt;/</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>password</span><span class="tag">&lt;/</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">init-param</span><span>&nbsp;</span><span class="attribute">useUnicode</span><span>=</span><span class="attribute-value">"true"</span><span class="tag">/&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p><strong>例子2:</strong></p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>jdbc/mysql</span><span class="tag">&lt;/</span><span class="tag-name">jndi-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">driver</span><span>&nbsp;</span><span class="attribute">type</span><span>=</span><span class="attribute-value">"org.gjt.mm.mysql.Driver"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>jdbc:mysql://localhost:3306/test</span><span class="tag">&lt;/</span><span class="tag-name">url</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">user</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">user</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">password</span><span class="tag">&gt;</span><span class="tag">&lt;/</span><span class="tag-name">password</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">driver</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">prepared-statement-cache-size</span><span class="tag">&gt;</span><span>8</span><span class="tag">&lt;/</span><span class="tag-name">prepared-statement-cache-size</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">max-connections</span><span class="tag">&gt;</span><span>20</span><span class="tag">&lt;/</span><span class="tag-name">max-connections</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">max-idle-time</span><span class="tag">&gt;</span><span>30s</span><span class="tag">&lt;/</span><span class="tag-name">max-idle-time</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">database</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>这些简单的配置，都可以让php轻松跑在连接池上。<br />
<strong>问题所在：</strong><br />
quercus写土了，没有在用户设置为unicode的时候来解析用户的输入，到处是hard code的latin1。（本来在GAE里使用这东西的人挺多的，可惜吧，AGE被盾了，然后quercus反馈latin1问题的人也不多，唉。）</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-j" start="1">
<li class="alt"><span><span>com.caucho.quercus.lib.db.JdbcConnectionResource:&nbsp;</span><span class="number">94</span><span>&nbsp;&nbsp;</span><span class="number">348</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>com.caucho.quercus.lib.db.Mysqli:<span class="number">229</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>上面三处修改为utf8即可。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/quercus-php-connect-pool.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>quercus记录：php和java的混合型项目建立手记</title>
		<link>http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html</link>
		<comments>http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html#comments</comments>
		<pubDate>Tue, 25 Oct 2011 13:30:55 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[quercus]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>创业公司参与项目的人口众多、背景不一，目前市场上的主流方向为php与java，很多时候java工程师恨铁不成钢，php工程师也无可奈何。于是便有了此文，讲述如何使用quercus创建php java混合型项目。 quercus是什么？ quercus是Caucho公司针对php语言的java实现，100%完成了php5的解析。是resin内建支持的功能。同时，因为使用了resin，使得php可以很容易得到连接池、分布式session、负载均衡等功能。使用resin的php项目可以更加安全，不存在很多fastcgi的问题。 性能如何？ 官方：用mediawiki与drupal来做实验，要比mod_php快4倍。 有一个编译选项，在resin专业版里支持，可以把php转成java class，得到更高性能。 新建一个java项目混合php项目 web.xml是关键，里面声明了*.php文件的访问都以com.caucho.quercus.servlet.QuercusServlet来执行。 &#60;?xml&#160;version="1.0"&#160;encoding="UTF-8"?&#62;&#160;&#160; &#60;web-app&#160;xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&#160;&#160; &#160;&#160;&#160;&#160;xmlns="http://java.sun.com/xml/ns/javaee"&#160;xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&#160;&#160; &#160;&#160;&#160;&#160;xsi:schemaLocation="http://java.sun.com/xml/ns/javaee&#160;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"&#160;&#160; &#160;&#160;&#160;&#160;id="WebApp_ID"&#160;version="2.5"&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;display-name&#62;testquercus&#60;/display-name&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;welcome-file-list&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;welcome-file&#62;index.html&#60;/welcome-file&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;welcome-file&#62;index.php&#60;/welcome-file&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/welcome-file-list&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;servlet&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;servlet-name&#62;Quercus&#160;Servlet&#60;/servlet-name&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;servlet-class&#62;com.caucho.quercus.servlet.QuercusServlet&#60;/servlet-class&#62;&#160;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/servlet&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;servlet-mapping&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;servlet-name&#62;Quercus&#160;Servlet&#60;/servlet-name&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#60;url-pattern&#62;*.php&#60;/url-pattern&#62;&#160;&#160; &#160;&#160;&#160;&#160;&#60;/servlet-mapping&#62;&#160;&#160;&#160; &#60;/web-app&#62;&#160;&#160; 所有的php文件放在webapp下，所有的java文件还放到java目录里。 如何混合java到php中? 在java目录新建类Test54Chen，生成后位置： WEB-INF/classes/com/chen/FrameWork.class /**&#160; &#160;*&#160;@author&#160;54chen(陈臻)&#160;[chenzhen@xiaomi.com&#160;czhttp@gmail.com]&#160; &#160;*&#160;@since&#160;2011-10-25&#160;下午08:40:49&#160; &#160;*/&#160;&#160; package&#160;com.chen;&#160;&#160; &#160;&#160; public&#160;class&#160;FrameWork&#160;{&#160;&#160; &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p>创业公司参与项目的人口众多、背景不一，目前市场上的主流方向为php与java，很多时候java工程师恨铁不成钢，php工程师也无可奈何。于是便有了此文，讲述如何使用quercus创建php java混合型项目。</p>
<p><strong>quercus是什么？</strong><br />
quercus是Caucho公司针对php语言的java实现，100%完成了php5的解析。是resin内建支持的功能。同时，因为使用了resin，使得php可以很容易得到连接池、分布式session、负载均衡等功能。使用resin的php项目可以更加安全，不存在很多fastcgi的问题。</p>
<p><strong>性能如何？</strong><br />
官方：用mediawiki与drupal来做实验，要比mod_php快<strong>4</strong>倍。<br />
有一个编译选项，在resin专业版里支持，可以把php转成java class，得到更高性能。</p>
<p><strong>新建一个java项目混合php项目</strong><br />
web.xml是关键，里面声明了*.php文件的访问都以com.caucho.quercus.servlet.QuercusServlet来执行。</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-xml" start="1">
<li class="alt"><span><span class="tag">&lt;?</span><span class="tag-name">xml</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"1.0"</span><span>&nbsp;</span><span class="attribute">encoding</span><span>=</span><span class="attribute-value">"UTF-8"</span><span class="tag">?&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span><span class="tag">&lt;</span><span class="tag-name">web-app</span><span>&nbsp;</span><span class="attribute">xmlns:xsi</span><span>=</span><span class="attribute-value">"http://www.w3.org/2001/XMLSchema-instance"</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">xmlns</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee"</span><span>&nbsp;</span><span class="attribute">xmlns:web</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">xsi:schemaLocation</span><span>=</span><span class="attribute-value">"http://java.sun.com/xml/ns/javaee&nbsp;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="attribute">id</span><span>=</span><span class="attribute-value">"WebApp_ID"</span><span>&nbsp;</span><span class="attribute">version</span><span>=</span><span class="attribute-value">"2.5"</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">display-name</span><span class="tag">&gt;</span><span>testquercus</span><span class="tag">&lt;/</span><span class="tag-name">display-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">welcome-file-list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>index.html</span><span class="tag">&lt;/</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>index.php</span><span class="tag">&lt;/</span><span class="tag-name">welcome-file</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">welcome-file-list</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>Quercus&nbsp;Servlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>com.caucho.quercus.servlet.QuercusServlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-class</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">servlet</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>Quercus&nbsp;Servlet</span><span class="tag">&lt;/</span><span class="tag-name">servlet-name</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>*.php</span><span class="tag">&lt;/</span><span class="tag-name">url-pattern</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="tag">&lt;/</span><span class="tag-name">servlet-mapping</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;&nbsp;</span></span></li>
<li class="alt"><span><span class="tag">&lt;/</span><span class="tag-name">web-app</span><span class="tag">&gt;</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>所有的php文件放在webapp下，所有的java文件还放到java目录里。</p>
<p>如何混合java到php中?<br />
在java目录新建类Test54Chen，生成后位置：<br />
WEB-INF/classes/com/chen/FrameWork.class</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-j" start="1">
<li class="alt"><span><span class="comment">/**</span>&nbsp;</span></li>
<li class=""><span><span class="comment">&nbsp;*&nbsp;@author&nbsp;54chen(陈臻)&nbsp;[chenzhen@xiaomi.com&nbsp;czhttp@gmail.com]</span>&nbsp;</span></li>
<li class="alt"><span><span class="comment">&nbsp;*&nbsp;@since&nbsp;2011-10-25&nbsp;下午08:40:49</span>&nbsp;</span></li>
<li class=""><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
<li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.chen;&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;</span></li>
<li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;FrameWork&nbsp;{&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;String&nbsp;go(String&nbsp;who)&nbsp;{&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">return</span><span>&nbsp;who&nbsp;+&nbsp;</span><span class="string">"&nbsp;gogogo!"</span><span>;&nbsp;&nbsp;</span></span></li>
<li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
<li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>在webapp新建php文件：<br />
test.php</p>
<div class="chen-hl">
<div class="bar"></div>
<ol class="dp-c" start="1">
<li class="alt"><span><span>&lt;?php&nbsp;&nbsp;</span></span></li>
<li class=""><span>import&nbsp;com.chen.FrameWork;&nbsp;&nbsp;</span></li>
<li class="alt"><span><span class="vars">$f</span><span>&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;FrameWork();&nbsp;&nbsp;</span></span></li>
<li class=""><span>var_dump(<span class="vars">$f</span><span>-&gt;go(</span><span class="string">"ohohoh"</span><span>));&nbsp;&nbsp;</span></span></li>
<li class="alt"><span>?&gt;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>配置到resin中：<br />
目标文件夹指到webapp。</p>
<p>访问：test.php</p>
<p>截图：<br />
1.整个项目的情况<br />
<img src="http://img04.taobaocdn.com/imgextra/i4/T1dG1wXjBcXXa0Lrvb_092913.jpg" alt="quercus" /><br />
2.访问的结果<br />
<img src="http://img01.taobaocdn.com/imgextra/i1/T115OvXmaaXXXqGHYb_092949.jpg" alt="quercus php java" /><br />
下一记：如何利用java做连接池提供给php使用。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/quercus-notes-php-java-mixed-projects.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>redmine极速安装手记</title>
		<link>http://www.54chen.com/php-tech/redmine-install-fast-detail.html</link>
		<comments>http://www.54chen.com/php-tech/redmine-install-fast-detail.html#comments</comments>
		<pubDate>Wed, 03 Aug 2011 00:40:06 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[资料文档]]></category>
		<category><![CDATA[install]]></category>
		<category><![CDATA[redmine]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/redmine-install-fast-detail.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>Redmine是用Ruby开发的基于基于web的项目管理软件，是用ROR框架开发的一套跨平台项目管理系统，系统通过“项目（Project）”的形式把成员、任务（问题）、文档、讨论以及各种形式的资源组织在一起，大家参与更新任务、文档等内容来推动项目的进度，同时系统利用时间线索和各种动态的报表形式来自动给成员汇报项目进度。 机器环境： ubuntu 10.04 dell optiplex 380 root权限下操作 1）apt-get install mysql-client mysqld-server 2)进mysql: create database redmine_default; GRANT all ON redmine_default.* TO root@'%' IDENTIFIED BY 'miliao'; FLUSH PRIVILEGES ; 3)apt-get install redmine redmine-mysql subversion libapache2-mod-passenger 4)ln -s /usr/share/redmine/public /var/www/redmine 5)a2enmod passenger &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img04.taobaocdn.com/imgextra/i4/T1RF46XddFXXXANWHX_084227.jpg" alt="redmine install ubuntu" /><br />
Redmine是用Ruby开发的基于基于web的项目管理软件，是用ROR框架开发的一套跨平台项目管理系统，系统通过“项目（Project）”的形式把成员、任务（问题）、文档、讨论以及各种形式的资源组织在一起，大家参与更新任务、文档等内容来推动项目的进度，同时系统利用时间线索和各种动态的报表形式来自动给成员汇报项目进度。</p>
<p>机器环境：</p>
<blockquote><p>ubuntu 10.04 dell optiplex 380<br />
root权限下操作</p></blockquote>
<p>1）apt-get install mysql-client mysqld-server</p>
<p>2)进mysql:</p>
<blockquote><p>create database redmine_default;<br />
GRANT all ON redmine_default.* TO root@'%' IDENTIFIED BY 'miliao';<br />
FLUSH PRIVILEGES ;</p></blockquote>
<p>3)apt-get install redmine redmine-mysql subversion libapache2-mod-passenger</p>
<p>4)ln -s /usr/share/redmine/public /var/www/redmine</p>
<p>5)a2enmod passenger</p>
<p>6)chmod a+x /usr/share/redmine/public</p>
<p>7)/etc/apache2/sites-available/default<br />
增加：</p>
<blockquote><p>&lt;Directory /var/www/redmine&gt;<br />
RailsBaseURI /redmine<br />
PassengerResolveSymlinksInDocumentRoot on<br />
&lt;/Directory&gt;</p></blockquote>
<p>8)/etc/init.d/apache2 restart<br />
9)打开 http://xxx/redmine</p>
<p>排查问题：<br />
1） /var/log/redmine下有500的原因<br />
2）中文乱码问题：</p>
<blockquote><p>上述第8步时，不要着急做配置。把redmine_default整个数据库导出来，替换其中的charset=laitin1为charset=utf8，清空原表重新导入后再用admin/admin登录重新配置。</p></blockquote>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/redmine-install-fast-detail.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>mediawiki脚本自动发内容实现</title>
		<link>http://www.54chen.com/php-tech/mediawiki-scripts-auto-post.html</link>
		<comments>http://www.54chen.com/php-tech/mediawiki-scripts-auto-post.html#comments</comments>
		<pubDate>Fri, 01 Jul 2011 02:29:07 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[autopost]]></category>
		<category><![CDATA[mediawiki]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/mediawiki-scripts-auto-post.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>相信很多公司都是在使用mediawiki做内部team的知识管理，同时也有一些边边角角的脚本去做诸如上线、报警一类的工作。经常会有这样的需求：在上线的时候自动更新wiki的一页内容。 实现起来很简单，只需要一个curl即可，mediawiki提供了http restful的接口，在api.php上，可以做很多事情，下面是实际使用的举例。 目标：上线脚本最后执行一下记录，更新wiki里的一页做为上线记录，Online logging包换的元素有：日期，项目，版本号，机器。 环境：安装了 curl的机器 实现细节（wiki.sh）： #! /bin/sh OPS_APP=$1 shift OPS_REV=$1 shift OPS_SERVER=$1 OPS_TIME=`date` echo "\nwrite to wiki" TOKEN=`curl -s -d 'action=login&#038;lgname=你的用户名&#038;lgpassword=你的密码&#038;format=json' http://你的wiki域名/wiki/api.php -D cookies.txt -b cookies.txt &#124; sed -e 's/.*token":"//' -e 's/".*//'` curl -s -d "action=login&#038;lgname=你的用户名&#038;lgpassword=你的密码&#038;lgtoken=${TOKEN}&#038;format=json" http://你的wiki域名/wiki/api.php &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img04.taobaocdn.com/imgextra/i4/T1r11iXhVkXXX_.NQ8_100702.jpg" alt="mediawiki auto post" /></p>
<p>相信很多公司都是在使用mediawiki做内部team的知识管理，同时也有一些边边角角的脚本去做诸如上线、报警一类的工作。经常会有这样的需求：在上线的时候自动更新wiki的一页内容。</p>
<p>实现起来很简单，只需要一个curl即可，mediawiki提供了http restful的接口，在api.php上，可以做很多事情，下面是实际使用的举例。</p>
<p>目标：上线脚本最后执行一下记录，更新wiki里的一页做为上线记录，Online logging包换的元素有：日期，项目，版本号，机器。</p>
<p>环境：安装了 curl的机器</p>
<p><strong>实现细节（wiki.sh）：</strong></p>
<blockquote><p>#! /bin/sh<br />
OPS_APP=$1<br />
shift<br />
OPS_REV=$1<br />
shift<br />
OPS_SERVER=$1<br />
OPS_TIME=`date`<br />
echo "\nwrite to wiki"</p>
<p>TOKEN=`curl -s -d 'action=login&#038;lgname=你的用户名&#038;lgpassword=你的密码&#038;format=json' http://你的wiki域名/wiki/api.php -D cookies.txt -b cookies.txt | sed -e 's/.*token":"//' -e 's/".*//'`</p>
<p>curl -s -d "action=login&#038;lgname=你的用户名&#038;lgpassword=你的密码&#038;lgtoken=${TOKEN}&#038;format=json" http://你的wiki域名/wiki/api.php -b cookies.txt -D cookies.txt > result</p>
<p>RET=`curl -s 'http://你的wiki域名/wiki/api.php?action=query&#038;prop=info&#038;intoken=edit&#038;titles=Online_logging&#038;indexpageids=&#038;format=json' -b cookies.txt -D cookies.txt `</p>
<p>ETOKEN=`echo ${RET}|sed -e 's/.*token":"//' -e 's/".*//' -e 's/+/%2B/g'`<br />
ETOKEN=`echo ${ETOKEN}|sed -e 's/\\\\/%5C/g'`<br />
TIME=`echo ${RET}|sed -e 's/.*starttimestamp":"//' -e 's/".*//'`<br />
URL="action=edit&#038;title=Online_logging&#038;section=0&#038;appendtext=%0A|${OPS_TIME}||${OPS_APP}||${OPS_REV}||${OPS_SERVER} %0A |-&#038;summary=robot change&#038;starttimestamp=${TIME}&#038;token=${ETOKEN}&#038;format=json"</p>
<p>curl -s -d "${URL}" http://你的wiki域名/wiki/api.php -b cookies.txt -D cookies.txt > result<br />
echo "\n**write successful**\n"
</p></blockquote>
<p><strong>具体使用：</strong><br />
首先新建一个名字为Online_logging的页面，内容如下：</p>
<blockquote><p>{|border="1" cellspacing="0"<br />
|-<br />
! 日期 || 项目 || 版本号 || 机器<br />
|-</p></blockquote>
<blockquote><p>sh wiki.sh 项目 版本号 服务器ip</p></blockquote>
<p><strong>api参考：</strong></p>
<p>http://www.mediawiki.org/wiki/API:Login</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/mediawiki-scripts-auto-post.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>[54chen原创]简单好用的土办法抗击洋鬼子对wordpress系统的广告灌入</title>
		<link>http://www.54chen.com/php-tech/easy-method-to-antispam-wordpress.html</link>
		<comments>http://www.54chen.com/php-tech/easy-method-to-antispam-wordpress.html#comments</comments>
		<pubDate>Mon, 23 Aug 2010 15:24:02 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[antispam]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/easy-method-to-antispam-wordpress.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>自升级wordpress3.0以后，一切风调雨顺，自上周起，被洋鬼子的广告肉机盯上了，平均每三五分钟一条广告，评论内容大致相同，评论ip来自五湖四海，各不相同。 虽然说akismet是wordpress中antispam无二的选择，但是akismet那个验证码让人很纠结，于是只能自己山寨一把了。 土办法步骤一 转发默认评论地址 常见的洋鬼子的广告肉机，都是利用了wordpress公开的post地址来做到脚本灌入的，其默认地址是wp-comments-post.php，第一步要做的是，屏蔽这个地址（以nginx为例）： rewrite ^/wp\-comments\-post\.php$ http://www.54chen.com/ last; 土办法步骤二 伪造假地址 既然第一步中的真实地址无法访问了，那第二步肯定是假冒出来可以访问的地址： if (!-e $request_filename){ rewrite ^/wc([0-9]+)\.html$ /wp-comments-post.php?54chen=$1 last; } 土办法步骤三 javascript制造假post 完成上面两步之后 ，最后一步就是将原来的comments.php修改post action的地址为伪造的地址，为了更加有效果，使用js来产生随机的wc1234.html即可： 在评论的form中增加onsubmit="chenAntiSpam()" name="commentform"； 再增加js: &#60;script type="text/javascript"&#62; function chenAntiSpam() {  var param ='wc'+Math.round(Math.random()*1000)+'.html';  document.commentform.action = 'http://www.54chen.com/'+param; } &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img04.taobaocdn.com/imgextra/i4/T1c3hJXb8pXXcVO1Z._112132.jpg" alt="54chen" /></p>
<p>自升级wordpress3.0以后，一切风调雨顺，自上周起，被洋鬼子的广告肉机盯上了，平均每三五分钟一条广告，评论内容大致相同，评论ip来自五湖四海，各不相同。<br />
虽然说akismet是wordpress中antispam无二的选择，但是akismet那个验证码让人很纠结，于是只能自己山寨一把了。<br />
<strong>土办法步骤一 转发默认评论地址</strong><br />
常见的洋鬼子的广告肉机，都是利用了wordpress公开的post地址来做到脚本灌入的，其默认地址是wp-comments-post.php，第一步要做的是，屏蔽这个地址（以nginx为例）：<br />
rewrite ^/wp\-comments\-post\.php$ http://www.54chen.com/ last;</p>
<p><strong>土办法步骤二 伪造假地址</strong><br />
既然第一步中的真实地址无法访问了，那第二步肯定是假冒出来可以访问的地址：<br />
if (!-e $request_filename){<br />
rewrite ^/wc([0-9]+)\.html$ /wp-comments-post.php?54chen=$1 last;<br />
}</p>
<p><strong>土办法步骤三 javascript制造假post</strong><br />
完成上面两步之后 ，最后一步就是将原来的comments.php修改post action的地址为伪造的地址，为了更加有效果，使用js来产生随机的wc1234.html即可：<br />
在评论的form中增加onsubmit="chenAntiSpam()" name="commentform"；<br />
再增加js:</p>
<p>&lt;script type="text/javascript"&gt;<br />
function chenAntiSpam() {<br />
 var param ='wc'+Math.round(Math.random()*1000)+'.html';<br />
 document.commentform.action = 'http://www.54chen.com/'+param;<br />
}<br />
&lt;/script&gt;</p>
<p>大功告成，有效防住了洋鬼子的灌。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/easy-method-to-antispam-wordpress.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>由php的call_user_func传reference引发的思考</title>
		<link>http://www.54chen.com/php-tech/php-call_user_func-reference-thinking.html</link>
		<comments>http://www.54chen.com/php-tech/php-call_user_func-reference-thinking.html#comments</comments>
		<pubDate>Tue, 20 Jul 2010 00:56:20 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[call_user_func]]></category>
		<category><![CDATA[reference]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/php-call_user_func-reference-thinking.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>问题的提出 网友bercmisir在院内留言，针对php手册中的call_user_func函数的文档一事，大致如下： http://php.net/manual/en/function.call-user-func.php 其中parameter下有这样一句话： Note: Note that the parameters for call_user_func() are not passed by reference. 简单地翻译一下，是说这个函数的参数是不能依靠引用来传递的。 还有一个例子： 输出是： 0 1 而网友bercmisir的问题在于： call_user_func('increment', $a);输出是0,而call_user_func('increment', &#038;$a);却输出是1，明明说不能依靠引用来传递。 寻根溯源 然后再进一步寻根溯源，这个Note的信息其实是http://bugs.php.net/bug.php?id=24931这个bug中最后处理的结果。 并且在call_user_func('increment', &#038;$a);虽然输出了1的结果，但一般情况下，会有一个警告信息：Deprecated: Call-time pass-by-reference has been deprecated。 这是什么原因呢？ 先看一个例子： 结果为2，并且没有类似expected to be a &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img06.taobaocdn.com/imgextra/i6/T1IytGXchrXXa_aivX_085522.jpg" alt="搞技术一定要深入到群众当中" /></p>
<p><strong>问题的提出</strong><br />
网友bercmisir在院内留言，针对php手册中的call_user_func函数的文档一事，大致如下：</p>
<p>http://php.net/manual/en/function.call-user-func.php</p>
<p>其中parameter下有这样一句话：<br />
Note: Note that the parameters for call_user_func() are not passed by reference.<br />
简单地翻译一下，是说这个函数的参数是不能依靠引用来传递的。<br />
还有一个例子：<br />
<?php<br />
error_reporting(E_ALL);<br />
function increment(&#038;$var)<br />
{<br />
    $var++;<br />
}</p>
<p>$a = 0;<br />
call_user_func('increment', $a);<br />
echo $a."\n";</p>
<p>call_user_func_array('increment', array(&#038;$a)); // You can use this instead before PHP 5.3<br />
echo $a."\n";<br />
?><br />
输出是：<br />
0<br />
1<br />
而网友bercmisir的问题在于：<br />
call_user_func('increment', $a);输出是0,而call_user_func('increment', &#038;$a);却输出是1，明明说不能依靠引用来传递。</p>
<p><strong>寻根溯源</strong></p>
<p>然后再进一步寻根溯源，这个Note的信息其实是http://bugs.php.net/bug.php?id=24931这个bug中最后处理的结果。<br />
并且在call_user_func('increment', &#038;$a);虽然输出了1的结果，但一般情况下，会有一个警告信息：Deprecated: Call-time pass-by-reference has been deprecated。</p>
<p>这是什么原因呢？<br />
先看一个例子：<br />
<?php<br />
error_reporting(E_ALL);<br />
function increment(&#038;$var)<br />
{<br />
    $var++;<br />
}<br />
$x = 1;<br />
increment($x);<br />
echo $x;<br />
?><br />
结果为2，并且没有类似expected to be a reference, value given的警告信息，相反地，如果将第8行代码修改为&#038;$x，将得到一个废除警告。从而得以验证，其实PHP在传递过程中，变量会根据形参需要的到底是引用还是值来自行决定传输的是引用还是值，并不需要显式地传递（相反显式传递是即将被废除的）。</p>
<p><strong>继续深入</strong></p>
<p>http://www.php.net/manual/en/language.references.pass.php</p>
<p>在php手册中，介绍引用的传递一节，在中间位置有一个Note说到：在函数调用时是不需要传引用的(也就是上节所说的显式调用)，在5.3中如果显式调用会出来一个废除警告。</p>
<p><strong>分析源码</strong></p>
<p>有人说：在php中写入，everything is a reference。<br />
查阅php源码，在./Zend/zend_compile.c的1579行有函数定义zend_do_pass_param。（php5.2.13）<br />
其中有这样一句判断：<br />
 if (original_op == ZEND_SEND_REF &#038;&#038; !CG(allow_call_time_pass_reference)) {打印废除警告。}<br />
大概意思就是说，在传递的是引用，并且php.ini的allow_call_time_pass_reference为否的话，打印警告。<br />
再看zend_do_pass_param使用的地方，可以发现是在parser阶段时，根据参数ZVAL结构体中元素的定义，来传递到底是var还是value还是reference。（php5.2.13 ./Zend/zend_language_parser.y/c 451/3593）</p>
<p><strong>结论</strong></p>
<p>引用其实类似linux里的文件硬链接一样，但和C语言中的指针是不相同的，在parser阶段php会根据上下文环境自行判断是传引用还是值。而本文所提到的call_user_function并不会自行判断传的是引用还是值。所以前面的例子call_user_function在传值的时候不管用，而在传引用的时候得出了正确结果（但其实还有一个废除警告）。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/php-call_user_func-reference-thinking.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[警示]Nginx + PHP CGI的安全漏洞：fix_pathinfo</title>
		<link>http://www.54chen.com/php-tech/nginx-php-cgi-of-security-hole.html</link>
		<comments>http://www.54chen.com/php-tech/nginx-php-cgi-of-security-hole.html#comments</comments>
		<pubDate>Thu, 20 May 2010 11:09:14 +0000</pubDate>
		<dc:creator>54chen</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[fix_pathinfo漏洞]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/nginx-php-cgi-of-security-hole.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>如果你正在使用nginx+php，请关注。 表像： 具体的重现过程，用php代码修改后缀名后上传，比如说www.xxx.com/1.jpg，访问的时候用www.xxx.com/1.jpg/xxx.php 这段jpg代码将会被执行！！！ http://docs.php.net/manual/zh/ini.core.php cgi.fix_pathinfo "1" PHP_INI_ALL 从 PHP 4.3.0 起可用 请注意：默认为1 解决办法： 1.修改php.ini中的cgi.cgi.fix_pathinfo为0（即使你在php.ini中没有搜到，也要设置，没有搜到表示默认为1） 2.判断文件上传类型时使用严格的判断，至于怎么判断，参见：http://www.54chen.com/php-tech/php-upload-file-types-to-determine-the-complete-program-and-php-nginx-upload-size-and-complete-control-program.html 3.把nginx的判断正则修改为去除/ if ( $fastcgi_script_name ~ \..*\/.*php ) { return 403; } 鸟哥在http://www.laruence.com/2010/05/20/1495.html一文中提及此事。<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><img src="http://img05.taobaocdn.com/bao/uploaded/i5/T1.RRAXjVDXXX7OsE8_070026.jpg" alt="php漏洞" /></p>
<p>如果你正在使用nginx+php，请关注。</p>
<p><strong>表像：</strong></p>
<p>具体的重现过程，用php代码修改后缀名后上传，比如说www.xxx.com/1.jpg，访问的时候用www.xxx.com/1.jpg/xxx.php</p>
<blockquote><p><strong><span style="color: #ff0000;">这段jpg代码将会被执行！！！</span></strong></p></blockquote>
<p><a href="http://docs.php.net/manual/zh/ini.core.php">http://docs.php.net/manual/zh/ini.core.php</a><br />
cgi.fix_pathinfo "1" PHP_INI_ALL 从 PHP 4.3.0 起可用 <strong><span style="color: #ff0000;">请注意：默认为1</span></strong></p>
<p><strong>解决办法：</strong><br />
1.修改php.ini中的cgi.cgi.fix_pathinfo为0（<span style="text-decoration: underline;">即使你在php.ini中没有搜到，也要设置，没有搜到表示默认为1</span>）<br />
2.判断文件上传类型时使用严格的判断，至于怎么判断，参见：<a href="http://www.54chen.com/php-tech/php-upload-file-types-to-determine-the-complete-program-and-php-nginx-upload-size-and-complete-control-program.html">http://www.54chen.com/php-tech/php-upload-file-types-to-determine-the-complete-program-and-php-nginx-upload-size-and-complete-control-program.html</a><br />
3.把nginx的判断正则修改为去除/<br />
if ( $fastcgi_script_name ~ \..*\/.*php ) {<br />
return 403;<br />
}</p>
<p>鸟哥在<a href="http://www.laruence.com/2010/05/20/1495.html">http://www.laruence.com/2010/05/20/1495.html</a>一文中提及此事。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/nginx-php-cgi-of-security-hole.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>从php核心代码看require和include的区别</title>
		<link>http://www.54chen.com/php-tech/php-require-include.html</link>
		<comments>http://www.54chen.com/php-tech/php-require-include.html#comments</comments>
		<pubDate>Wed, 05 May 2010 10:13:13 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[include]]></category>
		<category><![CDATA[require]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/php-require-include.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>前言 五一长假归来，休息长时间很有点不习惯，回到北京已经有些不适应了。 见到鸟哥的一文：深入理解PHP之require/include顺序 http://www.laruence.com/2010/05/04/1450.html 忍不住继续再深入了一下下，在此记录一下深入的过程，以供以后查阅。 普及 在php手册中： require() is identical to include() except upon failure it will also produce a fatal E_ERROR level error. In other words, it will halt the script whereas include() only emits a warning (E_WARNING) which &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p><strong>前言</strong><br />
五一长假归来，休息长时间很有点不习惯，回到北京已经有些不适应了。<br />
见到鸟哥的一文：深入理解PHP之require/include顺序 <a href="http://www.laruence.com/2010/05/04/1450.html">http://www.laruence.com/2010/05/04/1450.html</a><br />
忍不住继续再深入了一下下，在此记录一下深入的过程，以供以后查阅。</p>
<p><strong>普及</strong><br />
在php手册中：</p>
<blockquote><p>require() is identical to include()  except upon failure it will also produce a fatal E_ERROR  level error. In other words, it will halt the script whereas include() only emits a warning (E_WARNING) which allows the script to continue.</p></blockquote>
<p>就是说在失败的时候，require是会中止php运行的，而include是可以继续运行的。<br />
倒底有什么样的区别呢？我们带着这个疑问来一起进入PHP的核心代码。<br />
下面是一个PHP运行过程的图（这个图是出自哪里的？鸟哥画的？）<br />
<img src="http://img02.taobaocdn.com/bao/uploaded/i2/T1I1NzXa4xXXcL7xo6_062051.jpg" alt="php " /></p>
<blockquote><p>补习一下：lex是代码扫描器，扫描代码用的，yacc是Yet Another Compiler Compiler，作用是把任何一种代码的语法转成yacc语法，yacc就是解析器（真TMD绕）。<br />
lex在c下的后缀是*.l  yacc是*.y</p></blockquote>
<p><strong>正题</strong><br />
下面看操作记录：</p>
<blockquote><p>cc@cc-laptop:/opt/workspace$ svn checkout http://svn.php.net/repository/php/php-src/branches/PHP_5_3 php-src-5.3<br />
从svn取最新的php源代码。
</p></blockquote>
<p>开始深入：</p>
<blockquote><p>cc@cc-laptop:/opt/workspace/php-src-5.3$ find . -type f -name "*.l" -exec grep -Hn "require_once" {} \;<br />
./Zend/zend_language_scanner.l:1093:"require_once" {<br />
寻找lex代码扫描器文件中出现require_once的地方，zend_language_scanner.l的1093行。<br />
1093  "require_once" {<br />
1094         return T_REQUIRE_ONCE;<br />
1095 }</p></blockquote>
<p>然后再搜一下T_REQUIRE_ONCE,</p>
<blockquote><p>cc@cc-laptop:/opt/workspace/php-src-5.3$ find . -type f -name "*.y" -exec grep -Hn "T_INCLUDE" {} \;<br />
./Zend/zend_language_parser.y:52:%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE<br />
./Zend/zend_language_parser.y:985:	|	T_INCLUDE expr 			{ zend_do_include_or_eval(ZEND_INCLUDE, &amp;$$, &amp;$2 TSRMLS_CC); }<br />
./Zend/zend_language_parser.y:986:	|	T_INCLUDE_ONCE expr 	{ zend_do_include_or_eval(ZEND_INCLUDE_ONCE, &amp;$$, &amp;$2 TSRMLS_CC); }</p></blockquote>
<p>在985行附近，有这样一群代码：</p>
<blockquote><p>internal_functions_in_yacc:<br />
T_ISSET '(' isset_variables ')' { $$ = $3; }<br />
|       T_EMPTY '(' variable ')'        { zend_do_isset_or_isempty(ZEND_ISEMPTY, &amp;$$, &amp;$3 TSRMLS_CC); }<br />
|       T_INCLUDE expr                  { zend_do_include_or_eval(ZEND_INCLUDE, &amp;$$, &amp;$2 TSRMLS_CC); }<br />
|       T_INCLUDE_ONCE expr     { zend_do_include_or_eval(ZEND_INCLUDE_ONCE, &amp;$$, &amp;$2 TSRMLS_CC); }<br />
|       T_EVAL '(' expr ')'     { zend_do_include_or_eval(ZEND_EVAL, &amp;$$, &amp;$3 TSRMLS_CC); }<br />
|       T_REQUIRE expr                  { zend_do_include_or_eval(ZEND_REQUIRE, &amp;$$, &amp;$2 TSRMLS_CC); }<br />
|       T_REQUIRE_ONCE expr             { zend_do_include_or_eval(ZEND_REQUIRE_ONCE, &amp;$$, &amp;$2 TSRMLS_CC); }<br />
;</p></blockquote>
<p>于是乎，我们需要继续深入寻找zend_do_include_or_eval，</p>
<blockquote><p>cc@cc-laptop:/opt/workspace/php-src-5.3$ find . -type f -name "*.c" -exec grep -Hn "zend_do_include_or_eval" {} \;<br />
./Zend/zend_compile.c:4317:void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */</p></blockquote>
<p>zend_do_include_or_eval中组装了一个结构体，ZEND_INCLUDE_OR_EVAL。</p>
<p>再在zend_vm_def.h中找到ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)：<br />
switch (Z_LVAL(opline-&gt;op2.u.constant)) {代码略}</p>
<p>中间关键的一句是：<br />
new_op_array = compile_filename(Z_LVAL(opline-&gt;op2.u.constant), inc_filename TSRMLS_CC);</p>
<p>在zend_complie.h文件中:<br />
ZEND_API zend_op_array *compile_filename(int type, zval *filename TSRMLS_DC);</p>
<p>这个函数定义在zend_language_scaner.l文件中，找出最核心的代码：</p>
<blockquote><p>if (open_file_for_scanning(file_handle TSRMLS_CC)==FAILURE) {<br />
// require与include的差别：错误信息的显示级别（有bailout和无bailout）<br />
if (type==ZEND_REQUIRE) {   //require时<br />
zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle-&gt;filename TSRMLS_CC);<br />
zend_bailout();<br />
} else {<br />
zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle-&gt;filename TSRMLS_CC);<br />
}<br />
compilation_successful=0;<br />
} else {代码略}</p></blockquote>
<p>继续追踪zend_message_dispatcher可以在main/main.c文件中找到php_message_handler_for_zend函数：</p>
<blockquote><p>//include输出错误信息时的级别为：E_WARNING<br />
		case ZMSG_FAILED_INCLUDE_FOPEN:<br />
			php_error_docref("function.include" TSRMLS_CC, E_WARNING, "Failed opening '%s' for inclusion (include_path='%s')", php_strip_url_passwd((char *) data), STR_PRINT(PG(include_path)));<br />
			break;<br />
		//require输出错误信息时的级别为：E_COMPILE_ERROR<br />
代码略
</p></blockquote>
<p><strong>总结</strong><br />
和开头PHP手册所说完全一致，require和include的区别在于，出现错误时，一个是error一个是warning。</p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/php-require-include.html/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>PHP上传进度条深度解析</title>
		<link>http://www.54chen.com/php-tech/php-upload-progress.html</link>
		<comments>http://www.54chen.com/php-tech/php-upload-progress.html#comments</comments>
		<pubDate>Sun, 18 Apr 2010 10:32:09 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[上传进度条]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/php-upload-progress.html</guid>
		<description><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br>随着互联网的发展，越来越多的技术开始注重用户体验，以人为本才是长久之道，于是在上传的时候，大家都不再满足一个单一的“浏览”按钮，纷纷推出了带上传进度条的功能。而作为解释型语言的PHP，如何做到对上传文件的检测，如何实现上传进度条以其背后的原理，54chen将在本文中一步步展开。 一. 实现篇 一般情况，用PHP实现上传进度条就下面两种方法： 1.APC扩展（作者是PHP的创始人，5.2后PHP已经加入APC扩展） 2.PECL扩展模块 uploadprogress 不论是APC还是uploadprogress，都需要编译源码，因为原有的PHP函数根本不可能读取到临时文件夹里的东西。下面来看如何使用以及关键的代码： APC实现方法: 1.安装APC 2.配置php.ini，设置参数 apc.rfc1867=1 3.关键代码： if ($_SERVER['REQUEST_METHOD'] == 'POST') {  //上传请求 $status = apc_fetch('upload_' . $_POST['APC_UPLOAD_PROGRESS']); $status['done'] = 1; echo json_encode($status);  //输出给用户端页面里的ajax调用，相关文档请自己寻找 exit; } elseif (isset($_GET['progress_key'])) {   //读取上传进度 $status = apc_fetch('upload_'.$_GET['progress_key']); &#8230;<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></description>
			<content:encoded><![CDATA[<a href="http://www.54chen.com"><img border="0" src="http://www.54chen.com/wp-content/themes/54chen2011/images/54chen-logo.gif"></a><br>以下内容由<a href="http://www.54chen.com">[五四陈科学院]</a>提供<br><p>随着互联网的发展，越来越多的技术开始注重用户体验，以人为本才是长久之道，于是在上传的时候，大家都不再满足一个单一的“浏览”按钮，纷纷推出了带上传进度条的功能。而作为解释型语言的PHP，如何做到对上传文件的检测，如何实现上传进度条以其背后的原理，54chen将在本文中一步步展开。</p>
<p><strong>一. 实现篇</strong></p>
<p>一般情况，用PHP实现上传进度条就下面两种方法：</p>
<p>1.APC扩展（作者是PHP的创始人，5.2后PHP已经加入APC扩展）</p>
<p>2.PECL扩展模块 uploadprogress</p>
<p>不论是APC还是uploadprogress，都需要编译源码，因为原有的PHP函数根本不可能读取到临时文件夹里的东西。下面来看如何使用以及关键的代码：</p>
<div id="_mcePaste"><strong>APC实现方法:</strong></div>
<div id="_mcePaste">1.安装APC</div>
<div id="_mcePaste">2.配置php.ini，设置参数 apc.rfc1867=1</div>
<div id="_mcePaste">3.关键代码：</div>
<blockquote>
<div id="_mcePaste">if ($_SERVER['REQUEST_METHOD'] == 'POST') {  //上传请求</div>
<div id="_mcePaste">$status = apc_fetch('upload_' . $_POST['APC_UPLOAD_PROGRESS']);</div>
<div id="_mcePaste">$status['done'] = 1;</div>
<div id="_mcePaste">echo json_encode($status);  //输出给用户端页面里的ajax调用，相关文档请自己寻找</div>
<div id="_mcePaste">exit;</div>
<div id="_mcePaste">} elseif (isset($_GET['progress_key'])) {   //读取上传进度</div>
<div id="_mcePaste">$status = <span style="color: #ff0000;">apc_fetch</span>('upload_'.$_GET['progress_key']);</div>
<div id="_mcePaste">echo json_encode($status);</div>
<div id="_mcePaste">exit;</div>
<div id="_mcePaste">}</div>
</blockquote>
<div id="_mcePaste"><strong>uploadprogress实现方法：</strong></div>
<div id="_mcePaste">1.使用PECL 安装uploadprogress</div>
<div id="_mcePaste">2.php.ini里面设置 uploadprogress.file.filename_template = “/tmp/upd_%s.txt”</div>
<div id="_mcePaste">3.关键代码：</div>
<blockquote>
<div id="_mcePaste">if($_SERVER['REQUEST_METHOD']=='POST') {</div>
<div id="_mcePaste">if (is_uploaded_file($_FILES['upfile']['tmp_name'])) {</div>
<div id="_mcePaste">$upload_dir = 'your_path/';</div>
<div id="_mcePaste">$ext        = strrchr($_FILES['video']['name'], '.');</div>
<div id="_mcePaste">$sessid     = $_POST['UPLOAD_IDENTIFIER'] ;</div>
<div id="_mcePaste">$tmpfile    = $upload_dir . $sessid;</div>
<div id="_mcePaste">$sessfile   = $upload_dir . $sessid .$ext;</div>
<div id="_mcePaste">if (move_uploaded_file($_FILES['upfile']['tmp_name'],$tmpfile)) {</div>
<div id="_mcePaste">//上传成功</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">} elseif (!empty($_GET['sessid'])) {</div>
<div id="_mcePaste">header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");</div>
<div id="_mcePaste">header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");</div>
<div id="_mcePaste">header("Cache-Control: no-store, no-cache, must-revalidate");</div>
<div id="_mcePaste">header("Cache-Control: post-check=0, pre-check=0", false);</div>
<div id="_mcePaste">header("Pragma: no-cache");</div>
<div id="_mcePaste">header("Content-Type:text/html;charset=UTF-8");</div>
<div id="_mcePaste">$unique_id = $_GET['sessid'];</div>
<div id="_mcePaste">$uploadvalues = <span style="color: #ff0000;">uploadprogress_get_info</span>($unique_id);</div>
<div id="_mcePaste">if (is_array($uploadvalues)) {</div>
<div id="_mcePaste">echo json_encode($uploadvalues);</div>
<div id="_mcePaste">} else {</div>
<div id="_mcePaste">//读取进度失败，另外处理逻辑</div>
<div id="_mcePaste">}</div>
<div id="_mcePaste">}</div>
</blockquote>
<p><strong>二. 原理篇 </strong></p>
<p>注意上一篇中的红色函数。</p>
<p>下载到uploadprogress1.0.1进行源码分析，在代码中作了注释。</p>
<blockquote><p>static void uploadprogress_file_php_get_info(char * id, zval * return_value)</p>
<p>{</p>
<p>char s[1024];</p>
<p>char * filename;</p>
<p>char * template;</p>
<p>FILE *F;</p>
<p>TSRMLS_FETCH();</p>
<p>template = INI_STR("uploadprogress.file.filename_template"); <span style="color: #008000;">&lt;&lt;这里读取设置好的模板</span></p>
<p>if (strcmp(template, "") == 0)  {</p>
<p>return;</p>
<p>} else {</p>
<p>filename = uploadprogress_mk_filename( id, template );<span style="color: #008000;">&lt;&lt;&lt;存在的话，会创建</span></p>
<p>if (!filename) return;</p>
<p>F = VCWD_FOPEN(filename, "rb");</p>
<p>if (F) {</p>
<p>array_init(return_value);</p>
<p>while ( fgets(s, 1000, F) ) {<span style="color: #008000;">&lt;&lt;&lt;从流中读取一字符串 *s结果数据的首地址；1000-1:一次读入数据块的长度,其默认值为1k，即1024;F文件指针</span></p>
<p>char *k, *v, *e;</p>
<p>int index = 0;</p>
<p>e = strchr(s,'='); <span style="color: #008000;">&lt;&lt;&lt;查找字符串s中首次出现字符=的位置</span></p>
<p>if (!e) continue;</p>
<p>*e = 0; /* break the line into 2 parts */</p>
<p>v = e+1;</p>
<p>k = s;</p>
<p>/* trim spaces in front of the name/value */</p>
<p>while (*k &amp;&amp; *k &lt;= 32) k++;</p>
<p>while (*v &amp;&amp; *v &lt;= 32) v++;</p>
<p>/* trim spaces everywhere in the name */</p>
<p>for (e=k; *e; e++) if (*e &lt;= 32) { *e = 0; break; }</p>
<p>/* trim spaces only at the end of the value */</p>
<p>/* http://pecl.php.net/bugs/bug.php?id=14525 */</p>
<p>//for (e=v; *e; e++) if (*e &lt;= 32) { *e = 0; break; }</p>
<p>if (v != NULL) {<span style="color: #008000;">&lt;&lt;&lt;当文件有内容时</span></p>
<p>for (index = strlen(v); index &gt; 0; index--) {</p>
<p>if (v[index] &gt; 32) break;<span style="color: #008000;">&lt;&lt;&lt;累计</span></p>
<p>v[index] = 0;</p>
<p>}</p>
<p>}</p>
<p>add_assoc_string( return_value, k, v, 1 );</p>
<p>}</p>
<p>fclose(F);</p>
<p>}</p>
<p>if (filename) efree(filename);</p>
<p>return;</p>
<p>}</p>
<p>}</p></blockquote>
<p>在源码中还能发现:</p>
<blockquote><p>PHP_MINIT_FUNCTION(uploadprogress)</p>
<p>{</p>
<p>REGISTER_INI_ENTRIES();</p>
<p>php_rfc1867_callback = uploadprogress_php_rfc1867_file;</p>
<p>return SUCCESS;</p>
<p>}</p></blockquote>
<p>在MINIT中修改了php_rfc1867_callback，抽取uploadprogress_php_rfc1867_file的关键代码：</p>
<blockquote><p>upload_id = emalloc(strlen(*e_data-&gt;value) + 1);</p>
<p>strcpy(upload_id, *e_data-&gt;value);</p>
<p>progress-&gt;upload_id = upload_id;</p>
<p>progress-&gt;time_last  = time(NULL);</p>
<p>progress-&gt;speed_average  = 0;</p>
<p>progress-&gt;speed_last     = 0;</p>
<p>progress-&gt;bytes_uploaded = read_bytes;</p>
<p>progress-&gt;files_uploaded = 0;</p>
<p>progress-&gt;est_sec        = 0;</p>
<p>progress-&gt;identifier = uploadprogress_mk_filename(upload_id, template);<span style="color: #008000;">&lt;&lt;&lt;在指定的模板位置放下了临时文件</span></p>
<p>progress-&gt;identifier_tmp = emalloc(strlen( progress-&gt;identifier) + 4);</p>
<p>sprintf( progress-&gt;identifier_tmp, "%s.wr", progress-&gt;identifier );</p></blockquote>
<p>关于php_rfc1867_callback是什么，可以看哥学社另一哥鸟哥的分析 <a href="http://www.laruence.com/2008/11/07/586.html">http://www.laruence.com/2008/11/07/586.html</a></p>
<p><strong>三.总结</strong></p>
<p>在探测临时文件大小的时候，APC和 uploadprogress其实是大同小异的方法，先记录，再取大小百分比。</p>
<p>关于哥学社：<br />
<a style="color: #0b3b8c; text-decoration: none;" title="哥学社" href="http://www.54chen.com/blog-brother" target="_self">哥学社</a>是一个自由博客组织，以提高原创技术博客质量，为成员博客增加更有效评论，由来自腾讯、百度、盛大、人人网、新浪、奇虎、TOM等各大企业的哥们共同起草发起。</p>
<p>关于五四陈：<br />
54chen(陈臻)，人人网分布式存储研究人员，业余时间混迹于各技术组织且乐此不疲。目前关注实施PHP培训。对flex等前端技术有一点研究。<br />
个人技术站点:<a style="color: #0b3b8c; text-decoration: none;" href="http://www.54chen.com/">http://www.54chen.com/</a> 。可以通过电子邮件 czhttp@gmail.com 联系到他。</p>
<p>本文提及的文章：</p>
<p><a href="http://www.php.net/releases/5_2_0.php">http://www.php.net/releases/5_2_0.php</a></p>
<p><a href="http://www.ibm.com/developerworks/cn/opensource/os-php-v525/">http://www.ibm.com/developerworks/cn/opensource/os-php-v525/</a></p>
<p><a href="http://www.laruence.com/2008/11/07/586.html">http://www.laruence.com/2008/11/07/586.html</a></p>
<br><br>想快点找到作者也可以到Twitter上留言: <a href="https://www.twitter.com/54chen" target="_blank">@54chen</a><br>或者你懒得带梯子上墙，请到新浪微博：<a href="http://t.sina.com.cn/54chen" target="_blank">@54chen</a>]]></content:encoded>
			<wfw:commentRss>http://www.54chen.com/php-tech/php-upload-progress.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

