<?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/tag/php/feed" rel="self" type="application/rss+xml" />
	<link>http://www.54chen.com</link>
	<description>PHP、JAVA、缓存、架构、经验、分享</description>
	<lastBuildDate>Fri, 10 Feb 2012 12:21:03 +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>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>[警示]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>
		<item>
		<title>五四陈透过PHP看JAVA系列:fsockopen</title>
		<link>http://www.54chen.com/php-tech/54-chen-through-php-to-see-java-series-fsockopen.html</link>
		<comments>http://www.54chen.com/php-tech/54-chen-through-php-to-see-java-series-fsockopen.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 08:01:12 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[fsockopen]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/54-chen-through-php-to-see-java-series-fsockopen.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之间的一些异同，给从PHP学JAVA或者是从JAVA学PHP的同学一点启发，五四陈科学院出品。 第一部分，先看PHP的fsockopen 先来看PHP手册中的定义http://www.54chen.com/p/function.fsockopen.html 看完定义后，来看一段代码，利用PHP去更新squid的缓存： &#60;?php function updateCache($myUrl) { global $vSquidConfig; foreach ( $vSquidConfig ['host'] as $mySquid ) { $myHandle = @fsockopen ( "127.0.0.1", 80, $myErrNo, $myErrStr, 30 ); if ($myHandle) { $myResult = ''; @fputs ( $myHandle, "PURGE " . &#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之间的一些异同，给从PHP学JAVA或者是从JAVA学PHP的同学一点启发，五四陈科学院出品。</p>
<p><strong>第一部分，先看PHP的fsockopen</strong></p>
<p>先来看PHP手册中的定义<a href="http://www.54chen.com/p/function.fsockopen.html">http://www.54chen.com/p/function.fsockopen.html</a></p>
<p>看完定义后，来看一段代码，利用PHP去更新squid的缓存：</p>
<blockquote><p>&lt;?php<br />
function updateCache($myUrl) {<br />
global $vSquidConfig;<br />
foreach ( $vSquidConfig ['host'] as $mySquid ) {<br />
$myHandle = @fsockopen ( "127.0.0.1", 80, $myErrNo, $myErrStr, 30 );<br />
if ($myHandle) {<br />
$myResult = '';<br />
@fputs ( $myHandle, "PURGE " . $myFileName . " HTTP/1.0\r\n" );<br />
@fputs ( $myHandle, "Accept: */*\r\n" );<br />
@fputs ( $myHandle, "\r\n\r\n" );<br />
while ( ! feof ( $myHandle ) ) {<br />
$myResult .= fgets ( $myHandle, 128 );<br />
}<br />
@fclose ( $myHandle );<br />
}<br />
}<br />
}<br />
?&gt;</p></blockquote>
<p><strong>第二部分，再看JAVA如何达到这个目的</strong></p>
<blockquote><p>public void flush<a href="http://www.54chen.com/php-tech/%e5%a6%82%e4%bd%95%e7%94%a8php%e4%bb%a3%e7%a0%81%e6%b8%85%e7%a9%basquid%e7%bc%93%e5%ad%98%e4%b8%8b%e7%9a%84%e6%8c%87%e5%ae%9a%e6%96%87%e4%bb%b6.html">Squid</a>() {<br />
try {<br />
int port = 80;<br />
Socket socket = new Socket("127.0.0.1", port);<br />
String path = http://test.com/test.html";<br />
BufferedWriter wr = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));<br />
wr.write("PURGE " + path + " HTTP/1.0\r\n");<br />
wr.write("Accept: */*\r\n");<br />
wr.write("\r\n\r\n");</p>
<p>wr.flush();</p>
<p>// Get response<br />
BufferedReader rd = new BufferedReader(new InputStreamReader(socket.getInputStream()));<br />
String line;<br />
while ((line = rd.readLine()) != null) {<br />
// Process line...<br />
System.out.println(line);<br />
}<br />
wr.close();<br />
rd.close();<br />
} catch (Exception e) {<br />
}<br />
}</p></blockquote>
<p>亲爱的读者，您喜欢用PHP还是JAVA？</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/54-chen-through-php-to-see-java-series-fsockopen.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>五四陈透过PHP看JAVA系列：strtotime</title>
		<link>http://www.54chen.com/php-tech/54-chen-through-php-to-see-java-series-strtotime.html</link>
		<comments>http://www.54chen.com/php-tech/54-chen-through-php-to-see-java-series-strtotime.html#comments</comments>
		<pubDate>Thu, 04 Mar 2010 11:48:20 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[strtotime]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/54-chen-through-php-to-see-java-series-strtotime.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之间的一些异同，给从PHP学JAVA或者是从JAVA学PHP的同学一点启发，五四陈科学院出品。 第一部分，先看PHP的Date/Tme函数 详细见：http://www.54chen.com/p/ref.datetime.html 今天要说的是其中的strtotime函数 http://www.54chen.com/p/function.strtotime.html 函数的功能：接受一个包含美国英语日期格式的字符串并尝试将其解析为 Unix 时间戳（自 January 1 1970 00:00:00 GMT 起的秒数）。 例子： &#60;?php echo strtotime("2010-3-3 3:3:3"); ?&#62; 将得到结果： 1267585383 在PHP应用中，经常在需要记录时间的时候，使用Mysql的int(10)来保存这个 Unix 时间戳，并且时间的比较查找等操作，都用大于小于来进行。 第二部分，看JAVA对应的方法 try { fromUnixTime = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse("01/03/2010 08:00:00").getTime(); fromUnixTime /= 1000; } catch (ParseException &#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之间的一些异同，给从PHP学JAVA或者是从JAVA学PHP的同学一点启发，五四陈科学院出品。</p>
<p><strong>第一部分，先看PHP的Date/Tme函数</strong></p>
<p>详细见：<a href="http://www.54chen.com/p/ref.datetime.html">http://www.54chen.com/p/ref.datetime.html</a></p>
<p>今天要说的是其中的strtotime函数</p>
<p><a href="http://www.54chen.com/p/function.strtotime.html">http://www.54chen.com/p/function.strtotime.html</a></p>
<p>函数的功能：接受一个包含美国英语日期格式的字符串并尝试将其解析为    Unix 时间戳（自 January 1 1970 00:00:00 GMT 起的秒数）。</p>
<p>例子：</p>
<blockquote><p>&lt;?php<br />
echo strtotime("2010-3-3 3:3:3");<br />
?&gt;</p>
<p>将得到结果：</p>
<p>1267585383</p></blockquote>
<p>在PHP应用中，经常在需要记录时间的时候，使用Mysql的int(10)来保存这个   Unix 时间戳，并且时间的比较查找等操作，都用大于小于来进行。</p>
<p><strong>第二部分，看JAVA对应的方法</strong></p>
<blockquote><p>try {<br />
fromUnixTime = <span style="color: #ff0000;"><strong>new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").parse("01/03/2010 08:00:00").getTime();</strong></span><br />
fromUnixTime /= 1000;<br />
} catch (ParseException e1) {<br />
e1.printStackTrace();<br />
}</p></blockquote>
<p>看上去有点麻烦，不过因为java中操作mysql的<a href="http://www.54chen.com/java-ee/jdbc-socketread0-locked-in-mind-a-mysql-unknown-bug.html">jdbc</a>对类型的要求是非常严格的，所以一般在java项目中，不使用int来代替datetime类型的字段。</p>
<p><strong>第三部分，提升部分，反过来咋整（从Unix时间戳格式化为datetime）？</strong></p>
<p>先说PHP：</p>
<blockquote><p>&lt;?php<br />
echo date("Y-m-d H:i:s",1267585383);<br />
?&gt;</p></blockquote>
<p>再说JAVA：</p>
<blockquote><p>String date2 = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date ((<span style="color: #ff6600;">long</span>)1267585383*1000));<br />
System.out.println(date2);</p></blockquote>
<p>注意java中的强转为<a href="http://www.54chen.com/java-ee/java-using-the-bdb-notes-from-berkeley-db-java-api-records.html">long</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/54-chen-through-php-to-see-java-series-strtotime.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>解读PHP开源项目中列表和hook方法：while(has_items()): thme_ite();和apply_filters</title>
		<link>http://www.54chen.com/php-tech/php-open-source-projects-reading-lists-and-hook-methods-while-has_items-thme_ite-and-apply_filters.html</link>
		<comments>http://www.54chen.com/php-tech/php-open-source-projects-reading-lists-and-hook-methods-while-has_items-thme_ite-and-apply_filters.html#comments</comments>
		<pubDate>Mon, 08 Feb 2010 09:23:55 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[开源]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/php-open-source-projects-reading-lists-and-hook-methods-while-has_items-thme_ite-and-apply_filters.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>在wordpress,lilina等开源项目中，常常会看到一些莫名的代码，来无影去无踪，看上去很有意味，特地拿来分析分析，看看一般的作法。 part 1  列表 循环显示 先看代码： &#60;?php $num = 0; if(has_items()) { while(has_items()): the_item(); } ?&#62; 以上代码，出自某开源项目。。。 再进入the_item()函数内部，可以看到一个关键的函数： * Returns the current item * * @since 1.0 * * @return bool&#124;stdClass False if item doesn't exist, otherwise returns the specified &#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>在<a href="http://www.54chen.com/architecture/wordpress-nginx-php-cgi-mysql-memory-in-the-128m-to-install-and-optimize-the-vps-notes.html">wordpress</a>,lilina等开源项目中，常常会看到一些莫名的代码，来无影去无踪，看上去很有意味，特地拿来分析分析，看看一般的作法。</p>
<p><strong>part 1  列表 循环显示</strong></p>
<p>先看代码：</p>
<blockquote><p>&lt;?php<br />
$num = 0;<br />
if(has_items()) {<br />
while(has_items()): the_item();<br />
}<br />
?&gt;</p></blockquote>
<p>以上代码，出自某开源项目。。。</p>
<p>再进入the_item()函数内部，可以看到一个关键的函数：</p>
<blockquote><p>* Returns the current item<br />
*<br />
* @since 1.0<br />
*<br />
* @return bool|stdClass False if item doesn't exist, otherwise returns the specified item<br />
*/<br />
public function current_item() {<br />
$this-&gt;previous_item = $this-&gt;current_item;<br />
$this-&gt;current_item = '';</p>
<p>$item = each($this-&gt;items);<br />
$item = $item['value'];<br />
if(!$item)<br />
return false;</p>
<p>$this-&gt;current_item = $item;<br />
$this-&gt;current_feed = $item-&gt;feed;</p>
<p>return $item;<br />
}</p></blockquote>
<p>这个关键的函数是each()，来看手册：</p>
<h1>each</h1>
<div class="refnamediv"><a name="AEN12322"></a>(PHP 3, PHP 4, PHP 5)</p>
<p>each --       返回数组中当前的<a href="http://www.54chen.com/translate/dynamo-based-systems-designed-linkin-voldemort-voldemort-design-chinese-documents-i-am-a-chan-academy-of-sciences-translation-finalized.html">键／值</a>对并将数组指针向前移动一步</div>
<div class="refsect1"><a name="AEN12325"></a></p>
<h2>说明</h2>
<p>array <strong class="methodname">each</strong> ( array &amp;array )</p>
<p>返回 <var class="parameter">array</var> 数组中当前指针位置的键／值对并向前移动数组指针。键值对被返回为四个单元的数组，键名为      <var class="literal">0</var>，<var class="literal">1</var>，<var class="literal">key</var> 和 <var class="literal">value</var>。单元 <var class="literal">0</var> 和      <var class="literal">key</var> 包含有数组单元的键名，<var class="literal">1</var> 和      <var class="literal">value</var> 包含有数据。</p>
<p>如果内部指针越过了数组的末端，则 <strong class="function">each()</strong> 返回 <tt class="constant"><strong>FALSE</strong></tt>。</p>
<p>综合来看，其实就是一个做了一个游标一样的模型，利用each来操作一个数组或者相似的结构，每次在显示的时候，都有对数据数组的本身操作，而while里的has_item，只是作简单的判断有无而已。</p>
<p><strong>part2 hook</strong></p>
<p>第二种情况，是一个叫apply_filters的函数的<a href="http://www.54chen.com/architecture/wordpress-nginx-php-cgi-mysql-memory-in-the-128m-to-install-and-optimize-the-vps-notes.html">实现</a>。先看代码：</p>
<blockquote><p>function the_item() {<br />
global $lilina_items, $item;</p>
<p>$item = apply_filters('the_item', $lilina_items-&gt;current_item());<br />
}</p></blockquote>
<p>这是lilina里的一个函数，要看的是这个apply_filters方法，有一个简单的例子：</p>
<blockquote><p>function example_hook($string, $arg1, $arg2)<br />
{<br />
//Do stuff<br />
return $string;<br />
}<br />
$value = apply_filters('example_hook', 'filter me', 'arg1', 'arg2');</p></blockquote>
<p>apply_filters里面最关键的一个函数：</p>
<h1>call_user_func_array</h1>
<div class="refnamediv"><a name="AEN50629"></a>(PHP 4 &gt;= 4.0.4, PHP 5)</p>
<p>call_user_func_array --       Call a user function given with an array of parameters</p></div>
<div class="refsect1"><a name="AEN50632"></a></p>
<h2>Description</h2>
<p>mixed <strong class="methodname">call_user_func_array</strong> ( callback function, array param_arr )</p>
<p>Call a user defined function given by      <var class="parameter">function</var>, with      the <a href="http://www.54chen.com/php-tech/multi-nginx-configuration-of-single-php-fpm-approach-from-academy-of-sciences.html">parameters</a> in <var class="parameter">param_arr</var>.</p>
<p>其实这些渐渐被遗忘的<a href="http://www.54chen.com/webfe/academy-of-sciences-in-recent-years-a-good-article-summing-up.html">函数</a>，在高手们的使用下，对项目化的开发很有优势，随手记之。</div>
</div>
<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-open-source-projects-reading-lists-and-hook-methods-while-has_items-thme_ite-and-apply_filters.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP上传文件类型彻底判断方案及PHP＋nginx上传大小彻底控制方案</title>
		<link>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</link>
		<comments>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#comments</comments>
		<pubDate>Wed, 13 Jan 2010 01:06:21 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[上传]]></category>
		<category><![CDATA[大小]]></category>
		<category><![CDATA[类型]]></category>

		<guid isPermaLink="false">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</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 C上传文件如何准确判断文件类型－mime知识普及 本文目的在于，进一步更正前文所述的mime判断方式，以及增加一个nginx环境里的文件上传大小所影响的代码。 上传类型控制： 在我（54chen）工作中发现，其实修改文件的后缀，浏览器就会很傻瓜地传送错误的mime类型，所以前文的判断是一个半错误的方法（除了C代码是正确的）。 网上流传一段PHP读取文件头判断文件类型的方法，有一些bug，经我（54chen）修改实测，应该是这个样子： /** * 读取文件前几个字节 判断文件类型 * * @return String */ function checkTitle($filename) { $file     = fopen($filename, "rb"); $bin      = fread($file, 2); //只读2字节 fclose($file); $strInfo  = @unpack("c2chars", $bin); $typeCode = intval($strInfo['chars1'].$strInfo['chars2']); $fileType = ''; &#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>上回科学院发过一篇讲述上传判断的文章，位置是</p>
<h3><a rel="bookmark" href="../cc/php-java-c-upload-files-how-to-accurately-determine-the-file-type-mime-literacy.html">PHP JAVA C上传文件如何准确判断文件类型－mime知识普及</a></h3>
<p>本文目的在于，进一步更正前文所述的mime判断方式，以及增加一个nginx环境里的文件上传大小所影响的代码。</p>
<p><strong>上传类型控制：</strong></p>
<p>在我（<a href="http://www.54chen.com">54chen</a>）工作中发现，其实修改文件的后缀，浏览器就会很傻瓜地传送错误的<a href="http://www.54chen.com/_linux_/everyone-network-intel-technology-symposium-record.html">mime</a>类型，所以前文的判断是一个半错误的方法（除了C代码是正确的）。</p>
<p>网上流传一段PHP读取文件头判断文件类型的方法，有一些bug，经我（<a href="http://www.54chen.com/php-tech/mediawiki-pgsql.html">54chen</a>）修改实测，应该是这个样子：</p>
<blockquote><p>/**<br />
* 读取文件前几个字节 判断<a href="http://www.54chen.com/webfe/academy-of-sciences-in-recent-years-a-good-article-summing-up.html">文件</a>类型<br />
*<br />
* @return String<br />
*/<br />
function checkTitle($filename) {<br />
$file     = fopen($filename, "rb");<br />
$bin      = fread($file, 2); //只读2字节<br />
fclose($file);<br />
$strInfo  = @unpack("c2chars", $bin);<br />
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);<br />
$fileType = '';<br />
switch ($typeCode)<br />
{<br />
case 7790:<br />
$fileType = 'exe';<br />
break;<br />
case 7784:<br />
$fileType = 'midi';<br />
break;<br />
case 8297:<br />
$fileType = 'rar';<br />
break;<br />
case 255216:<br />
$fileType = 'jpg';<br />
break;<br />
case 7173:<br />
$fileType = 'gif';<br />
break;<br />
case 6677:<br />
$fileType = 'bmp';<br />
break;<br />
case 13780:<br />
$fileType = 'png';<br />
break;<br />
default:<br />
$fileType = 'unknown'.$typeCode;<br />
}<br />
//Fix<br />
if ($strInfo['chars1']=='-1' &amp;&amp; $strInfo['chars2']=='-40' ) {<br />
return 'jpg';<br />
}<br />
if ($strInfo['chars1']=='-119' &amp;&amp; $strInfo['chars2']=='80' ) {<br />
return 'png';<br />
}<br />
return $fileType;<br />
}</p></blockquote>
<p>这代码可以非常正确地分出修改后的文件，从而达到阻止修改后缀名上传的情况。</p>
<p><strong>上传大小控制：</strong></p>
<p>在PHP代码中直接读取$_FILE的size，而如果是特别大的文件，又使用了PHP＋<a href="http://www.54chen.com/architecture/54-chen-skills-the-whole-point-for-domain-names-using-nginx-and-javascript-to-do-a-simple-jump-to-inform-the-friendly-exchange-of-domain-names.html">nginx</a>的话，很有可能，超过2M的文件直接就被nginx就抛出来413错误了。</p>
<p>解决的办法：</p>
<p>修改/etc/nginx/nginx.conf</p>
<p>找到对应域名的<a href="http://www.54chen.com/architecture/wordpress-nginx-php-cgi-mysql-memory-in-the-128m-to-install-and-optimize-the-vps-notes.html">server</a>段：修改client_max_body_size的值，默认是2M。</p>
<p>这样子还不够，如果不修改php.ini里的值，你会发现上传的文件用上面的代码判断类型的时候会出问题。</p>
<p>修改/etc/php.ini</p>
<p>找到upload_max_<a href="http://www.54chen.com/cc/php-java-c-upload-files-how-to-accurately-determine-the-file-type-mime-literacy.html">filesize</a>，修改这个值，默认是2M。</p>
<p>一番折腾，类型和大小的控制基本上就完善了。</p>
<h2><strong><span style="color: #ff0000;">重要PS</span>：</strong></h2>
<p>对于上传文件类型的判断，一直没有太好的办法，即使使用上面的代码，也有办法构造假的图片的（如何构造不再传播），有人使用getimagesize来判断，不失为一种好办法：</p>
<p>if(in_array($attach['ext'], array('jpg', 'jpeg', 'gif', 'png', 'swf', 'bmp')) &amp;&amp; function_exists('getimagesize') &amp;&amp; <a href="mailto:!@getimagesize($target">!@getimagesize($target</a>)) {<br />
    @unlink($target);<br />
    upload_error('post_attachment_ext_notallowed', $attacharray);<br />
   }</p>
<p>摘自dz代码。</p>
<p>函数参考 <a href="http://cn2.php.net/getimagesize">http://cn2.php.net/getimagesize</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-file-types-to-determine-the-complete-program-and-php-nginx-upload-size-and-complete-control-program.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>ubuntu 9.10快速安装nginx+php环境手记[54chen科学院]</title>
		<link>http://www.54chen.com/php-tech/ubuntu-910-quick-install-nginx-php-notes-from-the-environment-54.html</link>
		<comments>http://www.54chen.com/php-tech/ubuntu-910-quick-install-nginx-php-notes-from-the-environment-54.html#comments</comments>
		<pubDate>Thu, 24 Dec 2009 09:17:05 +0000</pubDate>
		<dc:creator>cc0cc</dc:creator>
				<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.54chen.com/php-tech/ubuntu-910-quick-install-nginx-php-notes-from-the-environment-54.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>我(54chen)因为场景需要，特地在ubuntu9.10中安装nginx+php的环境，要快速不要优化，记录如下： sudo apt-get install php5 php5-cgi php5-cli php5-gd php5-curl php5-mysql nginx sudo apt-get install lighttpd spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -u www-data -g www-data -f /usr/bin/php-cgi 上面的操作解读： 1.安装php nginx 2.安装lighttpd，为啥要安装这个，因为他有个spawn-fcgi，因为apt下来的php不是php-fpm。 3.用spawn-fcgi启动php-cgi在9000端口监听。 sudo vim /etc/php5/cgi/php.ini 修改php.ini文件 cgi.fix_pathinfo=1; 这样php-cgi方能正常使用SCRIPT_FILENAME这个变量 sudo &#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>我(<a href="http://www.54chen.com">54chen</a>)因为场景需要，特地在<a href="http://www.54chen.com/_linux_/11-return-ubuntu-910-notes-from-the-hard-disk-installation.html">ubuntu9.10</a>中安装nginx+php的环境，要快速不要优化，记录如下：</p>
<blockquote><p>sudo apt-get install php5 php5-cgi php5-cli php5-gd php5-curl php5-mysql nginx</p>
<p>sudo apt-get install lighttpd</p>
<p>spawn-fcgi -a 127.0.0.1 -p 9000 -C 5 -u www-data -g www-data -f /usr/bin/php-cgi</p></blockquote>
<p>上面的操作解读：</p>
<p>1.安装php nginx</p>
<p>2.安装lighttpd，为啥要安装这个，因为他有个spawn-fcgi，因为apt下来的php不是php-fpm。</p>
<p>3.用spawn-fcgi启动php-cgi在9000端口监听。</p>
<blockquote><p>sudo vim /etc/php5/cgi/php.ini</p>
<p>修改php.ini文件</p>
<p>cgi.fix_pathinfo=1; 这样php-cgi方能正常使用SCRIPT_FILENAME这个变量</p></blockquote>
<p>sudo vim /etc/nginx/sites-enabled/www.54chen.com</p>
<blockquote><p>server {<br />
listen 80; //端口<br />
server_name wiki.54chen.com; //虚拟域名<br />
access_log /var/log/nginx/hwiki.54chen.com.access.log; //访问日志<br />
location / {<br />
root /home/wiki.54chen.com; //size根目录<br />
index index.php;<br />
}<br />
location ~ \.php$ { #php fastcgi的配置<br />
fastcgi_pass 127.0.0.1:9000; #php fastcgi的代理端口与ip<br />
fastcgi_index index.php;<br />
fastcgi_param SCRIPT_FILENAME /home/wiki.54chen.com$fastcgi_script_name; #要处理的php文件的路径<br />
include /etc/nginx/fastcgi_params; #fastcgi的参数文件地址<br />
}<br />
}</p></blockquote>
<p>好，上面的操作就建立了一个<a href="http://www.54chen.com/memo/%e4%b8%80%e5%8f%a5%e8%af%9d%e8%ae%b0%e5%bd%95%e5%a4%87%e5%bf%98.html">虚拟主机</a>，保存好。</p>
<p>sudo killall apache2</p>
<p>杀掉apache，启动nginx.</p>
<p>sudo /etc/init.d/nginx start</p>
<p>大功告成！整个过程不超过十五分钟。呼呼～～</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/ubuntu-910-quick-install-nginx-php-notes-from-the-environment-54.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

