<?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>Computer, Electron and Technology &#187; ruby</title>
	<atom:link href="http://www.donevii.com/post/tag/ruby/feed" rel="self" type="application/rss+xml" />
	<link>http://www.donevii.com</link>
	<description>关注技术、移动互联网以及一切 GEEK &#38; NERD 的事情</description>
	<lastBuildDate>Wed, 21 Dec 2011 10:49:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>PHP5 效率优化</title>
		<link>http://www.donevii.com/post/290.html</link>
		<comments>http://www.donevii.com/post/290.html#comments</comments>
		<pubDate>Sat, 13 Jan 2007 10:53:44 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[doc]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[开发]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[类]]></category>
		<category><![CDATA[缓存]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=290</guid>
		<description><![CDATA[静态调用的成员一定要定义成 static&#160;&#160;(PHP5 ONLY) PHP 5 引入了静态成员的概念，作用和 PHP 4 的函数内部静态变量一致，但前者是作为类的成员来使用。静态变量和 Ruby 的类变量(class variable)... ]]></description>
			<content:encoded><![CDATA[<p><strong><font color="#0000ff" size="2">静态调用的成员一定要定义成 static&nbsp;&nbsp;(<a href="http://www.donevii.com/post/tag/php" class="st_tag internal_tag" rel="tag" title="Posts tagged with php">PHP</a>5 ONLY)</font></strong></p>
<p>PHP 5 引入了静态成员的概念，作用和 PHP 4 的函数内部静态变量一致，但前者是作为类的成员来使用。静态变量和 <a href="http://www.donevii.com/post/tag/ruby" class="st_tag internal_tag" rel="tag" title="Posts tagged with ruby">Ruby</a> 的类变量(<a href="http://www.donevii.com/post/tag/class" class="st_tag internal_tag" rel="tag" title="Posts tagged with class">class</a> variable)差不多，所有类的实例共享同一个静态变量。</p>
<p><font face="Courier New"><font color="#008080">&lt;?php<br /></font><font color="#0000ff">class </font><font color="#008080">foo </font></font><font face="Courier New"><font color="#0000ff">{<br />&nbsp; &nbsp; function </font><font color="#008080">bar</font></font><font face="Courier New"><font color="#0000ff">() {<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;echo </font><font color="#008000">&#8216;foobar&#8217;</font></font><font face="Courier New"><font color="#0000ff">;<br />&nbsp; &nbsp; }<br />}</p>
<p></font><font color="#008080">$foo </font><font color="#0000ff">= new </font><font color="#008080">foo</font></font><font face="Courier New" color="#0000ff">;</p>
<p></font><font face="Courier New"><font color="#808080">// instance way</p>
<p></font><font color="#008080">$foo</font><font color="#0000ff">-&gt;</font><font color="#008080">bar</font></font><font face="Courier New" color="#0000ff">();</p>
<p></font><font face="Courier New"><font color="#808080">// static way</p>
<p></font><font color="#008080">foo</font><font color="#0000ff">::</font><font color="#008080">bar</font></font><font face="Courier New"><font color="#0000ff">();<br /></font><font color="#008080">?&gt;</font></p>
<p></font>静态地调用非 static 成员，效率会比静态地调用 static 成员慢 50-60%。主要是因为前者会产生 E_STRICT 警告，内部也需要做转换。</p>
<p><strong><font color="#0000ff">使用类常量 (PHP5 ONLY)</font></strong></p>
<p>PHP 5 新功能，类似于 C++ 的 const。</p>
<p>使用类常量的好处是：</p>
<p>- 编译时解析，没有额外开销<br />- 杂凑表更小，所以内部查找更快<br />- 类常量仅存在于特定「命名空间」，所以杂凑名更短<br />- 代码更干净，使除错更方便</p>
<p><strong><font color="#0000ff">(暂时)不要使用 require/include_once</font></strong></p>
<p>require/include_once 每次被调用的时候都会打开目标文件！</p>
<p>- 如果用绝对路径的话，PHP 5.2/6.0 不存在这个问题<br />- 新版的 APC 缓存系统已经解决这个问题</p>
<p>文件 I/O 增加 =&gt; 效率降低</p>
<p>如果需要，可以自行检查文件是否已被 require/include。</p>
<p><strong><font color="#0000ff">不要调用毫无意义的函数</font></strong></p>
<p>有对应的常量的时候，不要使用函数。</p>
<p><font face="Courier New"><font color="#008080">&lt;?php<br />php_uname</font><font color="#0000ff">(</font><font color="#008000">&#8216;s&#8217;</font><font color="#0000ff">) == </font><font color="#008080">PHP_OS</font></font><font face="Courier New"><font color="#0000ff">;<br /></font><font color="#008080">php_version</font><font color="#0000ff">() == </font><font color="#008080">PHP_VERSION</font></font><font face="Courier New"><font color="#0000ff">;<br /></font><font color="#008080">php_sapi_name</font><font color="#0000ff">() == </font><font color="#008080">PHP_SAPI</font></font><font face="Courier New"><font color="#0000ff">;<br /></font><font color="#008080">?&gt;</font><br /></font>虽然使用不多，但是效率提升大概在 3500% 左右。</p>
<p><strong><font color="#0000ff">最快的 Win32 检查</font></strong></p>
<p><font face="Courier New"><font color="#008080">&lt;?php<br />$is_win </font><font color="#0000ff">= </font><font color="#008080">DIRECTORY_SEPARATOR </font><font color="#0000ff">== &#8216;\\&#8217;</font></font><font face="Courier New"><font color="#008080">;<br />?&gt;</font></p>
<p></font>- 不用函数<br />- Win98/NT/2000/XP/Vista/Longhorn/Shorthorn/Whistler&#8230;通用<br />- 一直可用</p>
<p><strong><font color="#ffa500">时间问题 (PHP&gt;5.1.0 ONLY)</font></strong></p>
<p>你如何在你的软件中得知现在的时间？简单，「time() time() again, you ask me&#8230;」。</p>
<p>不过总归会调用函数，慢。</p>
<p>现在好了，用 $_<a href="http://www.donevii.com/post/tag/server" class="st_tag internal_tag" rel="tag" title="Posts tagged with server">SERVER</a>['REQUEST_TIME']，不用调用函数，又省了。</p>
<p><strong><font color="#0000ff">加速 PCRE</font></strong></p>
<p>&nbsp;对于不用保存的结果，不用 ()，一律用 (?:)</p>
<p>这样 PHP 不用为符合的内容分配内存，省。效率提升 15% 左右。</p>
<p>- 能不用正则，就不用正则，在分析的时候仔细阅读手册「字符串函数」部分。有没有你漏掉的好用的函数？</p>
<p><strong><font color="#0000ff">加速 strtr</font></strong></p>
<p>如果需要转换的全是单个字符的时候，用字符串而不是数组来做 strtr：</p>
<p><font face="Courier New"><font color="#008080">&lt;?php<br />$addr </font><font color="#0000ff">= </font><font color="#008080">strtr</font><font color="#0000ff">(</font><font color="#008080">$addr</font><font color="#0000ff">, </font><font color="#008000">&quot;abcd&quot;</font><font color="#0000ff">, </font><font color="#008000">&quot;efgh&quot;</font><font color="#0000ff">); </font></font><font face="Courier New"><font color="#808080">// good<br /></font><font color="#008080">$addr </font><font color="#0000ff">= </font><font color="#008080">strtr</font><font color="#0000ff">(</font><font color="#008080">$addr</font><font color="#0000ff">, array(</font><font color="#008000">&#8216;a&#8217; </font><font color="#0000ff">=&gt; </font><font color="#008000">&#8216;e&#8217;</font></font><font face="Courier New" color="#0000ff">,<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;</font><font face="Courier New"><font color="#808080">// &#8230;<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;</font><font color="#0000ff">)); </font></font><font face="Courier New"><font color="#808080">// bad<br /></font><font color="#008080">?&gt;</font></font><br />效率提升：10 倍。</p>
<p><strong><font color="#ffa500">不要做无谓的替换</font></strong></p>
<p>即使没有替换，str_replace 也会为其参数分配内存。很慢！解决办法：</p>
<p>- 用 strpos 先查找(非常快)，看是否需要替换，如果需要，再替换</p>
<p>效率：</p>
<p>- 如果需要替换：效率几乎相等，差别在 0.1% 左右。<br />- 如果不需要替换：用 strpos 快 200%。</p>
<p><strong><font color="#0000ff">邪恶的 @ 操作符</font></strong></p>
<p>不要滥用 @ 操作符。虽然 @ 看上去很简单，但是实际上后台有很多操作。用 @ 比起不用 @，效率差距：3 倍。</p>
<p>特别不要在循环中使用 @，在 5 次循环的测试中，即使是先用 error_reporting(0) 关掉错误，在循环完成后再打开，都比用 @ 快。</p>
<p><strong><font color="#0000ff">善用 strncmp</font></strong></p>
<p>当需要对比「前 n 个字符」是否一样的时候，用 strncmp/strncasecmp，而不是 substr/strtolower，更不是 PCRE，更千万别提 ereg。strncmp/strncasecmp 效率最高(虽然高得不多)。</p>
<p><strong><font color="#0000ff">慎用 substr_compare (PHP5 ONLY)</font></strong></p>
<p>按照上面的道理，substr_compare 应该比先 substr 再比较快咯。答案是否定的，除非：</p>
<p>- 无视大小写的比较<br />- 比较较大的字符串</p>
<p><strong><font color="#0000ff">不要用常量代替字符串</font></strong></p>
<p>为什么：</p>
<p>- 需要查询杂凑表两次<br />- 需要把常量名转换为小写(进行第二次查询的时候)<br />- 生成 E_NOTICE 警告<br />- 会建立临时字符串</p>
<p>效率差别：700%。</p>
<p><strong><font color="#0000ff">不要把 count/strlen/sizeof 放到 for 循环的条件语句中</font></strong></p>
<p>贴士：我的个人做法</p>
<p><font face="Courier New"><font color="#008080">&lt;?php<br /></font><font color="#0000ff">for (</font><font color="#008080">$i </font><font color="#0000ff">= </font><font color="#008080">0</font><font color="#0000ff">, </font><font color="#008080">$max </font><font color="#0000ff">= </font><font color="#008080">count</font><font color="#0000ff">(</font><font color="#008080">$array</font><font color="#0000ff">);</font><font color="#008080">$i </font><font color="#0000ff">&lt; </font><font color="#008080">$max</font><font color="#0000ff">; ++</font><font color="#008080">$i</font></font><font face="Courier New"><font color="#0000ff">);<br /></font><font color="#008080">?&gt;</font></font></p>
<p>效率提升相对于：</p>
<p>- count 50%<br />- strlen 75%</p>
<p><strong><font color="#ffa500">短的代码不一定快</font></strong></p>
<p><font face="Courier New" color="#008080">&lt;?php<br /></font><font face="Courier New"><font color="#808080">// longest<br /></font><font color="#0000ff">if (</font><font color="#008080">$a </font><font color="#0000ff">== </font><font color="#008080">$b</font></font><font face="Courier New"><font color="#0000ff">) {<br />&nbsp; &nbsp; </font><font color="#008080">$str </font><font color="#0000ff">.= </font><font color="#008080">$a</font></font><font face="Courier New"><font color="#0000ff">;<br />} else {<br />&nbsp; &nbsp; </font><font color="#008080">$str </font><font color="#0000ff">.= </font><font color="#008080">$b</font></font><font color="#0000ff"><font face="Courier New">;<br />}</font><br /></font><font face="Courier New"><font color="#808080">// longer<br /></font><font color="#0000ff">if (</font><font color="#008080">$a </font><font color="#0000ff">== </font><font color="#008080">$b</font></font><font face="Courier New"><font color="#0000ff">) {<br />&nbsp; &nbsp; </font><font color="#008080">$str </font><font color="#0000ff">.= </font><font color="#008080">$a</font></font><font face="Courier New"><font color="#0000ff">;<br />}<br /></font><font color="#008080">$str </font><font color="#0000ff">.= </font><font color="#008080">$b</font></font><font face="Courier New" color="#0000ff">;</p>
<p></font><font face="Courier New"><font color="#808080">// short<br /></font><font color="#008080">$str </font><font color="#0000ff">.= (</font><font color="#008080">$a </font><font color="#0000ff">== </font><font color="#008080">$b </font><font color="#0000ff">? </font><font color="#008080">$a </font><font color="#0000ff">: </font><font color="#008080">$b</font></font><font face="Courier New"><font color="#0000ff">);<br /></font><font color="#008080">?&gt;</font></font><br />你觉得哪个快？</p>
<p>效率比较：</p>
<p>- longest: 4.27<br />- longer: 4.43<br />- short: 4.76</p>
<p>不可思议？再来一个：<br /><font face="Courier New" color="#008080">&lt;?php<br /></font><font face="Courier New"><font color="#808080">// original<br /></font><font color="#008080">$d </font><font color="#0000ff">= </font><font color="#008080">dir</font><font color="#0000ff">(</font><font color="#008000">&#8216;.&#8217;</font></font><font face="Courier New"><font color="#0000ff">);<br />while ((</font><font color="#008080">$entry </font><font color="#0000ff">= </font><font color="#008080">$d</font><font color="#0000ff">-&gt;</font><font color="#008080">read</font><font color="#0000ff">()) !== </font><font color="#008080">false</font></font><font face="Courier New"><font color="#0000ff">) {<br />&nbsp; &nbsp; if (</font><font color="#008080">$entry </font><font color="#0000ff">== </font><font color="#008000">&#8216;.&#8217; </font><font color="#0000ff">|| </font><font color="#008080">$entry </font><font color="#0000ff">== </font><font color="#008000">&#8216;..&#8217;</font></font><font face="Courier New" color="#0000ff">) {<br />&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;continue;<br />&nbsp; &nbsp; }<br />}</p>
<p></font><font face="Courier New"><font color="#808080">// versus<br /></font><font color="#008080">glob</font><font color="#0000ff">(</font><font color="#008000">&#8216;./*&#8217;</font></font><font face="Courier New" color="#0000ff">);</p>
<p></font><font face="Courier New"><font color="#808080">// versus (include . and ..)<br /></font><font color="#008080">scandir</font><font color="#0000ff">(</font><font color="#008000">&#8216;.&#8217;</font></font><font face="Courier New"><font color="#0000ff">);<br /></font><font color="#008080">?&gt;</font></font><br />哪个快？</p>
<p>效率比较：</p>
<p>- original: 3.37<br />- glob: 6.28<br />- scandir: 3.42<br />- original without OO: 3.14<br />- SPL (PHP5): 3.95</p>
<p>画外音：从此也可以看出来 PHP5 的面向对象效率提高了很多，效率已经和纯函数差得不太多了。</p>
<p><strong><font color="#0000ff">提高 PHP 文件访问效率</font></strong></p>
<p>需要包含其他 PHP 文件的时候，使用完整路径，或者容易转换的相对路径。</p>
<p><font face="Courier New"><font color="#008080">&lt;?php</p>
<p></font><font color="#0000ff">include </font><font color="#008000">&#8216;file.php&#8217;</font><font color="#0000ff">; </font></font><font face="Courier New"><font color="#808080">// bad approach</p>
<p></font><font color="#008080">incldue </font><font color="#008000">&#8216;./file.php&#8217;</font><font color="#0000ff">; </font></font><font face="Courier New"><font color="#808080">// good</p>
<p></font><font color="#0000ff">include </font><font color="#008000">&#8216;/path/to/file.php&#8217;</font><font color="#0000ff">; </font></font><font face="Courier New"><font color="#808080">// ideal</p>
<p></font><font color="#008080">?&gt;</font></font></p>
<p><strong><font color="#0000ff">物尽其用</font></strong></p>
<p>PHP 有很多扩展和函数可用，在实现一个功能的之前，应该看看 PHP 是否有了这个功能？是否有更简单的实现？</p>
<p><font face="Courier New"><font color="#008080">&lt;?php<br />$filename </font><font color="#0000ff">= </font><font color="#008000">&quot;./somepic.gif&quot;</font></font><font face="Courier New"><font color="#0000ff">;<br /></font><font color="#008080">$handle </font><font color="#0000ff">= </font><font color="#008080">fopen</font><font color="#0000ff">(</font><font color="#008080">$filename</font><font color="#0000ff">, </font><font color="#008000">&quot;rb&quot;</font></font><font face="Courier New"><font color="#0000ff">);<br /></font><font color="#008080">$contents </font><font color="#0000ff">= </font><font color="#008080">fread</font><font color="#0000ff">(</font><font color="#008080">$handle</font><font color="#0000ff">, </font><font color="#008080">filesize</font><font color="#0000ff">(</font><font color="#008080">$filename</font></font><font face="Courier New"><font color="#0000ff">));<br /></font><font color="#008080">fclose</font><font color="#0000ff">(</font><font color="#008080">$handle</font></font><font face="Courier New" color="#0000ff">);</p>
<p></font><font face="Courier New"><font color="#808080">// vs. much simpler</p>
<p></font><font color="#008080">file_get_contents</font><font color="#0000ff">(</font><font color="#008000">&#8216;./somepic.gif&#8217;</font></font><font face="Courier New"><font color="#0000ff">);<br /></font><font color="#008080">?&gt;</font></font></p>
<p><strong><font color="#ffa500">关于引用的技巧</font></strong></p>
<p>引用可以：</p>
<p>- 简化对复杂结构数据的访问<br />- 优化内存使用<br /><font face="Courier New"><font color="#008080">&lt;?php<br />$a</font><font color="#0000ff">[</font><font color="#008000">'b'</font><font color="#0000ff">][</font><font color="#008000">'c'</font></font><font face="Courier New" color="#0000ff">] = array();</p>
<p></font><font face="Courier New"><font color="#808080">// slow 2 extra hash lookups per access<br /></font><font color="#0000ff">for (</font><font color="#008080">$i </font><font color="#0000ff">= </font><font color="#008080">0</font><font color="#0000ff">; </font><font color="#008080">$i </font><font color="#0000ff">&lt; </font><font color="#008080">5</font><font color="#0000ff">; ++</font><font color="#008080">$i</font></font><font face="Courier New"><font color="#0000ff">)<br />&nbsp; &nbsp; </font><font color="#008080">$a</font><font color="#0000ff">[</font><font color="#008000">'b'</font><font color="#0000ff">][</font><font color="#008000">'c'</font><font color="#0000ff">][</font><font color="#008080">$i</font><font color="#0000ff">] = </font><font color="#008080">$i</font></font><font face="Courier New" color="#0000ff">;</p>
<p></font><font face="Courier New"><font color="#808080">// much faster reference based approach<br /></font><font color="#008080">$ref </font><font color="#0000ff">=&amp; </font><font color="#008080">$a</font><font color="#0000ff">[</font><font color="#008000">'b'</font><font color="#0000ff">][</font><font color="#008000">'c'</font></font><font face="Courier New"><font color="#0000ff">];<br />for (</font><font color="#008080">$i </font><font color="#0000ff">= </font><font color="#008080">0</font><font color="#0000ff">; </font><font color="#008080">$i </font><font color="#0000ff">&lt; </font><font color="#008080">5</font><font color="#0000ff">; ++</font><font color="#008080">$i</font></font><font face="Courier New"><font color="#0000ff">)<br />&nbsp; &nbsp; </font><font color="#008080">$ref</font><font color="#0000ff">[</font><font color="#008080">$i</font><font color="#0000ff">] = </font><font color="#008080">$i</font></font><font face="Courier New"><font color="#0000ff">;<br /></font><font color="#008080">?&gt;</font></font><br /><font face="Courier New"><font color="#008080">&lt;?php<br />$a </font><font color="#0000ff">= </font><font color="#008000">&#8216;large string&#8217;</font></font><font face="Courier New" color="#0000ff">;</p>
<p></font><font face="Courier New"><font color="#808080">// memory intensive approach<br /></font><font color="#0000ff">function </font><font color="#008080">a</font><font color="#0000ff">(</font><font color="#008080">$str</font></font><font face="Courier New"><font color="#0000ff">)<br />{<br />&nbsp; &nbsp; return </font><font color="#008080">$str</font><font color="#0000ff">.</font><font color="#008000">&#8216;something&#8217;</font></font><font face="Courier New" color="#0000ff">;<br />}</p>
<p></font><font face="Courier New"><font color="#808080">// more efficient solution<br /></font><font color="#0000ff">function </font><font color="#008080">a</font><font color="#0000ff">(&amp;</font><font color="#008080">$str</font></font><font face="Courier New"><font color="#0000ff">)<br />{<br />&nbsp; &nbsp; </font><font color="#008080">$str </font><font color="#0000ff">.= </font><font color="#008000">&#8216;something&#8217;</font></font><font face="Courier New"><font color="#0000ff">;<br />}<br /></font><font color="#008080">?&gt;</font></font><br />==============================================<br />参考资料<br /><a href="http://ilia.ws/" target="_blank" snap_preview_added="spa">http://ilia.ws</a></p>
<p>Ilia 的个人网站，<a href="http://www.donevii.com/post/tag/blog" class="st_tag internal_tag" rel="tag" title="Posts tagged with blog">Blog</a>，他参与的开发以及出版的一些稿物链接等等。<br /><a href="http://ez.no/" target="_blank" snap_preview_added="spa">http://ez.no</a></p>
<p>eZ components 官方网站，eZ comp 是针对 PHP5 的开源通用库，以效率为己任，Ilia 也参与了开发。<br /><a href="http://phparch.com/" target="_blank" snap_preview_added="spa">http://phparch.com</a></p>
<p>php|architect，不错的 php 出版商/培训组织。买不起或者买不到的话，网上可以下到很多经典的盗版。</p>
<p><a href="http://talks.php.net/" target="_blank" snap_preview_added="spa">http://talks.php.net</a></p>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/290.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP On Rails</title>
		<link>http://www.donevii.com/post/240.html</link>
		<comments>http://www.donevii.com/post/240.html#comments</comments>
		<pubDate>Fri, 08 Dec 2006 09:53:48 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[开发]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=240</guid>
		<description><![CDATA[这两天看了几本 Ruby On Rails 的书，后来在网上搜索时发现原来 PHP 也有 Rails 的东西，比如 Symfony、CakePHP 和国人开发的 FleaPHP 都很不错。 ：） 不过因为封装得太多了，以至于程序运行效率有些... ]]></description>
			<content:encoded><![CDATA[<p>这两天看了几本 <a href="http://www.donevii.com/post/tag/ruby" class="st_tag internal_tag" rel="tag" title="Posts tagged with ruby">Ruby</a> On Rails 的书，后来在网上搜索时发现原来 <a href="http://www.donevii.com/post/tag/php" class="st_tag internal_tag" rel="tag" title="Posts tagged with php">PHP</a> 也有 Rails 的东西，比如 Symfony、CakePHP 和国人开发的 FleaPHP 都很不错。</p>
<p>：）</p>
<p>不过因为封装得太多了，以至于程序运行效率有些下降，但是比起其它的语言还是很快。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/240.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>各系Rails大点兵</title>
		<link>http://www.donevii.com/post/232.html</link>
		<comments>http://www.donevii.com/post/232.html#comments</comments>
		<pubDate>Mon, 27 Nov 2006 16:22:20 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=232</guid>
		<description><![CDATA[不知道明年今日，会不会出现一队只会用Ruby On Rails的毕业生，像当年的asp、jsp、php迅速剿了C++/perl的CGI那样，把我们给剿了。同好们劝我，根据大公司经济学，这基本不会发生。 在茫茫的框架... ]]></description>
			<content:encoded><![CDATA[<p>不知道明年今日，会不会出现一队只会用Ruby On Rails的毕业生，像当年的asp、jsp、php迅速剿了C++/perl的CGI那样，把我们给剿了。同好们劝我，根据大公司经济学，这基本不会发生。</p>
<p>在茫茫的框架之海认出一个Rails框架，基本上靠四个特征<br />1.一门动态语言<br />2.一个extreme simple to use的ORM框架<br />3.一个extreme simple to use的MVC框架<br />4.一些自动生成代码的命令、模版<br />其余ajax、<a href="http://www.donevii.com/post/tag/web" class="st_tag internal_tag" rel="tag" title="Posts tagged with web">web</a> service、i18n等特性自由扩展</p>
<p>1.<a href="http://www.donevii.com/post/tag/ruby" class="st_tag internal_tag" rel="tag" title="Posts tagged with ruby">Ruby</a>: <a href="http://www.donevii.com/post/tag/ruby" class="st_tag internal_tag" rel="tag" title="Posts tagged with ruby">Ruby</a> on Rails<br />Rails系的旗手，一己之力搞得J2EE阵营鸡飞蛋打。<br />旗手的作用表现在：<br />*最接近1.0的版本，目前已出到最后一个RC版 1.0 rc4(0.14.3)<br />*拥有一本amazon超级畅销的《Agile Web Development with Rails》，而且这本书的组织也好，part I是一个渐进的sample application 让你快速入门，partII是几个重要领域的深入介绍。<br />*拥有自己的IDE: RadRails ，基于Eclipse但独立成军，目前出到0.5。(是不是怕惨了Eclipse的多变，现在这些IDE的发行版本开始反包含了Eclipse在内。)</p>
<p>2.<a href="http://www.donevii.com/post/tag/python" class="st_tag internal_tag" rel="tag" title="Posts tagged with python">Python</a>: DJango、turbogears<br />认识不深，所以DJango请看limodou的blog，turbogears看xlp123的。</p>
<p>3.Groovy: grails<br />如果能顺产，绝对是J2EE阵营里感情分最高涨的项目。因为它语言用Groovy，ORM用annotation版Hibernate，MVC用Spring。不用担心它换汤不换药，因为经过extreme的封装，再结合Groovy，绝对不再是原来的Spring+Hibernate，而是和RoR差不多的一样东西了。不信可以看看他的Sample。<br />不过这个项目的源码目录树非一般的乱，也还没有0.1版释出。还有一样奇怪的事情，这个Groovy项目，大多数的class代码都是Java写的。</p>
<p>4.<a href="http://www.donevii.com/post/tag/php" class="st_tag internal_tag" rel="tag" title="Posts tagged with php">Php</a>: symfony ,cake<br />据说cake比symfony弱非常多，所以没看。<br />symfonys是基于php5的项目，成功整合了Propel(ORM)、Mojavi3(MVC)，再配合自动生成的脚本打造而成。看他的sample，最后整合出来的东西也很Rails了，除了ORM层的xml文件。<br />还有一个发现是Php项目现在可以用pear来安装，很像Ruby的gem，Java的Maven要努力了。<br />C: />pear channel-discover pear.symfony-project.com <br />C: />pear install symfony/symfony<br />这样就装完了symfonys和propel&amp;croel, mojavi3,还有用来运行脚本命令的pake(php make)，PHing(php ant?)，一大堆东西。</p>
<p>from :http://www.blogjava.net/calvin/archive/2005/11/22/20938.<a href="http://www.donevii.com/post/tag/html" class="st_tag internal_tag" rel="tag" title="Posts tagged with html">html</a><br />author:江南白衣  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/232.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails RESTful (1) 什麼是REST?</title>
		<link>http://www.donevii.com/post/231.html</link>
		<comments>http://www.donevii.com/post/231.html#comments</comments>
		<pubDate>Mon, 27 Nov 2006 15:59:16 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[server]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=231</guid>
		<description><![CDATA[Ruby on Rails 1.2 的一個重要進展是 RESTful，在了解怎麼用之前，我們要先了解什麼是 REST(Representational State Transfer)? 什麼是REST? REST 是一種分散式超媒體系統(如WWW)的軟體架構風格，你可以想像它是... ]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.donevii.com/post/tag/ruby" class="st_tag internal_tag" rel="tag" title="Posts tagged with ruby">Ruby</a> on Rails 1.2 的一個重要進展是 RESTful，在了解怎麼用之前，我們要先了解什麼是 REST(Representational State Transfer)?</p>
<p>什麼是REST?</p>
<p>REST 是一種分散式超媒體系統(如WWW)的軟體架構風格，你可以想像它是一個良好設計的Web應用程式規則: 一組網路Web頁面(虛擬的狀態機器)，其中 Client 透過點選超連結(狀態變換)，結果是下個Web頁面(表示應用程式的下一個狀態)。</p>
<p>REST 所描述的網路系統包括三個部份:<br />data elements (resource, resource identifier, representation)<br />connectors (client, <a href="http://www.donevii.com/post/tag/server" class="st_tag internal_tag" rel="tag" title="Posts tagged with server">server</a>, <a href="http://www.donevii.com/post/tag/cache" class="st_tag internal_tag" rel="tag" title="Posts tagged with cache">cache</a>, resolver, tunnel)<br />components (origin server, gateway, proxy, user agent)</p>
<p>幾個重點:<br />Data elements 由標準化介面存取<br />Components 透過介面傳輸 資源表徵 (representations of resources) 來溝通，而不是直接操作資源本身。<br />Connectors 提供 component 的抽象介面來溝通，隱藏溝通機制的實作細節。<br />Components 使用 connectors 來存取，connectors 提供資源的存取或居中。<br />所有來自 connector 的 requests 必須包含所有必要的資訊來了解該 request，不需要依靠之前的request (即 stateless)</p>
<p>嚴格來說REST符合以下幾個條件:<br />應用程式的狀態跟功能拆成 resources<br />每個 resource 使用獨一無二用來當作超連結的通用定位語法(在WWW中即URI)<br />所有 resources 共用一致的介面在 client 跟 resource 之間轉換狀態，包括:<br />一組有限的良好定義操作 well-defined operations<br />一組有限的內容格式 content types,也許包括 可執行的程式碼 code-on-demand (在WWW中即Javascript)<br />這種通訊協定 protocol (在WWW中即用HTTP) 包含以下特色: <br />使用者端/伺服器端 Client/Server<br />狀態無關 Stateless<br />可以快取 Cacheable<br />分層的 Layered</p>
<p>符合 REST principles 的系統稱做 RESTful。 </p>
<p>一般來說REST這個詞彙常被用來描述任何使用XML (or YAML, JSON, plain text) 的簡單介面，而不須靠其他機制(如SOAP)。另外 REST 雖然是個來自 WWW 的架構概念(比WWW晚)，但是這兩者並不是綁在一起，有可能設計一個大型軟體系統符合REST但是不用HTTP協定也不需跟WWW互動，也有可能設計一個簡單的 XML+HTTP 界面使用 RPC model 而不符合 REST principles。</p>
<p>Resources</p>
<p>REST的一個最重要的觀念就是 resources (特定資訊的資源)，每一個 resource 由一個 global identifier (即URI)所表示。為了操作這些  resources，網路的 components (即 clients 跟servers) 透過標準化的介面 (即HTTP) 來溝通並交換這些 resources 的 representations (即實際上傳達資訊的文件).</p>
<p>任意數量的 connectors (如clients, servers, caches, tunnels等) 可以居中 request，但是都不可以 &ldquo;seeing past&rdquo; (不需要其他 layer層)。這樣的應用程式跟一個 resource 互動根據兩件事情: resource的URI 跟 要做的動作  &ndash; 它不需要知道是否有  caches, proxies, gateways, firewalls, tunnels, 或其他任何藏在sever之間的東西。這個應用程式只需要知道資訊的格式 (representation)，通常是 HTML或 XML 或圖片什麼的。</p>
<p>REST 有什麼優點?<br />支援快取 caching 將改善反應時間跟server的負載能力。<br />因為不必維持連結狀態，大大改善 server 的 scalability 能力。這表示不同server可以處理同一串 requests。<br />一個瀏覽器就可以存取任一應用程式跟資源，client 端不需使用別的軟體。<br />在HTTP之上不依存其他機制跟軟體。<br />跟其他連結方式相比(如RPC)，可以提供相等的功能。<br />不需要其他的 discovery 機制，因為使用超連結了。<br />提供比RPC更好的長期相容性，因為 :<br />如同HTML這種文件具有後前及向後的相容能力<br />支援新的內容格式不需要丟掉舊的</p>
<p>另外比起RPC-style，URL command line 有極佳的 human-friendly 優點，容易 discovered/ transmitted /scripted/bookmarked 一個 URL。請參考 The Beauty of REST 跟 Tangled in the Threads 的優點介紹。</p>
<p>跟 RPC 的比較</p>
<p>跟 REST <a href="http://www.donevii.com/post/tag/web" class="st_tag internal_tag" rel="tag" title="Posts tagged with web">Web</a> 應用程式對比的就是 RPC (Remote procedure call，實作上有XML-RPC或SOAP等) 了。RPC 應用程式曝露一或多個網路物件，每個有特定的 functions 可以呼叫。在 client 與物件溝通之前，它必須知道這個物件的知識來操作。</p>
<p>REST 的設計限制了 resource 的面向，它定義了介面  (動詞 verbs 跟內容型別 content types)，導致比RPC更少的型別，但是更多的resource identifiers (名詞nouns)。REST 的設計尋求定義一組 resources 讓 Clients 可以一致性的互動，而且提供超連結在資源之間可以瀏覽，而不需要了解整個 resources 的知識 。Server 提供的表單 forms 也可以被用在 RESTful 的環境來描述 clients 如何建構 URL 來跟特定的resource做溝通。</p>
<p>這張圖指出了REST的三位一體 : Nouns, 有限的 Verbs 跟 Content Types。</p>
<p>需注意的是，根據不同的用法要求跟效率，在不同的應用程式環境中，該使用哪種架構仍有很大討論的空間跟爭議(SOAP的支持者認為REST仍有其侷限，只適合簡單的應用)。REST的重要性在於它有個目前最成功的大型軟體架構應用: Wide World Web。RESTful 是 Web 的天性，也是讓 Web 成功的原因，因此 RESTful 的支持者認為使用 RESTful 架構就是 Web上最好的方法來做到有擴充性(scalable),彈性跟有威力的應用程式。在有這麼多複雜的RPC技術之後，REST因其簡單又有威力的架構近來越來越受到矚目跟重視。</p>
<p>舉例</p>
<p>一個 RPC 應用程式可能會定義以下的操作:</p>
<p>getUser()<br />addUser()<br />removeUser()<br />updateUser()<br />getLocation()<br />addLocation()<br />removeLocation()<br />updateLocation()<br />listUsers()<br />listLocations()<br />findLocation()<br />findUser()</p>
<p>Client 的程式碼可能會這樣存取:</p>
<p>exampleAppObject = new ExampleApp(&rdquo;example.com:1234&Prime;)<br />exampleAppObject.getUser()</p>
<p>在 REST中，重點在 resources(或稱作 nouns)的多樣性，比如說可能有以下的用法:</p>
<p>http://example.com/users/<br />http://example.com/users/{user} (one for each user)<br />http://example.com/findUserForm<br />http://example.com/locations/<br />http://example.com/locations/{location} (one for each location)<br />http://example.com/findLocationForm</p>
<p>Client 的程式碼可能這樣存取:</p>
<p>userResource = new Resource(http://example.com/users/001)<br />userResource.get()</p>
<p>每個 resource 擁有自己的識別名詞，而 Clients 從單一 resource 開始瀏覽，透過標準操作走訪 resource ，如 GET 下載，PUT更新，DELETE刪除，POST新增，注意到每個物件有自己的URL，而且可以容易被快取，複製跟書籤化(bookmarked)。</p>
<p>參考資源<br />Representational State Transfer<br />RestWiki<br />How to Create a REST Protocol</p>
<p>From :http://ihower.idv.tw/<a href="http://www.donevii.com/post/tag/blog" class="st_tag internal_tag" rel="tag" title="Posts tagged with blog">blog</a>/archives/1542 </p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/231.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP &amp; memcached</title>
		<link>http://www.donevii.com/post/204.html</link>
		<comments>http://www.donevii.com/post/204.html#comments</comments>
		<pubDate>Wed, 15 Nov 2006 07:54:17 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[测试]]></category>
		<category><![CDATA[类]]></category>
		<category><![CDATA[缓存]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=204</guid>
		<description><![CDATA[一、memcached 简介 在很多场合，我们都会听到 memcached 这个名字，但很多同学只是听过，并没有用过或实际了解过，只知道它是一个很不错的东东。这里简单介绍一下，memcached 是高效、快速的分... ]]></description>
			<content:encoded><![CDATA[<p><strong>一、memcached 简介</strong></p>
<p>在很多场合，我们都会听到 <a href="http://www.danga.com/memcached/">memcached</a> 这个名字，但很多同学只是听过，并没有用过或实际了解过，只知道它是一个很不错的东东。这里简单介绍一下，memcached 是高效、快速的分布式内存对象缓存系统，主要用于加速 <a href="http://www.donevii.com/post/tag/web" class="st_tag internal_tag" rel="tag" title="Posts tagged with web">WEB</a> 动态应用程序。</p>
<p><strong>二、memcached 安装</strong></p>
<p>首先是下载 memcached 了，目前最新版本是 1.1.12，直接从官方网站即可下载到 <a href="http://www.danga.com/memcached/dist/memcached-1.1.12.tar.gz">memcached-1.1.12.tar.gz</a>。除此之外，memcached 用到了 <a href="http://monkey.org/~provos/libevent/">libevent</a>，我<a href="http://monkey.org/~provos/libevent-1.1a.tar.gz">下载的是 libevent-1.1a.tar.gz</a>。</p>
<p>接下来是分别将 libevent-1.1a.tar.gz 和 memcached-1.1.12.tar.gz 解开包、编译、安装：</p>
<pre class="code" style="PADDING-BOTTOM: 20px; WIDTH: 500px"># tar -xzf libevent-1.1a.tar.gz# cd libevent-1.1a# ./configure --prefix=/usr# make# make install# cd ..# tar -xzf memcached-1.1.12.tar.gz# cd memcached-1.1.12# ./configure --prefix=/usr# make# make install</pre>
<p>安装完成之后，memcached 应该在 /usr/bin/memcached。</p>
<p><strong>三、运行 memcached 守护程序</strong></p>
<p>运行 memcached 守护程序很简单，只需一个命令行即可，不需要修改任何配置文件（也没有配置文件给你修改 <img class="wp-smiley" alt=":)" src="http://nio.infor96.com/wp-includes/images/smilies/icon_smile.gif" /> ）：</p>
<pre class="code" style="PADDING-BOTTOM: 20px; WIDTH: 500px">/usr/bin/memcached -d -m 128 -l 192.168.1.1 -p 11211 -u httpd</pre>
<p>参数解释：</p>
<pre class="code" style="PADDING-BOTTOM: 20px; WIDTH: 500px">-d 以守护程序（daemon）方式运行 memcached；-m 设置 memcached 可以使用的内存大小，单位为 M；-l 设置监听的 IP 地址，如果是本机的话，通常可以不设置此参数；-p 设置监听的端口，默认为 11211，所以也可以不设置此参数；-u 指定用户，如果当前为 root 的话，需要使用此参数指定用户。</pre>
<p>当然，还有其它参数可以用，<code>man memcached</code> 一下就可以看到了。</p>
<p><strong>四、memcached 的工作原理</strong></p>
<p>首先 memcached 是以守护程序方式运行于一个或多个服务器中，随时接受客户端的连接操作，客户端可以由各种语言编写，目前已知的客户端 API 包括 Perl/<a href="http://www.donevii.com/post/tag/php" class="st_tag internal_tag" rel="tag" title="Posts tagged with php">PHP</a>/<a href="http://www.donevii.com/post/tag/python" class="st_tag internal_tag" rel="tag" title="Posts tagged with python">Python</a>/Ruby/<a href="http://www.donevii.com/post/tag/java" class="st_tag internal_tag" rel="tag" title="Posts tagged with java">Java</a>/C#/C 等等。PHP 等客户端在与 memcached 服务建立连接之后，接下来的事情就是存取对象了，每个被存取的对象都有一个唯一的标识符 key，存取操作均通过这个 key 进行，保存到 memcached 中的对象实际上是放置内存中的，并不是保存在 <a href="http://www.donevii.com/post/tag/cache" class="st_tag internal_tag" rel="tag" title="Posts tagged with cache">cache</a> 文件中的，这也是为什么 memcached 能够如此高效快速的原因。注意，这些对象并不是持久的，服务停止之后，里边的数据就会丢失。</p>
<p><strong>三、PHP 如何作为 memcached 客户端</strong></p>
<p>有两种方法可以使 PHP 作为 memcached 客户端，调用 memcached 的服务进行对象存取操作。</p>
<p>第一种，PHP 有一个叫做 <a href="http://www.php.net/manual/en/ref.memcache.php">memcache 的扩展</a>，<a href="http://www.donevii.com/post/tag/linux" class="st_tag internal_tag" rel="tag" title="Posts tagged with linux">Linux</a> 下编译时需要带上 <em>&ndash;enable-memcache[=DIR]</em> 选项，Window 下则在 php.ini 中去掉 php_memcache.dll 前边的注释符，使其可用。</p>
<p>除此之外，还有一种方法，可以避开扩展、重新编译所带来的麻烦，那就是直接使用 <a href="http://wikipedia.sourceforge.net/doc/memcached-client/_includes_memcached-client_php.html" class="broken_link">php-memcached-client</a>。</p>
<p>本文选用第二种方式，虽然效率会比扩展库稍差一些，但问题不大。</p>
<p><strong>四、PHP memcached 应用示例</strong></p>
<p>首先 <a id="p481" href="http://nio.infor96.com/wp-content/uploads/2006/04/memcached-client.zip" class="broken_link">下载 memcached-client.php</a>，在下载了 memcached-client.php 之后，就可以通过这个文件中的类&ldquo;memcached&rdquo;对 memcached 服务进行操作了。其实代码调用非常简单，主要会用到的方法有 add()、get()、replace() 和 delete()，方法说明如下：</p>
<p><code>add ($key, $val, $exp = 0)</code><br />往 memcached 中写入对象，$key 是对象的唯一标识符，$val 是写入的对象数据，$exp 为过期时间，单位为秒，默认为不限时间；</p>
<p><code>get ($key)</code><br />从 memcached 中获取对象数据，通过对象的唯一标识符 $key 获取；</p>
<p><code>replace ($key, $value, $exp=0)</code><br />使用 $value 替换 memcached 中标识符为 $key 的对象内容，参数与 add() 方法一样，只有 $key 对象存在的情况下才会起作用；</p>
<p><code>delete ($key, $time = 0)</code><br />删除 memcached 中标识符为 $key 的对象，$time 为可选参数，表示删除之前需要等待多长时间。</p>
<p>下面是一段简单的测试代码，代码中对标识符为 &lsquo;mykey&rsquo; 的对象数据进行存取操作：</p>
<pre class="code" style="PADDING-BOTTOM: 20px; WIDTH: 500px"><code><span style="COLOR: #000000">&lt;pre&gt;<span style="COLOR: #0000bb">&lt;?php</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;包含&nbsp;memcached&nbsp;类文件</span><span style="COLOR: #007700">require_once(</span><span style="COLOR: #dd0000">&lsquo;memcached-client.php&rsquo;</span><span style="COLOR: #007700">);</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;选项设置</span><span style="COLOR: #0000bb">$options&nbsp;</span><span style="COLOR: #007700">=&nbsp;array(&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #dd0000">&rsquo;servers&rsquo;&nbsp;</span><span style="COLOR: #007700">=&gt;&nbsp;array(</span><span style="COLOR: #dd0000">&lsquo;192.168.1.1:11211&prime;</span><span style="COLOR: #007700">),&nbsp;</span><span style="COLOR: #ff8000">//memcached&nbsp;服务的地址、端口，可用多个数组元素表示多个&nbsp;memcached&nbsp;服务&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #dd0000">&lsquo;<a href="http://www.donevii.com/post/tag/debug" class="st_tag internal_tag" rel="tag" title="Posts tagged with debug">debug</a>&rsquo;&nbsp;</span><span style="COLOR: #007700">=&gt;&nbsp;</span><span style="COLOR: #0000bb">true</span><span style="COLOR: #007700">,&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//是否打开&nbsp;debug&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #dd0000">&lsquo;compress_threshold&rsquo;&nbsp;</span><span style="COLOR: #007700">=&gt;&nbsp;</span><span style="COLOR: #0000bb">10240</span><span style="COLOR: #007700">,&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//超过多少字节的数据时进行压缩&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #dd0000">&lsquo;persistant&rsquo;&nbsp;</span><span style="COLOR: #007700">=&gt;&nbsp;</span><span style="COLOR: #0000bb">false&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//是否使用持久连接&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #007700">);</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;创建&nbsp;memcached&nbsp;对象实例</span><span style="COLOR: #0000bb">$mc&nbsp;</span><span style="COLOR: #007700">=&nbsp;new&nbsp;</span><span style="COLOR: #0000bb">memcached</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$options</span><span style="COLOR: #007700">);</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;设置此脚本使用的唯一标识符</span><span style="COLOR: #0000bb">$key&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #dd0000">&lsquo;mykey&rsquo;</span><span style="COLOR: #007700">;</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;往&nbsp;memcached&nbsp;中写入对象</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">add</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&rsquo;some&nbsp;random&nbsp;strings&rsquo;</span><span style="COLOR: #007700">);</span><span style="COLOR: #0000bb">$val&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">);echo&nbsp;</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">.</span><span style="COLOR: #0000bb">str_pad</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;$mc-&gt;add()&nbsp;&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">60</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;_&rsquo;</span><span style="COLOR: #007700">).</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">;</span><span style="COLOR: #0000bb">var_dump</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$val</span><span style="COLOR: #007700">);</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;替换已写入的对象数据值</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">replace</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">,&nbsp;array(</span><span style="COLOR: #dd0000">&rsquo;some&rsquo;</span><span style="COLOR: #007700">=&gt;</span><span style="COLOR: #dd0000">&lsquo;haha&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;array&rsquo;</span><span style="COLOR: #007700">=&gt;</span><span style="COLOR: #dd0000">&lsquo;xxx&rsquo;</span><span style="COLOR: #007700">));</span><span style="COLOR: #0000bb">$val&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">);echo&nbsp;</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">.</span><span style="COLOR: #0000bb">str_pad</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;$mc-&gt;replace()&nbsp;&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">60</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;_&rsquo;</span><span style="COLOR: #007700">).</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">;</span><span style="COLOR: #0000bb">var_dump</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$val</span><span style="COLOR: #007700">);</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;删除&nbsp;memcached&nbsp;中的对象</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">delete</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">);</span><span style="COLOR: #0000bb">$val&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">);echo&nbsp;</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">.</span><span style="COLOR: #0000bb">str_pad</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;$mc-&gt;delete()&nbsp;&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">60</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;_&rsquo;</span><span style="COLOR: #007700">).</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">;</span><span style="COLOR: #0000bb">var_dump</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$val</span><span style="COLOR: #007700">);</span><span style="COLOR: #0000bb">?&gt;</span>&lt;/pre&gt;</span></code></pre>
<p>是不是很简单，在实际应用中，通常会把数据库查询的结果集保存到 memcached 中，下次访问时直接从 memcached 中获取，而不再做数据库查询操作，这样可以在很大程度上减轻数据库的负担。通常会将 SQL 语句 md5() 之后的值作为唯一标识符 key。下边是一个利用 memcached 来缓存数据库查询结果集的示例（此代码片段紧接上边的示例代码）：</p>
<pre class="code" style="PADDING-BOTTOM: 20px; WIDTH: 500px"><code><span style="COLOR: #000000"><span style="COLOR: #0000bb">&lt;?php$sql&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #dd0000">&lsquo;SELECT&nbsp;*&nbsp;FROM&nbsp;users&rsquo;</span><span style="COLOR: #007700">;</span><span style="COLOR: #0000bb">$key&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">md5</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$sql</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//memcached&nbsp;对象标识符</span><span style="COLOR: #007700">if&nbsp;(&nbsp;!(</span><span style="COLOR: #0000bb">$datas&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">get</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">))&nbsp;)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;在&nbsp;memcached&nbsp;中未获取到缓存数据，则使用数据库查询获取记录集。&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #007700">echo&nbsp;</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">.</span><span style="COLOR: #0000bb">str_pad</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;Read&nbsp;datas&nbsp;from&nbsp;MySQL.&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">60</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;_&rsquo;</span><span style="COLOR: #007700">).</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000bb">$conn&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">mysql_connect</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;localhost&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;test&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;test&rsquo;</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000bb">mysql_select_db</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;test&rsquo;</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000bb">$result&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">mysql_query</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$sql</span><span style="COLOR: #007700">);&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(</span><span style="COLOR: #0000bb">$row&nbsp;</span><span style="COLOR: #007700">=&nbsp;</span><span style="COLOR: #0000bb">mysql_fetch_object</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$result</span><span style="COLOR: #007700">))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000bb">$datas</span><span style="COLOR: #007700">[]&nbsp;=&nbsp;</span><span style="COLOR: #0000bb">$row</span><span style="COLOR: #007700">;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #ff8000">//&nbsp;&nbsp;将数据库中获取到的结果集数据保存到&nbsp;memcached&nbsp;中，以供下次访问时使用。&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000bb">$mc</span><span style="COLOR: #007700">-&gt;</span><span style="COLOR: #0000bb">add</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$key</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">$datas</span><span style="COLOR: #007700">);}&nbsp;else&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">.</span><span style="COLOR: #0000bb">str_pad</span><span style="COLOR: #007700">(</span><span style="COLOR: #dd0000">&lsquo;Read&nbsp;datas&nbsp;from&nbsp;memcached.&rsquo;</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #0000bb">60</span><span style="COLOR: #007700">,&nbsp;</span><span style="COLOR: #dd0000">&lsquo;_&rsquo;</span><span style="COLOR: #007700">).</span><span style="COLOR: #dd0000">&ldquo;n&rdquo;</span><span style="COLOR: #007700">;}</span><span style="COLOR: #0000bb">var_dump</span><span style="COLOR: #007700">(</span><span style="COLOR: #0000bb">$datas</span><span style="COLOR: #007700">);</span><span style="COLOR: #0000bb">?&gt;</span></span></code></pre>
<p>可以看出，使用 memcached 之后，可以减少数据库连接、查询操作，数据库负载下来了，脚本的运行速度也提高了。</p>
<p>之前我曾经写过一篇名为<a href="http://nio.infor96.com/sharing-php-session-data-between-servers/" class="broken_link">《PHP 实现多服务器共享 SESSION 数据》</a>文章，文中的 SESSION 是使用数据库保存的，在并发访问量大的时候，服务器的负载会很大，经常会超出 MySQL 最大连接数，利用 memcached，我们可以很好地解决这个问题，工作原理如下：</p>
<ul>
<li>用户访问网页时，查看 memcached 中是否有当前用户的 SESSION 数据，使用 session_id() 作为唯一标识符；如果数据存在，则直接返回，如果不存在，再进行数据库连接，获取 SESSION 数据，并将此数据保存到 memcached 中，供下次使用； </li>
<li>当前的 PHP 运行结束（或使用了 <a href="http://php.liukang.com/manual/en/function.session-write-close.php" class="broken_link">session_write_close()</a>）时，会调用 My_Sess::write() 方法，将数据写入数据库，这样的话，每次仍然会有数据库操作，对于这个方法，也需要进行优化。使用一个全局变量，记录用户进入页面时的 SESSION 数据，然后在 write() 方法内比较此数据与想要写入的 SESSION 数据是否相同，不同才进行数据库连接、写入数据库，同时将 memcached 中对应的对象删除，如果相同的话，则表示 SESSION 数据未改变，那么就可以不做任何操作，直接返回了； </li>
<li>那么用户 SESSION 过期时间怎么解决呢？记得 memcached 的 add() 方法有个过期时间参数 $exp 吗？把这个参数值设置成小于 SESSION 最大存活时间即可。另外别忘了给那些一直在线的用户延续 SESSION 时长，这个可以在 write() 方法中解决，通过判断时间，符合条件则更新数据库数据。 </li>
</ul>
<p><strong>五、相关资源</strong></p>
<ul>
<li><a href="http://www.danga.com/memcached/">memcached 官方网站</a> </li>
<li><a href="http://wikipedia.sourceforge.net/doc/memcached-client/_includes_memcached-client_php.html" class="broken_link">PHP memcached client</a> </li>
<li><a href="http://nio.infor96.com/wp-content/uploads/2006/04/memcached-client.zip" class="broken_link">下载 memcached-client.php</a> </li>
</ul>
<p><strong><em>肖理达 (KrazyNio AT hotmail.com), 2006.04. 06, 转载请注明出处</em></strong></p>
<p><strong><em>转载自:http://nio.infor96.com/php-memcached/</em></strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/204.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tim Bray 又有惊人之语：PHP比Java更具有伸缩性</title>
		<link>http://www.donevii.com/post/193.html</link>
		<comments>http://www.donevii.com/post/193.html#comments</comments>
		<pubDate>Sat, 11 Nov 2006 08:17:35 +0000</pubDate>
		<dc:creator>gavinkwoe</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[class]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[开发]]></category>
		<category><![CDATA[测试]]></category>

		<guid isPermaLink="false">http://www.donevii.com/?p=193</guid>
		<description><![CDATA[在 CSDN 上看到的,原文在Tim bray的blog ：comparison intrinsic qualities of Java, Rails, and PHP&#160;&#160;中（http://www.tbray.org/ongoing/When/200x/2006/11/10/Comparing-Frameworks） Tim首先明确了它这个观点的适用的范围：Web... ]]></description>
			<content:encoded><![CDATA[<p>在 CSDN 上看到的,原文在Tim bray的blog ：comparison intrinsic qualities of <a href="http://www.donevii.com/post/tag/java" class="st_tag internal_tag" rel="tag" title="Posts tagged with java">Java</a>, Rails, and <a href="http://www.donevii.com/post/tag/php" class="st_tag internal_tag" rel="tag" title="Posts tagged with php">PHP</a>&nbsp;&nbsp;中（<a href="http://www.tbray.org/ongoing/When/200x/2006/11/10/Comparing-Frameworks">http://www.tbray.org/ongoing/When/200x/2006/11/10/Comparing-Frameworks</a>）</p>
<p>Tim首先明确了它这个观点的适用的范围：Web应用程序。对于那些基于浏览器的，从数据库显示一些信息，然后能够更新数据库的这种应用程序。</p>
<p><a href="http://www.tbray.org/ongoing/When/200x/2006/11/10/-big/Comparison-1.jpg" class="broken_link"><img class="norm" title="Comparing Web Frameworks" alt="Comparing Web Frameworks" src="http://www.tbray.org/ongoing/When/200x/2006/11/10/Comparison-1.png" width="300" /></a></p>
<p>1 伸缩性</p>
<p>Java 开发了EBay ，而 PHP 开发了 Wikipedia&nbsp;和 Yahoo! Finance. 它们的伸缩性都足够好。</p>
<p>2 开发速度</p>
<p>3 工具支持</p>
<p>Java是最大的赢家，Rails有TextMate，PHP有Zend</p>
<p>4 可维护性</p>
<p>一个好的应用程序需要 面向对象，MVC架构，代码可读，代码的数量越少越好。</p>
<p>Tim认为这是PHP的痛脚，虽然PHP完全可以写出上面的代码，但是PHPer通常不这么做。大多数PHP程序是意大利面式的代码裹着意大利面式的SQL和意大利面式的HTML。（笑死人了）</p>
<p>Tim最后说，不要问它PHP，Rails,Java那个好，它依赖于你对项目进行的选择。最近几年PHP和Rails教会了我们开发的速度是多么的重要。在一切的开发中，维护才是最重要的。</p>
<p>InfoQ对Tim进行了访问：</p>
<p><span style="FONT-WEIGHT: bold">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InfoQ: 为什么Rails比Java更具有可维护性?</span> </p>
<blockquote><p>主要是因为代码少。事实是Ruby强制使用MVC模式，其模板机制和ORM，以及测试和程序代码耦合的太紧密了。请记住，我们到现在还搞不清，Rails对于那些不适用于CRUD形式的程序到底有什么用。</p>
<p><span style="FONT-WEIGHT: bold">InfoQ: 为什么PHP比Java更具有伸缩性？</span> </p>
<p>不是这个意思，而是在web应用领域，它易于伸缩（没有中间件或服务要共享）。</p>
<p><span style="FONT-WEIGHT: bold">InfoQ: 那一种特性在你的比较中最为重要？</span></p>
</blockquote>
<blockquote><p>可维护性。</p></blockquote>
<p>Tim 继续在其blog中解释了可维护性：</p>
<blockquote><p>在这个疯狂的Web2.0的世界里，能够快速的构建系统非常重要。面对投资和开发需求，你要在最短的时间交付系统。但是真正做过企业开发的聪明的程序员和经理们都知道。开发最大的成本是从你产品交付的那一刻，才刚刚开始。</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.donevii.com/post/193.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

