<?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>I&#039;m Donkey &#187; 坨坨胡同儿</title>
	<atom:link href="http://imdonkey.com/blog/archives/category/sunight/feed" rel="self" type="application/rss+xml" />
	<link>http://imdonkey.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 26 Aug 2010 02:14:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>php中对共享内存，消息队列的操作</title>
		<link>http://imdonkey.com/blog/archives/557</link>
		<comments>http://imdonkey.com/blog/archives/557#comments</comments>
		<pubDate>Sun, 22 Aug 2010 03:01:00 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=557</guid>
		<description><![CDATA[php作为脚本程序，通常生命周期都很短，如在web应用中，一次请求就是php运行的一个周期，请求结束则生命周期截止。所以php在处理需要共享的资源时，一般会将共享数据保存在数据库或dbm之类的文件中，再者就是利用内存实现共享。你可以选择已有的工具辅助你，像memcache；也可以自己编写代码访问操作系统的共享内存段。
php中对共享内存段的操作有两组函数：<a href="http://cn.php.net/manual/en/book.sem.php">System V IPC</a>和<a href="http://cn.php.net/manual/en/book.shmop.php">Shared Memory</a>。其中System V IPC系列函数能够更方便的操作数据，无需像Shared Memory那样必须自己掌握读写时的偏移量、长度等，也不用序列化/反序列化来回转换（因为Shared Memory函数只支持字符串格式的数据参数）。但是System V IPC系列不支持Windows，所以如果要在win环境下使用，只能选Shared Memory。
因为php默认不支持这些函数，所以需要重编译php。如要使用：
System V信号量，编译时加上 &#8211;enable-sysvsem
System V共享内存，编译时加上 &#8211;enable-sysvshm
System V<p class='read-more'><a href='http://imdonkey.com/blog/archives/557'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>php作为脚本程序，通常生命周期都很短，如在web应用中，一次请求就是php运行的一个周期，请求结束则生命周期截止。所以php在处理需要共享的资源时，一般会将共享数据保存在数据库或dbm之类的文件中，再者就是利用内存实现共享。你可以选择已有的工具辅助你，像memcache；也可以自己编写代码访问操作系统的共享内存段。</p>
<p>php中对共享内存段的操作有两组函数：<a href="http://cn.php.net/manual/en/book.sem.php">System V IPC</a>和<a href="http://cn.php.net/manual/en/book.shmop.php">Shared Memory</a>。其中System V IPC系列函数能够更方便的操作数据，无需像Shared Memory那样必须自己掌握读写时的偏移量、长度等，也不用序列化/反序列化来回转换（因为Shared Memory函数只支持字符串格式的数据参数）。但是System V IPC系列不支持Windows，所以如果要在win环境下使用，只能选Shared Memory。</p>
<p>因为php默认不支持这些函数，所以需要重编译php。如要使用：<br />
System V信号量，编译时加上 &#8211;enable-sysvsem<br />
System V共享内存，编译时加上 &#8211;enable-sysvshm<br />
System V消息队列，编译时加上 &#8211;enable-sysvmsg<br />
Shared Memory，编译时加上 &#8211;enable-shmop</p>
<p>先写个Shared Memory的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$key</span> <span style="color: #000000;">=</span> <span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #7F0055; font-weight: bold;">__FILE__</span><span style="color: #000000;">,</span> <span style="color: #0000ff;">'i'</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$size</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">100</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$shm_h</span> <span style="color: #000000;">=</span> <span style="color: #000000;">@</span><span style="color: #990000;">shmop_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #000000;">,</span> <span style="color: #0000ff;">'c'</span><span style="color: #000000;">,</span> <span style="color: #208080;">0644</span><span style="color: #000000;">,</span> <span style="color: #000088;">$size</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span> <span style="color: #000000;">===</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;shmop open failed&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #990000;">exit</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$data</span> <span style="color: #000000;">=</span> <span style="color: #990000;">shmop_read</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #000000;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #000000;">,</span> <span style="color: #000088;">$size</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$data</span> <span style="color: #000000;">=</span> <span style="color: #990000;">unserialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #666666; font-style: italic;">//如果没有数据则写一个</span>
<span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;there is no data&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #000088;">$data</span> <span style="color: #000000;">=</span> <span style="color: #0000ff;">&quot;imdonkey&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #666666; font-style: italic;">//就算数据是文本，write时也要序列化</span>
        <span style="color: #000088;">$write_size</span> <span style="color: #000000;">=</span> <span style="color: #990000;">shmop_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #000000;">,</span> <span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
        <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$write_size</span> <span style="color: #000000;">===</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;shmop write failed!&quot;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">//如果有，显示出来，之后删掉</span>
<span style="color: #7F0055;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;shared memory data: &quot;</span><span style="color: #000000;">;</span>
        <span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
        <span style="color: #990000;">shmop_delete</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #990000;">shmop_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>再写个System V shm的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">&lt;?php</span> 
<span style="color: #000088;">$shm_key</span> <span style="color: #000000;">=</span> <span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #7F0055; font-weight: bold;">__FILE__</span><span style="color: #000000;">,</span> <span style="color: #0000ff;">'i'</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$memsize</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">120</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$shm_h</span> <span style="color: #000000;">=</span> <span style="color: #990000;">shm_attach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_key</span><span style="color: #000000;">,</span> <span style="color: #000088;">$memsize</span><span style="color: #000000;">,</span> <span style="color: #208080;">0644</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span> <span style="color: #000000;">===</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;shmop open failed&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #990000;">exit</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$var_key</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$data</span> <span style="color: #000000;">=</span> <span style="color: #000000;">@</span><span style="color: #990000;">shm_get_var</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #000000;">,</span> <span style="color: #000088;">$var_key</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$data</span> <span style="color: #000000;">=</span> <span style="color: #0000ff;">&quot;imdonkey&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;there is no data, insert <span style="color: #006699; font-weight: bold;">$data</span>.<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #990000;">shm_put_var</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #000000;">,</span> <span style="color: #000088;">$var_key</span><span style="color: #000000;">,</span> <span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #7F0055;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;find data: <span style="color: #006699; font-weight: bold;">$data</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #000000;">;</span>
        <span style="color: #990000;">shm_remove_var</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #000000;">,</span> <span style="color: #000088;">$var_key</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #990000;">shm_detach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shm_h</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>可以看到，sysV对于每个数据都另外设立了对应的var_key，这样在同一内存区域可以保存多个数据，而不用像shmop中那样再申请另外一个共享内存区域，还免除了序列化的干扰（虽然数据最终还是以序列化的形式保存，但不用开发者去手动实现）。</p>
<p>例子虽然简单，但也有一些需要注意的地方，不管是shm_attach还是shmop_open，所申请的内存的大小一定要满足后面数据的体积，这个体积包括数据本身序列化后的长，还有php添加的少量header信息。php官方文档中有人提出了一种计算要申请的内存大小的公式，这个公式可以保证所申请的内存足够存储<strong>一个</strong>指定的数据。公式如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//当shm_attach第一次被调用时，php向共享内存写入一个header</span>
<span style="color: #000088;">$shmHeaderSize</span> <span style="color: #000000;">=</span> <span style="color: #009900;">&#40;</span>PHP_INT_SIZE <span style="color: #000000;">*</span> <span style="color: #cc66cc;">4</span><span style="color: #009900;">&#41;</span> <span style="color: #000000;">+</span> <span style="color: #cc66cc;">8</span><span style="color: #000000;">;</span>
<span style="color: #666666; font-style: italic;">//当shm_put_var调用时，php会在序列化后的数据前面，加一个header</span>
<span style="color: #000088;">$shmVarSize</span> <span style="color: #000000;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">serialize</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">+</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">4</span> <span style="color: #000000;">*</span> PHP_INT_SIZE<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000;">/</span><span style="color: #cc66cc;">4</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000;">*</span> <span style="color: #cc66cc;">4</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000;">+</span> <span style="color: #cc66cc;">4</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$memsize</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$shmHeaderSize</span> <span style="color: #000000;">+</span> <span style="color: #000088;">$shmVarSize</span><span style="color: #000000;">;</span></pre></div></div>

<p>这个公式是否适用于所有情况，我不敢说，所以我想最好还是在程序中，将准备放入共享内存的数据结构设计好，尽量保证数据大小在某一范围内。</p>
<p>还有就是为了防止共享内存被浪费，当数据无用时及时调用对应的remove方法释放资源。</p>
<p>介绍完共享内存再顺带提一下消息队列Message Queue（也是在<a href="http://cn.php.net/manual/en/book.sem.php">System V IPC</a>函数组中），消息队列似乎可以视为另一种共享内存，只是数据存储的方式有些不同。简单来说，就是每个key对应一个队列，每个队列可以保存多个数据，数据间按照先进先出的原则进行操作。php文档中的例子很好的介绍了各函数的应用：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">&lt;?php</span> 
<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$argv</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">&lt;</span><span style="color: #cc66cc;">2</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;Usage: <span style="color: #006699; font-weight: bold;">$argv[0]</span> stat|send|receive|remove msgType MSG [msg] <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;   EX: <span style="color: #006699; font-weight: bold;">$argv[0]</span> send 1 <span style="color: #000099; font-weight: bold;">\&quot;</span>This is no 1<span style="color: #000099; font-weight: bold;">\&quot;</span> <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;       <span style="color: #006699; font-weight: bold;">$argv[0]</span> receive ID <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;       <span style="color: #006699; font-weight: bold;">$argv[0]</span> stat <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;       <span style="color: #006699; font-weight: bold;">$argv[0]</span> remove <span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000;">;</span> 
        <span style="color: #990000;">exit</span><span style="color: #000000;">;</span> 
<span style="color: #009900;">&#125;</span> 
&nbsp;
<span style="color: #000088;">$MSGKey</span> <span style="color: #000000;">=</span> <span style="color: #0000ff;">&quot;123456&quot;</span> <span style="color: #000000;">;</span> 
<span style="color: #000088;">$seg</span> <span style="color: #000000;">=</span> msg_get_queue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$MSGKey</span><span style="color: #009900;">&#41;</span> <span style="color: #000000;">;</span> 
&nbsp;
<span style="color: #7F0055;">switch</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #7F0055;">case</span> <span style="color: #0000ff;">&quot;send&quot;</span><span style="color: #000000;">:</span> 
        msg_send<span style="color: #009900;">&#40;</span><span style="color: #000088;">$seg</span><span style="color: #000000;">,</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;msg_send done...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">break</span><span style="color: #000000;">;</span> 
&nbsp;
    <span style="color: #7F0055;">case</span> <span style="color: #0000ff;">&quot;receive&quot;</span><span style="color: #000000;">:</span> 
        <span style="color: #000088;">$stat</span> <span style="color: #000000;">=</span> msg_stat_queue<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$seg</span> <span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">'Messages in the queue: '</span><span style="color: #000000;">.</span><span style="color: #000088;">$stat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'msg_qnum'</span><span style="color: #009900;">&#93;</span><span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$stat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'msg_qnum'</span><span style="color: #009900;">&#93;</span><span style="color: #000000;">&gt;</span><span style="color: #cc66cc;">0</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
            msg_receive<span style="color: #009900;">&#40;</span><span style="color: #000088;">$seg</span><span style="color: #000000;">,</span> <span style="color: #000088;">$argv</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$msgtype</span><span style="color: #000000;">,</span> <span style="color: #cc66cc;">1024</span><span style="color: #000000;">,</span> <span style="color: #000088;">$data</span><span style="color: #000000;">,</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">,</span> MSG_IPC_NOWAIT<span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
            <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$msgtype</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
            <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
            <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #000000;">;</span> 
        <span style="color: #009900;">&#125;</span> 
        <span style="color: #7F0055;">else</span> <span style="color: #009900;">&#123;</span> 
            <span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">&quot;No Msg...<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #000000;">;</span> 
        <span style="color: #009900;">&#125;</span> 
        <span style="color: #7F0055;">break</span><span style="color: #000000;">;</span> 
&nbsp;
    <span style="color: #7F0055;">case</span> <span style="color: #0000ff;">&quot;stat&quot;</span><span style="color: #000000;">:</span> 
      <span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span> msg_stat_queue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$seg</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">break</span><span style="color: #000000;">;</span> 
&nbsp;
    <span style="color: #7F0055;">case</span> <span style="color: #0000ff;">&quot;remove&quot;</span><span style="color: #000000;">:</span> 
        msg_remove_queue<span style="color: #009900;">&#40;</span><span style="color: #000088;">$seg</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
        <span style="color: #7F0055;">break</span><span style="color: #000000;">;</span> 
<span style="color: #009900;">&#125;</span> 
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>消息队列中的数据同样受到大小的约束，具体约束范围可通过msg_stat_queue的msg_qbytes看到。这段代码唯一有点小改动的地方就在接受消息时，指定了MSG_IPC_NOWAIT，不然如果目标队列没有数据，默认会一直等待。</p>
<p>一般会用到共享内存或消息队列的情况，都会涉及到多线程/进程，或跨语言的数据传递。如果是php脚本/进程间共享数据，那只要小心点操作就没什么问题。如果要求跨语言，那很可能遇到千奇百怪的问题，呵呵，我还没试过，但在网上看到别人发的苦水贴，以后有机会一定实验一下。</p>
<p>在调试共享内存、信号量、消息队列时，可以配合Linux系统命令观察数据存储情况及信号量、消息队列资源分配情况，如ipcs, ipcrm命令。</p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/557/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>初识PHP中的闭包</title>
		<link>http://imdonkey.com/blog/archives/526</link>
		<comments>http://imdonkey.com/blog/archives/526#comments</comments>
		<pubDate>Fri, 09 Jul 2010 15:58:31 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=526</guid>
		<description><![CDATA[闭包的概念早已应用在其他某些编程语言中，而且使用的人越来越多，可见大家对函数式编程的喜爱。PHP从5.3后也开始支持闭包，此文就简单介绍一下PHP中闭包的实现。由于本人对闭包的理解和应用水平不高，所以疏漏误解之处请多多包涵并指正 <img src='http://imdonkey.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />
首先来看看这两个概念：Lambda和Closure，其实说它们是“两个”概念有些不合适，Lambda是Closure的基础，两者都是匿名方法，只是使用时略有不同。
引用一下网上的介绍：
Lambda函数（通常所谓的匿名函数）简单来说就是一次性函数，可以在任何时候定义，且经常赋值给一个变量。函数自身和对应变量处于同一个作用域内，当离开变量的作用域后，该函数也将消亡，Lambda不保存任何状态。
闭包(Closure)是指一个可以在自己环境中执行的函数，调用时可以访问已经绑定的变量。它们来源于函数式编程世界，在那里有非常多的应用。闭包和Lambda函数类似，但是闭包还可以和定义时指定的外部变量交互。
我们可以简单地理解为Closure可以访问父级视野（parent scope）定义的变量，而Lambda不行。
下面举个例子来说明，比如我想对某一数组的每个元素追加<p class='read-more'><a href='http://imdonkey.com/blog/archives/526'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>闭包的概念早已应用在其他某些编程语言中，而且使用的人越来越多，可见大家对函数式编程的喜爱。PHP从5.3后也开始支持闭包，此文就简单介绍一下PHP中闭包的实现。由于本人对闭包的理解和应用水平不高，所以疏漏误解之处请多多包涵并指正 <img src='http://imdonkey.com/blog/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /><br />
首先来看看这两个概念：Lambda和Closure，其实说它们是“两个”概念有些不合适，Lambda是Closure的基础，两者都是匿名方法，只是使用时略有不同。</p>
<p>引用一下网上的介绍：</p>
<blockquote><p>Lambda函数（通常所谓的匿名函数）简单来说就是一次性函数，可以在任何时候定义，且经常赋值给一个变量。函数自身和对应变量处于同一个作用域内，当离开变量的作用域后，该函数也将消亡，Lambda不保存任何状态。</p>
<p>闭包(Closure)是指一个可以在自己环境中执行的函数，调用时可以访问已经绑定的变量。它们来源于函数式编程世界，在那里有非常多的应用。闭包和Lambda函数类似，但是闭包还可以和定义时指定的外部变量交互。</p></blockquote>
<p>我们可以简单地理解为Closure可以访问父级视野（parent scope）定义的变量，而Lambda不行。<br />
下面举个例子来说明，比如我想对某一数组的每个元素追加一个字符后缀，后缀的内容作为参数传递给函数。</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Lambda实现代码：</span>
<span style="color: #7F0055; font-weight: bold;">function</span> appendPostfix<span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #000000;">,</span> <span style="color: #000088;">$postfix</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$anonyFun</span> <span style="color: #000000;">=</span> <span style="color: #7F0055; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #000000;">,</span> <span style="color: #000088;">$p</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #000088;">$e</span><span style="color: #000000;">.</span><span style="color: #0000ff;">'_'</span><span style="color: #000000;">.</span><span style="color: #000088;">$p</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">return</span> <span style="color: #990000;">array_map</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$anonyFun</span><span style="color: #000000;">,</span> <span style="color: #000088;">$array</span><span style="color: #000000;">,</span> <span style="color: #990000;">array_fill</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #000000;">,</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$postfix</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>由于Lambda不能直接调用$postfix变量，所以只好对匿名函数多加个参数，并在调用array_map时将$postfix作为callback参数再次传递一次。</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Closure实现代码：</span>
<span style="color: #7F0055; font-weight: bold;">function</span> appendPostfix<span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #000000;">,</span> <span style="color: #000088;">$postfix</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$anonyFun</span> <span style="color: #000000;">=</span> <span style="color: #7F0055; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$e</span><span style="color: #009900;">&#41;</span> use<span style="color: #009900;">&#40;</span><span style="color: #000088;">$postfix</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #000088;">$e</span><span style="color: #000000;">.</span><span style="color: #0000ff;">'_'</span><span style="color: #000000;">.</span><span style="color: #000088;">$postfix</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">return</span> <span style="color: #990000;">array_map</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$anonyFun</span><span style="color: #000000;">,</span> <span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>通过使用use关键字，将$postfix传入匿名函数（值传递），于是代码简洁了许多。这里只是说明一下闭包的应用，当然可以通过其他方式实现此功能。</p>
<p>那么对于PHP语言来讲使用闭包都有哪些好处：<br />
1. 代码简洁<br />
不用将函数定义在其他地方，提高代码可读性。也不用为避免函数名重复而而额外添加诸如“if(!function_exists(&#8216;xxx&#8217;))” 的判断。如果你留意Ruby或Python的代码，会惊讶地发现其简洁的风格和直观的可读性。虽然目前PHP的闭包还达不到那些动态语言的水平，但毕竟是向那个方向所作出的第一步尝试。</p>
<p>2.性能<br />
如果按照以前的办法动态定义一个函数(利用create_function)，会有几点不足：由于都是字符串形式，一般IDE无法实现语法高亮；还有就是动态函数是在运行期编译的，而非编译期，所以不能通过<a href="http://blog.csdn.net/laruence/archive/2008/07/18/2673488.aspx">opcode</a>来缓存优化性能。</p>
<p>相对的，PHP的闭包有哪些缺点或者说不足：<br />
1. 留意内存泄露<br />
先看一段简单的代码：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">function</span> increase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$x</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">10</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> use <span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$x</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #000088;">$x</span><span style="color: #000000;">++;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$f</span> <span style="color: #000000;">=</span> increase<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
&nbsp;
<span style="color: #000088;">$r</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$f</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$r</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$f</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span></pre></div></div>

<p>increase方法中的$x是函数局部变量，但是在执行完$f = increase()后并没有被释放掉，因为返回的闭包一直保留着对其的引用。所以在程序输出结果中$x的值会不断递增。这说成是需要注意的地方，不如视为一种编程技巧，我们可以利用这种特性延长函数内部变量的生命周期，相当于在闭包中定义了一个全局的静态变量。</p>
<p>2. 局限<br />
直到5.3.2，PHP的闭包中还<a href="http://wiki.php.net/rfc/closures/removal-of-this">不能直接使用$this</a>，需要先将$this赋给一个临时变量，再通过这个临时变量操纵$this，比如：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">class</span> Foo
<span style="color: #009900;">&#123;</span>
    <span style="color: #7F0055; font-weight: bold;">private</span> <span style="color: #000088;">$x</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">3</span><span style="color: #000000;">;</span>
    <span style="color: #7F0055; font-weight: bold;">private</span> <span style="color: #7F0055; font-weight: bold;">function</span> f<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #7F0055;">return</span> <span style="color: #cc66cc;">15</span><span style="color: #000000;">;</span>
    <span style="color: #009900;">&#125;</span> 
&nbsp;
    <span style="color: #7F0055; font-weight: bold;">public</span> <span style="color: #7F0055; font-weight: bold;">function</span> getClosureUsingPrivates<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$self</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$this</span><span style="color: #000000;">;</span> <span style="color: #666666; font-style: italic;">//注意这行</span>
        <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> use <span style="color: #009900;">&#40;</span><span style="color: #000088;">$self</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #7F0055;">return</span> <span style="color: #000088;">$self</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">x</span> <span style="color: #000000;">*</span> <span style="color: #000088;">$self</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">f</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #000000;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>当然，闭包还有很多特性和应用可以挖掘，借鉴下网上总结的常用闭包应用：重构、定制、遍历集合、管理资源、实施策略。<br />
以后可以考虑多使用闭包的形式，以此来学习和体验闭包带来的不同体验。</p>
<p>部分参考文章：<br />
<a href="http://wiki.php.net/rfc/closures"> Lambda functions and closures</a><br />
<a href="http://www.phpv.net/html/1703.html">谈PHP 闭包特性在实际应用中的问题</a></p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/526/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP简单实现：阿拉伯数字-&gt;汉字</title>
		<link>http://imdonkey.com/blog/archives/504</link>
		<comments>http://imdonkey.com/blog/archives/504#comments</comments>
		<pubDate>Fri, 07 May 2010 14:15:16 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/archives/504</guid>
		<description><![CDATA[<div id="_mcePaste">
<div id="_mcePaste">数字转汉字，如：123 转为 一百二十三。这种需求遇到的时候不多，但，我还是遇到了</div>
<div id="_mcePaste">闲话不多说，直接上代码：</div>
</div><p class='read-more'><a href='http://imdonkey.com/blog/archives/504'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>数字转汉字（只支持整数），这种需求遇到的时候不多，但，我还是遇到了<br />
闲话不多说，直接上代码：</p>
<pre class="brush: php;">
&lt;?php
/*
数字转汉字
如：123 转为 一百二十三
*/
function num2str($num) {
	if(!is_numeric($num)) return false;

	$ret = '';
	if($num &lt; 0) {
		$ret = '负';
		$num = -$num;
	}

	$zhNumArray = array(
		&quot;1&quot; =&gt; &quot;一&quot;,
		&quot;2&quot; =&gt; &quot;二&quot;,
		&quot;3&quot; =&gt; &quot;三&quot;,
		&quot;4&quot; =&gt; &quot;四&quot;,
		&quot;5&quot; =&gt; &quot;五&quot;,
		&quot;6&quot; =&gt; &quot;六&quot;,
		&quot;7&quot; =&gt; &quot;七&quot;,
		&quot;8&quot; =&gt; &quot;八&quot;,
		&quot;9&quot; =&gt; &quot;九&quot;,
		&quot;0&quot; =&gt; &quot;零&quot;,
	);

	$bitStrArray = array(
		&quot;1&quot; =&gt; &quot;&quot;,
		&quot;10&quot; =&gt; &quot;十&quot;,
		&quot;100&quot; =&gt; &quot;百&quot;,
		&quot;1000&quot; =&gt; &quot;千&quot;,
		&quot;10000&quot; =&gt; &quot;万&quot;,
		&quot;100000000&quot; =&gt; &quot;亿&quot;,
	);

	$prebit = 0;//上次记录的位数
	krsort($bitStrArray);
	foreach($bitStrArray as $bit =&gt; $name) {
		$bit = floatval($bit);
		if($num &gt;= $bit) {
			$tmpNum = floor($num / $bit);
			if($tmpNum &gt;= 10) {
				$tmpRet = num2str($tmpNum);
				$ret .= $tmpRet . $name;
			} else {
				if($prebit/$bit &gt; 10) {//按照中文习惯补零
					$ret .= '0';
				}
				$ret .= $tmpNum . $name;
			}
			$prebit = $bit;
			$num = fmod($num, $bit);//取模
		}
	}

	$ret = str_replace(array_keys($zhNumArray), array_values($zhNumArray), $ret);
	return $ret;
}

$test = '1234567890';
echo num2str($test);
?&gt;
</pre>
<p>这段代码算不上优美，可读性还凑合，bug肯定会有（那还展示出来干嘛呀- -!）。但我还是幻想万一对人能有所帮助呢，或者引来某个迷路的高手指点一二，都算是件好事。</p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/504/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP简单实现中文分词——二分法</title>
		<link>http://imdonkey.com/blog/archives/500</link>
		<comments>http://imdonkey.com/blog/archives/500#comments</comments>
		<pubDate>Fri, 07 May 2010 14:06:41 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[分词]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=500</guid>
		<description><![CDATA[<div id="_mcePaste">
<div id="_mcePaste">二分法是一种简单的中文分词方法，其原理就是把中文字符串按两个字进行切分，如“imdonkey的主人要发奋了”，拆分完就是“imdonkey/的主/主人/人要/要发/发奋/奋了”。当然，为了更好的被搜索引擎利用，现实项目中还会对结果进一步处理，这里就不多说了，因为作者本人目前也不懂呢。</div>
<div id="_mcePaste"></div>
<div id="_mcePaste">好，闲话不多说，直接上代码：</div>
</div><p class='read-more'><a href='http://imdonkey.com/blog/archives/500'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>二分法是一种简单的中文分词方法，其原理就是把中文字符串按两个字进行切分，如“imdonkey的主人要发奋了”，拆分完就是“imdonkey/的主/主人/人要/要发/发奋/奋了”。当然，为了更好的被搜索引擎利用，现实项目中还会对结果进一步处理，这里就不多说了，因为作者本人目前也不懂呢。</p>
<p>好，闲话不多说，直接上代码：</p>
<pre class="brush: php;">
&lt;?php
/*
*功能：对于输入的内容按照二分法规则进行分词，遵循以下规则
*实例：imdonkey的主人要发奋了
*结果：imdonkey 的主 主人 人要 要发 发奋 奋了
*/

function binary_split($str) {
	$ret = array();
	$preword = '';
	$preischinese = false;
	for($i = 0; $i &lt; strlen($str); $i++) {
		$cur = $str[$i];
		if(ord($cur) &gt; 0x80) {
			// current is chinese
			if(!empty($preword)) {
				if($preischinese){
					// preword is chinese
					if(strlen($preword) == 4) {
						$ret[] = $preword.$cur;
						$preword = substr($preword, 2);
					}

				} else {
					// preword is non-chinese
					$ret[] = $preword;
					$preword = '';
				}
			}
			$preword .= $cur;
			$preischinese = true;

		} else {
			// current is non-chinese
			if(!empty($preword)) {
				if($preischinese){
					// preword is chinese
					$ret[] = $preword;
					$preword = '';

				} else {
					// preword is non-chinese

				}
			}
			$preword .= $cur;
			$preischinese = false;
		}

	}//end for
	if(!empty($preword)) $ret[] = $preword;

	return $ret;
}

$test = 'imdonkey的主人要发奋了';
print_r(binary_split($test));
?&gt;
</pre>
<p>这段代码算不上优美，可读性还凑合，bug肯定会有（那还展示出来干嘛呀- -!）。但我还是幻想万一对人能有所帮助呢，或者引来某个迷路的高手指点一二，都算是件好事。</p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/500/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>检测链表中是否有环</title>
		<link>http://imdonkey.com/blog/archives/356</link>
		<comments>http://imdonkey.com/blog/archives/356#comments</comments>
		<pubDate>Sun, 25 Apr 2010 17:02:13 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[算法]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=356</guid>
		<description><![CDATA[<div id="_mcePaste">其实这是个经典算法题，但我却刚刚听说，可见对于算法，我已经漠视很久了。这不是一个专业程序员应该有的状态…… 在此推荐一篇关于<a href="http://static.icybear.net/[CN]Programmer%20competency%20matrix.htm">程序员能力矩阵</a>的文章，please enjoy~ :)</div>
<div id="_mcePaste">这个题目是听公司同事说起的，当时我的第一反应也是建立一个哈希表，然后循环检查元素是否已经存在于这个表中，没有就添加进去，并检查下一个，如果有就说明此链表是个环。甚至为了优化性能，可以隔几个检查一次，这样还能减少比对次数。后来google了一下，豁然开朗~</div>
<div id="_mcePaste">简单说来，就是设置两个指针(fast, slow)，初始值都指向头，slow每次前进一步，fast每次前进二步(如果能证明其他数值性能更高，欢迎补充)，如果链表存在环，则fast必定先进入环，而slow后进入环，两个指针必定相遇。(当然，fast先行头到尾部为NULL，则为无环链表)</div><p class='read-more'><a href='http://imdonkey.com/blog/archives/356'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>其实这是个经典算法题，但我却刚刚听说，可见对于算法，我已经漠视很久了。这不是一个专业程序员应该有的状态…… 在此推荐一篇关于<a href="http://static.icybear.net/[CN]Programmer%20competency%20matrix.htm">程序员能力矩阵</a>的文章，please enjoy~ <img src='http://imdonkey.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>这个题目是听公司同事说起的，当时我的第一反应也是建立一个哈希表，然后循环检查元素是否已经存在于这个表中，没有就添加进去，并检查下一个，如果有就说明此链表是个环。甚至为了优化性能，可以隔几个检查一次，这样还能减少比对次数。后来google了一下，豁然开朗~</p>
<p>简单说来，就是设置两个指针(fast, slow)，初始值都指向头，slow每次前进一步，fast每次前进二步(如果能证明其他数值性能更高，欢迎补充)，如果链表存在环，则fast必定先进入环，而slow后进入环，两个指针必定相遇。(当然，fast先行头到尾部为NULL，则为无环链表)，具体到Java代码是这样的：</p>
<p>首先先定义LinkedNode类，为了简化代码，我只给它设置了一个属性：next</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">class</span> LinkedNode <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">private</span> LinkedNode next <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">void</span> setNext<span style="color: #009900;">&#40;</span>LinkedNode _next<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">this</span>.<span style="color: #006633;">next</span> <span style="color: #339933;">=</span> _next<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> LinkedNode next<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">return</span> <span style="color: #006699; font-weight: bold;">this</span>.<span style="color: #006633;">next</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>然后开始写测试代码：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">class</span> CircleChecker <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">static</span> <span style="color: #006699; font-weight: bold;">final</span> <span style="color: #006699; font-weight: bold;">int</span> HASHCHECK <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">static</span> <span style="color: #006699; font-weight: bold;">final</span> <span style="color: #006699; font-weight: bold;">int</span> STEPCHECK <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #008200;">/**
	 * Generate a linked list
	 * @param circle if true, return a circle list
	 * @param capacity list size
	 * @return linked list
	 */</span>
	<span style="color: #006699; font-weight: bold;">private</span> List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> getLinkedList<span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">boolean</span> circle, <span style="color: #006699; font-weight: bold;">int</span> capacity<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> list <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> LinkedList<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		LinkedNode head <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> LinkedNode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		list.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">--</span>capacity <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			LinkedNode node <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> LinkedNode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			list.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>list.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setNext</span><span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			list.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #006699; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>circle<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			list.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>list.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">setNext</span><span style="color: #009900;">&#40;</span>head<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;List size is :&quot;</span> <span style="color: #339933;">+</span> list.<span style="color: #006633;">size</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">return</span> list<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">boolean</span> hashCheck<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> list<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">boolean</span> hasCircle <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		Set<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> hash <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> HashSet<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		LinkedNode node <span style="color: #339933;">=</span> list.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		hash.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">int</span> times <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">int</span> step <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>node.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #006699; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> step <span style="color: #339933;">&amp;&amp;</span> node.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #006699; font-weight: bold;">null</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				node <span style="color: #339933;">=</span> node.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #006699; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>hash.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>node<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				hasCircle <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">true</span><span style="color: #339933;">;</span>
				<span style="color: #006699; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			times<span style="color: #339933;">++;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Check Time: &quot;</span> <span style="color: #339933;">+</span> times<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">return</span> hasCircle<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">boolean</span> stepCheck<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> list<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">boolean</span> hasCircle <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">int</span> i<span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">int</span> step1 <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">int</span> step2 <span style="color: #339933;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span>
&nbsp;
		LinkedNode node1 <span style="color: #339933;">=</span> list.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		LinkedNode node2 <span style="color: #339933;">=</span> list.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">int</span> times <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>node1.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #006699; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> node2.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #006699; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> step1 <span style="color: #339933;">&amp;&amp;</span> node1.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #006699; font-weight: bold;">null</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				node1 <span style="color: #339933;">=</span> node1.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> step2 <span style="color: #339933;">&amp;&amp;</span> node2.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #006699; font-weight: bold;">null</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				node2 <span style="color: #339933;">=</span> node2.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #006699; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>node1 <span style="color: #339933;">==</span> node2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				hasCircle <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">true</span><span style="color: #339933;">;</span>
				<span style="color: #006699; font-weight: bold;">break</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			times<span style="color: #339933;">++;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Check Time: &quot;</span> <span style="color: #339933;">+</span> times<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">return</span> hasCircle<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">void</span> startCheck<span style="color: #009900;">&#40;</span>List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> list, <span style="color: #006699; font-weight: bold;">int</span> mode<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">long</span> start <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">boolean</span> result <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">false</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>mode<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">case</span> HASHCHECK<span style="color: #339933;">:</span>
			<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;[Hash Check]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			result <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">this</span>.<span style="color: #006633;">hashCheck</span><span style="color: #009900;">&#40;</span>list<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #006699; font-weight: bold;">break</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">case</span> STEPCHECK<span style="color: #339933;">:</span>
			<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;[Step Check]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			result <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">this</span>.<span style="color: #006633;">stepCheck</span><span style="color: #009900;">&#40;</span>list<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #006699; font-weight: bold;">break</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">default</span><span style="color: #339933;">:</span>
			<span style="color: #003399;">System</span>.<span style="color: #006633;">err</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Unsupported Mode&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #006699; font-weight: bold;">long</span> end <span style="color: #339933;">=</span> <span style="color: #003399;">System</span>.<span style="color: #006633;">currentTimeMillis</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;RunningTime: &quot;</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>end <span style="color: #339933;">-</span> start<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Result is &quot;</span> <span style="color: #339933;">+</span> result <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\r</span><span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">static</span> <span style="color: #006699; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> arg<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		CircleChecker app <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> CircleChecker<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> testList <span style="color: #339933;">=</span> app.<span style="color: #006633;">getLinkedList</span><span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">true</span>, <span style="color: #cc66cc;">500000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		app.<span style="color: #006633;">startCheck</span><span style="color: #009900;">&#40;</span>testList, HASHCHECK<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		app.<span style="color: #006633;">startCheck</span><span style="color: #009900;">&#40;</span>testList, STEPCHECK<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>运行结果如下：<br />
List size is :500000</p>
<p>[Hash Check]<br />
Check Time: 249999<br />
RunningTime: 453<br />
Result is true</p>
<p>[Step Check]<br />
Check Time: 499999<br />
RunningTime: 40<br />
Result is true</p>
<p>这是对一个环路链表的检测结果，下面再试试无环路链表。把main函数中的</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> testList <span style="color: #339933;">=</span> app.<span style="color: #006633;">getLinkedList</span><span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">true</span>, <span style="color: #cc66cc;">500000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>改为：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">List<span style="color: #339933;">&lt;</span>LinkedNode<span style="color: #339933;">&gt;</span> testList <span style="color: #339933;">=</span> app.<span style="color: #006633;">getLinkedList</span><span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">false</span>, <span style="color: #cc66cc;">500000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>运行结果如下：<br />
List size is :500000</p>
<p>[Hash Check]<br />
Check Time: 250000<br />
RunningTime: 448<br />
Result is false</p>
<p>[Step Check]<br />
Check Time: 250000<br />
RunningTime: 24<br />
Result is false</p>
<p>可见虽然哈希表检查法可能在比较次数上较少，但是总耗时多了很多，主要耗费在hash.add(node)上，因为选择的是Set，所以为了保证元素唯一性，在add数据时会检查是否已存在。而且当要检查的元素数量巨大时，要占用非常大的内存，甚至OutOfMemoryError。而快慢两步走法（sorry，我起得名字有点土），仅仅进行指针比较既可，极其快速，而且不占内存！<br />
这才是我们应该追求的终极目标</p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/356/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP中json_decode的整型溢出问题</title>
		<link>http://imdonkey.com/blog/archives/346</link>
		<comments>http://imdonkey.com/blog/archives/346#comments</comments>
		<pubDate>Sun, 25 Apr 2010 03:53:40 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=346</guid>
		<description><![CDATA[编码过程中遇到个错误，就是在处理json时，数值较大的int值在解码后数据被损坏，比如：

<span style="color: #000088;">$array</span> <span style="color: #000000;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">&#34;id1&#34;</span> <span style="color: #000000;">=&#62;</span> <span style="color: #cc66cc;">2147483647</span><span style="color: #000000;">,</span>
    <span style="color: #0000ff;">&#34;id2&#34;</span> <span style="color: #000000;">=&#62;</span> <span style="color: #cc66cc;">2147483648</span>
<span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$json</span> <span style="color: #000000;">=</span> <span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$out</span> <span style="color: #000000;">=</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$json</span><span style="color: #000000;">,</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$out</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>

理论上应该看到：

array(2) {
    ["id1"]=>int(2147483647)
    ["id2"]=>int(2147483648)
}
但实际在我的电脑上却得到：
array(2) {
    ["id1"]=>int(2147483647)
    ["id2"]=>int(<span style="color: #3366ff;">-2147483646</span>)
}
这是由PHP整数值范围决定的，而这个范围依赖于操作系统。在32位操作系统中，PHP的整数最大值是2147483647，你可以通过输出PHP_INT_MAX看到。
一般情况下<p class='read-more'><a href='http://imdonkey.com/blog/archives/346'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>编码过程中遇到个错误，就是在处理json时，数值较大的int值在解码后数据被损坏，比如：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$array</span> <span style="color: #000000;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">&quot;id1&quot;</span> <span style="color: #000000;">=&gt;</span> <span style="color: #cc66cc;">2147483647</span><span style="color: #000000;">,</span>
    <span style="color: #0000ff;">&quot;id2&quot;</span> <span style="color: #000000;">=&gt;</span> <span style="color: #cc66cc;">2147483648</span>
<span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$json</span> <span style="color: #000000;">=</span> <span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$out</span> <span style="color: #000000;">=</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$json</span><span style="color: #000000;">,</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$out</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span></pre></div></div>

<p>理论上应该看到：</p>
<pre>
array(2) {
    ["id1"]=>int(2147483647)
    ["id2"]=>int(2147483648)
}</pre>
<p>但实际在我的电脑上却得到：</p>
<pre>array(2) {
    ["id1"]=>int(2147483647)
    ["id2"]=>int(<span style="color: #3366ff;">-2147483646</span>)
}</pre>
<p>这是由PHP整数值范围决定的，而这个范围依赖于操作系统。在32位操作系统中，PHP的整数最大值是2147483647，你可以通过输出PHP_INT_MAX看到。</p>
<p>一般情况下，你赋值一个很大的数，PHP会自动判定这个数值的范围并自动转换类型，如：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$large_number</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">2147483647</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$large_number</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>                     <span style="color: #666666; font-style: italic;">// int(2147483647)</span>
&nbsp;
<span style="color: #000088;">$large_number</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">2147483648</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$large_number</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>                     <span style="color: #666666; font-style: italic;">// float(2147483648)</span>
&nbsp;
<span style="color: #000088;">$million</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">1000000</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$large_number</span> <span style="color: #000000;">=</span>  <span style="color: #cc66cc;">50000</span> <span style="color: #000000;">*</span> <span style="color: #000088;">$million</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$large_number</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>                     <span style="color: #666666; font-style: italic;">// float(50000000000)</span></pre></div></div>

<p>但是在json_decode方法中没有进行这种检测，这是PHP（旧版本）的bug，在5.3以后的版本，就不存在这个问题了。</p>
<p>如果你不想更新你的PHP，那还有个办法，就是将数字转为字符串。还是以上面的代码为例：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$array</span> <span style="color: #000000;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">&quot;id1&quot;</span> <span style="color: #000000;">=&gt;</span> <span style="color: #cc66cc;">2147483647</span><span style="color: #000000;">,</span>
    <span style="color: #0000ff;">&quot;id2&quot;</span> <span style="color: #000000;">=&gt;</span> <span style="color: #cc66cc;">2147483648</span>
<span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$json</span> <span style="color: #000000;">=</span> <span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
&nbsp;
<span style="color: #000088;">$json</span> <span style="color: #000000;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/(&quot;id\d&quot;:)(\d{9,})/i'</span><span style="color: #000000;">,</span> <span style="color: #0000ff;">'${1}&quot;${2}&quot;'</span><span style="color: #000000;">,</span> <span style="color: #000088;">$json</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
&nbsp;
<span style="color: #000088;">$out</span> <span style="color: #000000;">=</span> <span style="color: #990000;">json_decode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$json</span><span style="color: #000000;">,</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$out</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span></pre></div></div>

<p>当然，这个怎么替换是按需而定的，而且需要比较细致的测试。</p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/346/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>浅谈PHP中的Session机制</title>
		<link>http://imdonkey.com/blog/archives/255</link>
		<comments>http://imdonkey.com/blog/archives/255#comments</comments>
		<pubDate>Sun, 28 Mar 2010 15:07:29 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=255</guid>
		<description><![CDATA[<div id="_mcePaste">做web开发，必然会涉及到Session，这是由于http协议本身是无状态的（每次响应都是独立的，彼此间没有联系），所以如果需要在页面跳转间保持某个用户的身份，就要在每次连接时告诉服务器端你的唯一标示号，即Session ID。这样，服务器端便可通过Session ID得到所需的数据。</div>
<div id="_mcePaste">在PHP中，Session是通过$_SESSION这个全局变量来set/get的，不过在使用之前要先初始化。初始化是通过session_start函数（如果php.ini中将session.auto_start设为1，则会自动初始化），之后PHP会为request自动生成一个唯一随机数作为Session ID，生成算法默认提供了MD5 (128 bits) 和SHA-1 (160 bits)，由php.ini中session.hash_function设定。其实也可以自定义，比如在随机数基础上将来访者的IP地址也加入到算法中</div><p class='read-more'><a href='http://imdonkey.com/blog/archives/255'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>做web开发，必然会涉及到Session，这是由于http协议本身是无状态的（每次响应都是独立的，彼此间没有联系），所以如果需要在页面跳转间保持某个用户的身份，就要在每次连接时告诉服务器端你的唯一标示号，即Session ID。这样，服务器端便可通过Session ID得到所需的数据。</p>
<p>在PHP中，Session是通过$_SESSION这个全局变量来set/get的，不过在使用之前要先初始化。初始化是通过session_start函数（如果php.ini中将session.auto_start设为1，则会自动初始化），之后PHP会为request自动生成一个唯一随机数作为Session ID，生成算法默认提供了MD5 (128 bits) 和SHA-1 (160 bits)，由php.ini中session.hash_function设定。其实也可以自定义，比如在随机数基础上将来访者的IP地址也加入到算法中，像CodeIgniter1.7.2中代码：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sessid</span> <span style="color: #000000;">=</span> <span style="color: #0000ff;">''</span><span style="color: #000000;">;</span>
<span style="color: #7F0055;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessid</span><span style="color: #009900;">&#41;</span> <span style="color: #000000;">&lt;</span> <span style="color: #cc66cc;">32</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$sessid</span> <span style="color: #000000;">.=</span> <span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #000000;">,</span> <span style="color: #990000;">mt_getrandmax</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">// To make the session ID even more secure we'll combine it with the user's IP</span>
<span style="color: #000088;">$sessid</span> <span style="color: #000000;">.=</span> <span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">CI</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">input</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">ip_address</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #000088;">$sessid</span> <span style="color: #000000;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">uniqid</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessid</span><span style="color: #000000;">,</span> <span style="color: #7F0055; font-weight: bold;">TRUE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>生成的ID存放在服务器的某一目录下，这由php.ini中session.save_path配置。如果要在多个服务器中同步session id，你可以将其存放在数据库或共享缓存中。这需要你自定义一系列Session的读写方法，并在调用session_start函数前先设定好，以下面代码为例(来自php document中的一段示例代码)：</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> <span style="color: #ff0000;">`ws_sessions`</span> <span style="color: #66cc66;">&#40;</span> 
  <span style="color: #ff0000;">`session_id`</span> varchar<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">BINARY</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">''</span><span style="color: #66cc66;">,</span> 
  <span style="color: #ff0000;">`session_expires`</span> int<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">UNSIGNED</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">'0'</span><span style="color: #66cc66;">,</span> 
  <span style="color: #ff0000;">`session_data`</span> text<span style="color: #66cc66;">,</span> 
  <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`session_id`</span><span style="color: #66cc66;">&#41;</span> 
<span style="color: #66cc66;">&#41;</span> TYPE<span style="color: #66cc66;">=</span>InnoDB;</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">&lt;?php</span> 
<span style="color: #7F0055; font-weight: bold;">class</span> session <span style="color: #009900;">&#123;</span> 
   <span style="color: #666666; font-style: italic;">// session-lifetime </span>
   <span style="color: #7F0055; font-weight: bold;">var</span> <span style="color: #000088;">$lifeTime</span><span style="color: #000000;">;</span> 
   <span style="color: #666666; font-style: italic;">// mysql-handle </span>
   <span style="color: #7F0055; font-weight: bold;">var</span> <span style="color: #000088;">$dbHandle</span><span style="color: #000000;">;</span> 
   <span style="color: #7F0055; font-weight: bold;">function</span> open<span style="color: #009900;">&#40;</span><span style="color: #000088;">$savePath</span><span style="color: #000000;">,</span> <span style="color: #000088;">$sessName</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
       <span style="color: #666666; font-style: italic;">// get session-lifetime </span>
       <span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">lifeTime</span> <span style="color: #000000;">=</span> <span style="color: #990000;">get_cfg_var</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;session.gc_maxlifetime&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// open database-connection </span>
       <span style="color: #000088;">$dbHandle</span> <span style="color: #000000;">=</span> <span style="color: #000000;">@</span><span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;server&quot;</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;user&quot;</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;password&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #000088;">$dbSel</span> <span style="color: #000000;">=</span> <span style="color: #000000;">@</span><span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;database&quot;</span><span style="color: #000000;">,</span><span style="color: #000088;">$dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// return success </span>
       <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">!</span><span style="color: #000088;">$dbHandle</span> <span style="color: #000000;">||</span> <span style="color: #000000;">!</span><span style="color: #000088;">$dbSel</span><span style="color: #009900;">&#41;</span> 
           <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #000000;">;</span> 
       <span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$dbHandle</span><span style="color: #000000;">;</span> 
       <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span> 
   <span style="color: #009900;">&#125;</span> 
   <span style="color: #7F0055; font-weight: bold;">function</span> close<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
       <span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">gc</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ini_get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'session.gc_maxlifetime'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// close database-connection </span>
       <span style="color: #7F0055;">return</span> <span style="color: #000000;">@</span><span style="color: #990000;">mysql_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
   <span style="color: #009900;">&#125;</span> 
   <span style="color: #7F0055; font-weight: bold;">function</span> read<span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
       <span style="color: #666666; font-style: italic;">// fetch session-data </span>
       <span style="color: #000088;">$res</span> <span style="color: #000000;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT session_data AS d FROM ws_sessions 
                           WHERE session_id = '<span style="color: #006699; font-weight: bold;">$sessID</span>' 
                           AND session_expires &gt; &quot;</span><span style="color: #000000;">.</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// return data or an empty string at failure </span>
       <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #000000;">=</span> <span style="color: #990000;">mysql_fetch_assoc</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
           <span style="color: #7F0055;">return</span> <span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'d'</span><span style="color: #009900;">&#93;</span><span style="color: #000000;">;</span> 
       <span style="color: #7F0055;">return</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #000000;">;</span> 
   <span style="color: #009900;">&#125;</span> 
   <span style="color: #7F0055; font-weight: bold;">function</span> write<span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessID</span><span style="color: #000000;">,</span><span style="color: #000088;">$sessData</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
       <span style="color: #666666; font-style: italic;">// new session-expire-time </span>
       <span style="color: #000088;">$newExp</span> <span style="color: #000000;">=</span> <span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000;">+</span> <span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">lifeTime</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// is a session with this id in the database? </span>
       <span style="color: #000088;">$res</span> <span style="color: #000000;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT * FROM ws_sessions 
                           WHERE session_id = '<span style="color: #006699; font-weight: bold;">$sessID</span>'&quot;</span><span style="color: #000000;">,</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// if yes, </span>
       <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_num_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$res</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
           <span style="color: #666666; font-style: italic;">// ...update session-data </span>
           <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;UPDATE ws_sessions 
                         SET session_expires = '<span style="color: #006699; font-weight: bold;">$newExp</span>', 
                         session_data = '<span style="color: #006699; font-weight: bold;">$sessData</span>' 
                         WHERE session_id = '<span style="color: #006699; font-weight: bold;">$sessID</span>'&quot;</span><span style="color: #000000;">,</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
           <span style="color: #666666; font-style: italic;">// if something happened, return true </span>
           <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_affected_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
               <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span> 
       <span style="color: #009900;">&#125;</span> 
       <span style="color: #666666; font-style: italic;">// if no session-data was found, </span>
       <span style="color: #7F0055;">else</span> <span style="color: #009900;">&#123;</span> 
           <span style="color: #666666; font-style: italic;">// create a new row </span>
           <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;INSERT INTO ws_sessions ( 
                         session_id, 
                         session_expires, 
                         session_data) 
                         VALUES( 
                         '<span style="color: #006699; font-weight: bold;">$sessID</span>', 
                         '<span style="color: #006699; font-weight: bold;">$newExp</span>', 
                         '<span style="color: #006699; font-weight: bold;">$sessData</span>')&quot;</span><span style="color: #000000;">,</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
           <span style="color: #666666; font-style: italic;">// if row was created, return true </span>
           <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_affected_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
               <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span> 
       <span style="color: #009900;">&#125;</span> 
       <span style="color: #666666; font-style: italic;">// an unknown error occured </span>
       <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #000000;">;</span> 
   <span style="color: #009900;">&#125;</span> 
   <span style="color: #7F0055; font-weight: bold;">function</span> destroy<span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessID</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
       <span style="color: #666666; font-style: italic;">// delete session-data </span>
       <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;DELETE FROM ws_sessions WHERE session_id = '<span style="color: #006699; font-weight: bold;">$sessID</span>'&quot;</span><span style="color: #000000;">,</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// if session was deleted, return true, </span>
       <span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">mysql_affected_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> 
           <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// ...else return false </span>
       <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #000000;">;</span> 
   <span style="color: #009900;">&#125;</span> 
   <span style="color: #7F0055; font-weight: bold;">function</span> gc<span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessMaxLifeTime</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
       <span style="color: #666666; font-style: italic;">// delete old sessions </span>
       <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;DELETE FROM ws_sessions WHERE session_expires &lt; &quot;</span><span style="color: #000000;">.</span><span style="color: #990000;">time</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
       <span style="color: #666666; font-style: italic;">// return affected rows </span>
       <span style="color: #7F0055;">return</span> <span style="color: #990000;">mysql_affected_rows</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">dbHandle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
   <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span> 
<span style="color: #000088;">$session</span> <span style="color: #000000;">=</span> <span style="color: #7F0055; font-weight: bold;">new</span> session<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
<span style="color: #990000;">session_set_save_handler</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$session</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;open&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> 
                         <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$session</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;close&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> 
                         <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$session</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;read&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> 
                         <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$session</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;write&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> 
                         <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$session</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;destroy&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">,</span> 
                         <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #000000;">&amp;</span><span style="color: #000088;">$session</span><span style="color: #000000;">,</span><span style="color: #0000ff;">&quot;gc&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
<span style="color: #990000;">session_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span> 
<span style="color: #666666; font-style: italic;">// etc... </span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>除了上述方法外还有其他办法可以保持Session的同步，可以参考<a href="http://www.phpchina.com/bbs/viewthread.php?tid=176201">PHP SESSION解惑</a>一文中第四部分“session的同步”。</p>
<p>下面再谈谈Session ID的传递方式：Cookie和URL传递。<br />
Cookie是比较常用的方式，在这种模式下，启动Session后服务器会在HTTP Response中自动加上header(&#8216;Set-Cookie: session_name()=session_id(); path=/&#8217;)，并在以后的请求中加上这个Cookie。当从该页跳转到的新页面并调用session_start()后，PHP将检查与给定ID相关联的服务器端存贮的session数据，如果没找到，则新建一个数据集。但是有一点，这种传递方式必须在用户浏览器开启Cookie的情况下才可用，如果万一用户关闭了Cookie，那么只好选择另外一种通过URL参数传递Session ID。<br />
开启URL传递需要在php.ini中设置session.use_trans_sid（<em>文档中提示使用这种方式会有安全风险，因为它显示地将Session ID放在url中，所以除非迫不得已不要选择此方式</em>），并在代码中做如下修改：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// 如果客户端使用cookie,可直接传递session到page2.php</span>
<span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">'&lt;br /&gt;&lt;a href=&quot;page2.php&quot;&gt;page 2&lt;/a&gt;'</span><span style="color: #000000;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// 如果客户端禁用cookie</span>
<span style="color: #7F0055;">echo</span> <span style="color: #0000ff;">'&lt;br /&gt;&lt;a href=&quot;page2.php?'</span> <span style="color: #000000;">.</span> SID <span style="color: #000000;">.</span> <span style="color: #0000ff;">'&quot;&gt;page 2&lt;/a&gt;'</span><span style="color: #000000;">;</span>
<span style="color: #666666; font-style: italic;">/*
 默认php5.2.1下,SID只有在cookie被写入的同时才会有值,如果该session
 对应的cookie已经存在,那么SID将为(未定义)空
 */</span></pre></div></div>

<p>关于Session的内容还有很多，具体可查看<a href="http://www.php.net/manual/en/book.session.php">官方手册</a>，如果有新的总结会继续更新。</p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/255/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>让CodeIgniter自动加载所有自定义类</title>
		<link>http://imdonkey.com/blog/archives/142</link>
		<comments>http://imdonkey.com/blog/archives/142#comments</comments>
		<pubDate>Sat, 30 Jan 2010 17:59:43 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=142</guid>
		<description><![CDATA[此文主要是提出一种让CodeIgniter自动加载所有自定义类的办法，即lazyloading。（只适用于没有带参数的构造函数的类）

先举个例子，如果我在一个controller中想调用某自定义的library，一般来讲需要两步：
1.  $this->load->library("mylib");
2.  $this->mylib->myfunction();

虽然第一步不是每次都要调用，但至少要在使用前初始化一次。当需要的library比较多时，假如再加上需要的model类，那就有点烦人了。所以，我们要做的就是去掉第一步，不管在controller，library还是model中，让codeigniter自动load需要的类，这样我们就能更专注于业务逻辑，而不用考虑载入的问题。<p class='read-more'><a href='http://imdonkey.com/blog/archives/142'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>此文主要是提出一种让CodeIgniter自动加载所有自定义类的办法，即lazyloading。（只适用于没有带参数的构造函数的类）</p>
<p>先举个例子，如果我在一个controller中想调用某自定义的library，一般来讲需要两步：<br />
1.  $this-&gt;load-&gt;library(&#8220;mylib&#8221;);<br />
2.  $this-&gt;mylib-&gt;myfunction();</p>
<p>虽然第一步不是每次都要调用，但至少要在使用前初始化一次。当需要的library比较多时，假如再加上需要的model类，那就有点烦人了。所以，我们要做的就是去掉第一步，不管在controller，library还是model中，让codeigniter自动load需要的类，这样我们就能更专注于业务逻辑，而不用考虑载入的问题。</p>
<p>大家都知道，php5中预定义了__get()方法来获取属性，这个方法不是默认存在的，需要我们手工添加到类里面去。我们就利用这个方法来实现自动加载，首先需要在system/library/Controller和Model两个codeigniter文件中加上__get()方法，代码如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">function</span> __get <span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span> <span style="color: #000000;">==</span> <span style="color: #0000ff;">&quot;config&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #7F0055;">return</span><span style="color: #000000;">;</span>
	<span style="color: #000088;">$var</span> <span style="color: #000000;">=&amp;</span>wxMagicGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">return</span> <span style="color: #000088;">$var</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>而wxMagicGet方法可以定义在一个你自己的helper文件中，代码如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #7F0055; font-weight: bold;">function</span> <span style="color: #000000;">&amp;</span>wxMagicGet<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span> <span style="color: #000000;">==</span> <span style="color: #0000ff;">&quot;db&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$CI</span> <span style="color: #000000;">=</span> <span style="color: #000000;">&amp;</span>get_instance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
		<span style="color: #000088;">$CI</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">database</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #000088;">$CI</span><span style="color: #000000;">-&gt;</span><span style="color: #000088;">$name</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000;">!</span>wxGetLoadingInfo<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> <span style="color: #000088;">$type</span><span style="color: #000000;">,</span> <span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">null</span><span style="color: #000000;">;</span>
&nbsp;
	<span style="color: #000088;">$CI</span> <span style="color: #000000;">=</span> <span style="color: #000000;">&amp;</span>get_instance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span> <span style="color: #000000;">==</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$CI</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">library</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mpath</span><span style="color: #000000;">.</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #7F0055;">else</span> <span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$type</span> <span style="color: #000000;">==</span> <span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$CI</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #000000;">-&gt;</span><span style="color: #004000;">model</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mpath</span><span style="color: #000000;">.</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #7F0055;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">null</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #7F0055;">return</span> <span style="color: #000088;">$CI</span><span style="color: #000000;">-&gt;</span><span style="color: #000088;">$name</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #7F0055; font-weight: bold;">function</span> wxGetLoadingInfo<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> <span style="color: #000000;">&amp;</span><span style="color: #000088;">$type</span><span style="color: #000000;">,</span> <span style="color: #000000;">&amp;</span><span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	static <span style="color: #000088;">$pathmap</span> <span style="color: #000000;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
	<span style="color: #000088;">$filename</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$name</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">strripos</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> <span style="color: #0000ff;">&quot;.php&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000;">===</span> <span style="color: #7F0055; font-weight: bold;">FALSE</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$filename</span> <span style="color: #000000;">.=</span> <span style="color: #0000ff;">&quot;.php&quot;</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #7F0055;">return</span> _find_where<span style="color: #009900;">&#40;</span><span style="color: #000088;">$filename</span><span style="color: #000000;">,</span> <span style="color: #000088;">$type</span><span style="color: #000000;">,</span> <span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #7F0055; font-weight: bold;">function</span> _find_where<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> <span style="color: #000000;">&amp;</span><span style="color: #000088;">$type</span><span style="color: #000000;">,</span> <span style="color: #000000;">&amp;</span><span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">//find in app model</span>
	<span style="color: #000088;">$type</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">2</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span>_find_where_path<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> APPPATH<span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;models/&quot;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$mpath</span> <span style="color: #000000;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mpath</span><span style="color: #000000;">,</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span>APPPATH<span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;models/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//find in app library</span>
	<span style="color: #000088;">$type</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span>_find_where_path<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> APPPATH<span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;libraries/&quot;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$mpath</span> <span style="color: #000000;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mpath</span><span style="color: #000000;">,</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span>APPPATH<span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;libraries/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//find in base library</span>
	<span style="color: #000088;">$type</span> <span style="color: #000000;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span>_find_where_path<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> BASEPATH<span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;libraries/&quot;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$mpath</span> <span style="color: #000000;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$mpath</span><span style="color: #000000;">,</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span>BASEPATH<span style="color: #000000;">.</span><span style="color: #0000ff;">&quot;libraries/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #7F0055; font-weight: bold;">function</span> _find_where_path<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> <span style="color: #000088;">$path</span><span style="color: #000000;">,</span> <span style="color: #000000;">&amp;</span><span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span> <span style="color: #000000;">.</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$mpath</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$path</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span> <span style="color: #000000;">.</span> <span style="color: #990000;">ucfirst</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$mpath</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$path</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">file_exists</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span> <span style="color: #000000;">.</span> <span style="color: #990000;">strtoupper</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$mpath</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$path</span><span style="color: #000000;">;</span>
		<span style="color: #7F0055;">return</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">//更深入的查找所有子目录</span>
	<span style="color: #000088;">$found</span> <span style="color: #000000;">=</span> <span style="color: #7F0055; font-weight: bold;">false</span><span style="color: #000000;">;</span>
	<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span> <span style="color: #000000;">=</span> <span style="color: #000000;">@</span><span style="color: #990000;">opendir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$path</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #7F0055;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #7F0055; font-weight: bold;">false</span> <span style="color: #000000;">!==</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span> <span style="color: #000000;">=</span> <span style="color: #990000;">readdir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span> <span style="color: #000000;">!=</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #000000;">&amp;&amp;</span> <span style="color: #000088;">$file</span> <span style="color: #000000;">!=</span> <span style="color: #0000ff;">&quot;..&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #000088;">$child</span> <span style="color: #000000;">=</span> <span style="color: #000088;">$path</span><span style="color: #000000;">.</span><span style="color: #000088;">$file</span><span style="color: #000000;">;</span>
				<span style="color: #7F0055;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_dir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$child</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #7F0055;">if</span> <span style="color: #009900;">&#40;</span>_find_where_path<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #000000;">,</span> <span style="color: #000088;">$child</span> <span style="color: #000000;">.</span> <span style="color: #0000ff;">&quot;/&quot;</span><span style="color: #000000;">,</span> <span style="color: #000088;">$mpath</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
						<span style="color: #000088;">$found</span> <span style="color: #000000;">=</span> <span style="color: #7F0055; font-weight: bold;">true</span><span style="color: #000000;">;</span>
						<span style="color: #7F0055;">break</span><span style="color: #000000;">;</span>
					<span style="color: #009900;">&#125;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #990000;">closedir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span><span style="color: #000000;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #7F0055;">return</span> <span style="color: #000088;">$found</span><span style="color: #000000;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>好，一个自动查找并加载的helper就写好了，记得将这个helper放到application/config/autoload.php文件中，这样codeigniter在每次运行时会自动初始化它。</p>
<p>以后我们开发时不管在哪都可以直接调用需要的类，不需要先load了。：）<br />
Controller里直接写：$this-&gt;classname-&gt;function(xxx)就行，<br />
Library里需要先初始化codeigniter资源，如：$this-&gt;obj = &amp;get_instance();<br />
之后也可直接写：$this-&gt;obj-&gt;classname-&gt;function(xxx)</p>
<p>关于codeigniter的框架结构及初始化程序流程，可以参考下面两篇文章：<br />
<a href="http://www.pqshow.com/program/php/200909/10208.html">codeigniter是如何实现mvc模式以及单一入口<br />
</a><a href="http://blog.csdn.net/yuhaibao324/archive/2009/12/20/5037818.aspx">codeIgniter之优缺点</a></p>
<p>codeigniter手册请查看官方网站：<a href="http://codeigniter.org.cn/user_guide/index.html">http://codeigniter.org.cn/user_guide/index.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/142/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Java实现Amazon数据抓取(包括Signature生成)</title>
		<link>http://imdonkey.com/blog/archives/60</link>
		<comments>http://imdonkey.com/blog/archives/60#comments</comments>
		<pubDate>Wed, 30 Dec 2009 08:19:11 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[WebService]]></category>

		<guid isPermaLink="false">http://imdonkey.com/blog/?p=60</guid>
		<description><![CDATA[Amazon目前已提供了N多服务，这里只涉及其中的Product Advertising API。通过它，你可以访问Amazon的数据库，实现很多有用的功能，如：获取商品信息、买家/卖家的评论、还可以搜索物品、促销信息等，这些数据有助于建立你自己的电子商务网站。

下面简单讲述一下用Java语言访问Product Advertising API，并写了两个<span style="color: #0000ff;">搜索物品</span>和<span style="color: #0000ff;">浏览目录</span>的例子。

相关链接：
<a href="http://docs.amazonwebservices.com/AWSECommerceService/2009-10-01/DG/">Product Advertising API
</a><a href="http://code.google.com/p/amazon-product-advertising-api-sample/">amazon-product-advertising-api-sample</a><p class='read-more'><a href='http://imdonkey.com/blog/archives/60'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<p>Amazon目前已提供了N多服务，这里只涉及其中的Product Advertising API。通过它，你可以访问Amazon的数据库，实现很多有用的功能，如：获取商品信息、买家/卖家的评论、还可以搜索物品、促销信息等，这些数据有助于建立你自己的电子商务网站。</p>
<p>下面简单讲述一下用Java语言访问Product Advertising API</p>
<p>首先，你要先去 http://aws.amazon.com 注册自己的账号，注册后记住系统生成的Access Key ID和     Secret Access Key，这两个key值在代码中会用到。这时你可以到<a class="ulink" href="http://associates-amazon.s3.amazonaws.com/signed-requests/helper/index.html" target="_blank">Product Advertising API Signed Requests Helper</a>测试一下这两个Key是否可用，顺便也能了解了解Amazon设定的request和response结构。</p>
<p>然后下载Product Advertising API Java Client                 Side Library（<span style="color: #008000;">需要Java6</span>），这个lib可以简化开发。下载步骤：</p>
<blockquote>
<ol type="1">
<li>
<p class="simpara">Go to the directory where you want to generate the stubs and create a                           &#8220;build&#8221; directory and a &#8220;src&#8221; directory.</p>
<p class="simpara">All of the generated source code will go under &#8220;src&#8221; folder.</p>
</li>
<li>
<p class="simpara">If you are using Eclipse 3.2, create a custom binding to disable                         &#8220;Wrapper Style&#8221; code generation.</p>
<pre style="overflow: auto; background: #ffffff;">&lt;jaxws:bindings wsdlLocation="http://ecs.amazonaws.com/AWSECommerceService/AWSECommerceService.wsdl" xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"&gt;
  &lt;jaxws:enableWrapperStyle&gt;false&lt;/jaxws:enableWrapperStyle&gt;
&lt;/jaxws:bindings&gt;</pre>
<p class="simpara">This step is necessary because Eclipse 3.2 does not support wrapper                             style generated code. However, if you are an IDE that does support                             wrapper style generated code, such as NetBeans, this step is not                             required.</p>
</li>
<li>
<p class="simpara">Run the command:</p>
<pre style="overflow: auto; background: #ffffff;">wsimport -d ./build -s ./src  -p com.ECS.client.jax http://ecs.amazonaws.com/AWSECommerceService/AWSECommerceService.wsdl -b jaxws-custom.xml .</pre>
<p class="simpara">You can find the generated stubs in the path,                             <em>com.ECS.client.jax</em> .</p>
</li>
</ol>
</blockquote>
<p>由于2009年8月后，Amazon升级了WebService，对request添加了更为严格的安全机制——Signature，所以还需要下载两个辅助文件：</p>
<tr>
<td width="1%"><a href="http://developer.amazonwebservices.com/connect/servlet/JiveServlet/download/53-35999-143146-2680/awshandlerresolver.java"><img src="http://developer.amazonwebservices.com/connect/servlet/JiveServlet?attachImage=true&amp;contentType=application%2Foctet-stream&amp;attachment=2680" border="0" alt="Attachment" /></a></td>
<td class="jive-description" width="98%"><a href="http://developer.amazonwebservices.com/connect/servlet/JiveServlet/download/53-35999-143146-2680/awshandlerresolver.java">awshandlerresolver.java</a> (4.2 K)</td>
</tr>
<tr>
<td width="1%"><a href="http://developer.amazonwebservices.com/connect/servlet/JiveServlet/download/53-35999-143146-2681/commons-codec-1.3.jar"><img src="http://developer.amazonwebservices.com/connect/servlet/JiveServlet?attachImage=true&amp;contentType=application%2Foctet-stream&amp;attachment=2681" border="0" alt="Attachment" /></a></td>
<td class="jive-description" width="98%"><a href="http://developer.amazonwebservices.com/connect/servlet/JiveServlet/download/53-35999-143146-2681/commons-codec-1.3.jar">commons-codec-1.3.jar</a> (45.6 K)</td>
</tr>
<p>接下来，就可以写demo了，记得import刚刚下载的开发包和辅助代码。</p>
<p><strong>DEMO1</strong>. 先写个Search的例子，搜索ASIN为0596007124的物品</p>
<p>示例代码如下：</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">class</span> Info <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">static</span> <span style="color: #006699; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">new</span> Info<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> Info<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #008200;">// Initialize Web Service</span>
		AWSECommerceService service <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> AWSECommerceService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		service.<span style="color: #006633;">setHandlerResolver</span><span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">new</span> AwsHandlerResolver<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;Your Secret Key&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #008200;">// Create Web Service Connection</span>
		AWSECommerceServicePortType port <span style="color: #339933;">=</span> service.<span style="color: #006633;">getAWSECommerceServicePort</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #008200;">// Add Parameters for the Item Lookup</span>
		ItemLookupRequest request <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> ItemLookupRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		request.<span style="color: #006633;">getItemId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;0596007124&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		request.<span style="color: #006633;">setIdType</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ASIN&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		request.<span style="color: #006633;">getResponseGroup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Large&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #008200;">// Wrap Request in Lookup Body</span>
		ItemLookup body <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> ItemLookup<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		body.<span style="color: #006633;">setAWSAccessKeyId</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;Your Access ID&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		body.<span style="color: #006633;">setShared</span><span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #008200;">// Assign Results to a Response Object</span>
		ItemLookupResponse response <span style="color: #339933;">=</span> port.<span style="color: #006633;">itemLookup</span><span style="color: #009900;">&#40;</span>body<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		Item item <span style="color: #339933;">=</span> response.<span style="color: #006633;">getItems</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getItem</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>上面的例子中ResponseGroup只添加了“Large”，意思是返回结果中包括物品的大图，除此以外，你还可以添加更多的返回信息，如：BrowseNodes，EditorialReview，ItemAttributes等。</p>
<p><strong>DEMO2</strong>. 抓取Amazon某个目录下的所有物品。这种抓取需要知道要抓的目录id号，即nodeid，这个可以通过分析Amazon的url获得。<br />
比如：<strong><a style="font-family: verdana, arial, helvetica, sans-serif; color: #003399; text-decoration: none;" href="http://www.amazon.com/s/qid=1262157503/ref=sr_hi?ie=UTF8&amp;rs=1058&amp;bbn=&amp;rh=i%3Astripbooks&amp;page=1">Books</a> <span style="color: #666666; font-weight: normal;">›</span> <a style="font-family: verdana, arial, helvetica, sans-serif; color: #003399; text-decoration: none;" href="http://www.amazon.com/s/qid=1262157503/ref=sr_hi?ie=UTF8&amp;rs=1058&amp;bbn=173507&amp;rh=i%3Astripbooks%2Cn%3A%211000%2Cn%3A173507&amp;page=1">Professional &amp; Technical</a> <span style="color: #666666; font-weight: normal;">›</span> <a style="font-family: verdana, arial, helvetica, sans-serif; color: #003399; text-decoration: none;" href="http://www.amazon.com/s/qid=1262157503/ref=sr_hi?ie=UTF8&amp;rs=1058&amp;bbn=173508&amp;rh=i%3Astripbooks%2Cn%3A%211000%2Cn%3A173507%2Cn%3A173508&amp;page=1">Architecture</a> <span style="color: #666666; font-weight: normal;">›</span> Materials <span style="color: #000000; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-weight: normal; line-height: 19px;">这个目录，它的url是</span></strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<pre style="overflow: auto; background: #ffffff;"><a href="http://www.amazon.com/gp/search/ref=sr_nr_n_10?rh=i:stripbooks,n:!1000,n:173507,n:173508,n:1058&amp;bbn=173508&amp;ie=UTF8&amp;qid=1262157489&amp;rnid=173508">http://www.amazon.com/gp/search/ref=sr_nr_n_10?rh=i:stripbooks,n:!1000,n:173507,n:173508,n:1058&amp;bbn=173508&amp;ie=UTF8&amp;qid=1262157489&amp;rnid=173508</a></pre>
<p>，它的nodeid就是1058</p>
<p><strong><span style="color: #000000; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-weight: normal; line-height: 19px;">示例代码如下：</span></strong></p>
<p><strong><span style="color: #000000; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-weight: normal; line-height: 19px;"> </span></strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">class</span> InfoScrap <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> <span style="color: #006699; font-weight: bold;">static</span> <span style="color: #006699; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #006699; font-weight: bold;">new</span> InfoScrap<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #006699; font-weight: bold;">public</span> InfoScrap<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #008200;">// Initialize Web Service</span>
		AWSECommerceService service <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> AWSECommerceService<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		service.<span style="color: #006633;">setHandlerResolver</span><span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">new</span> AwsHandlerResolver<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;Your Secret Key&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #008200;">// Create Web Service Connection</span>
		AWSECommerceServicePortType port <span style="color: #339933;">=</span> service.<span style="color: #006633;">getAWSECommerceServicePort</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #008200;">// Add Parameters for the Item Search</span>
		ItemSearchRequest request <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> ItemSearchRequest<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		java.<span style="color: #006633;">util</span>.<span style="color: #006633;">List</span><span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span> attrs <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> ArrayList<span style="color: #339933;">&lt;</span>String<span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		attrs.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Request&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		attrs.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;BrowseNodes&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		attrs.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;EditorialReview&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		attrs.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;ItemAttributes&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		attrs.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Large&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		request.<span style="color: #006633;">getResponseGroup</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">addAll</span><span style="color: #009900;">&#40;</span>attrs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		request.<span style="color: #006633;">setBrowseNode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;1058&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		request.<span style="color: #006633;">setSearchIndex</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Books&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #008200;">// Only search Book</span>
&nbsp;
		<span style="color: #008200;">// Get browse node page count</span>
		<span style="color: #006699; font-weight: bold;">int</span> page <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
		ItemSearch itemSearch <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> ItemSearch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		itemSearch.<span style="color: #006633;">setAWSAccessKeyId</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;Your Access ID&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		itemSearch.<span style="color: #006633;">getRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		ItemSearchResponse response <span style="color: #339933;">=</span> port.<span style="color: #006633;">itemSearch</span><span style="color: #009900;">&#40;</span>itemSearch<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		java.<span style="color: #006633;">util</span>.<span style="color: #006633;">List</span><span style="color: #339933;">&lt;</span>Items<span style="color: #339933;">&gt;</span> itemssList <span style="color: #339933;">=</span> response.<span style="color: #006633;">getItems</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Items items <span style="color: #339933;">:</span> itemssList<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			page <span style="color: #339933;">=</span> items.<span style="color: #006633;">getTotalPages</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">intValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #008200;">// Start Scrapping Items per page</span>
		<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #006699; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> page<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			request.<span style="color: #006633;">setItemPage</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">BigInteger</span>.<span style="color: #006633;">valueOf</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			port <span style="color: #339933;">=</span> service.<span style="color: #006633;">getAWSECommerceServicePort</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			itemSearch <span style="color: #339933;">=</span> <span style="color: #006699; font-weight: bold;">new</span> ItemSearch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			itemSearch.<span style="color: #006633;">setAWSAccessKeyId</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;Your Access ID&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			itemSearch.<span style="color: #006633;">getRequest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>request<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			response <span style="color: #339933;">=</span> port.<span style="color: #006633;">itemSearch</span><span style="color: #009900;">&#40;</span>itemSearch<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			itemssList <span style="color: #339933;">=</span> response.<span style="color: #006633;">getItems</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Items items <span style="color: #339933;">:</span> itemssList<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				java.<span style="color: #006633;">util</span>.<span style="color: #006633;">List</span><span style="color: #339933;">&lt;</span>Item<span style="color: #339933;">&gt;</span> itemsList <span style="color: #339933;">=</span> items.<span style="color: #006633;">getItem</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #006699; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Item item <span style="color: #339933;">:</span> itemsList<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					<span style="color: #008200;">// callback(item);</span>
					<span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Complete &quot;</span> <span style="color: #339933;">+</span> i <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;/&quot;</span> <span style="color: #339933;">+</span> page<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><span style="white-space: pre;"> </span>相关链接：<span style="color: #000000;"><br />
<a href="http://docs.amazonwebservices.com/AWSECommerceService/2009-10-01/DG/"> Product Advertising API<br />
<span style="color: #000000; -webkit-text-decorations-in-effect: none;"><span style="text-decoration: underline;"> </span></span></a><a href="http://code.google.com/p/amazon-product-advertising-api-sample/">amazon-product-advertising-api-sample</a></span></p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">http://docs.amazonwebservices.com/AWSECommerceService/2009-10-01/GSG/index.html?ImplementinganA2SRequest.html</div>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/60/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>如何让Linux支持PHP GD库的imagerotate方法</title>
		<link>http://imdonkey.com/blog/archives/7</link>
		<comments>http://imdonkey.com/blog/archives/7#comments</comments>
		<pubDate>Mon, 14 Dec 2009 08:26:01 +0000</pubDate>
		<dc:creator>luoxi</dc:creator>
				<category><![CDATA[坨坨胡同儿]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://imdonkey.com/wordpress/?p=7</guid>
		<description><![CDATA[这里介绍的方法是经过试验可行的（虽然后来遇到了其他问题，见文章下面），在此感谢原作者的贡献！
原文地址：<a title="  You are herehow to enable php imagerotate function on ubuntu how to enable php imagerotate function on ubuntu" href="http://voae.com/enable-php-imagerotate-gd" target="_blank">http://voae.com/enable-php-imagerotate-gd
</a>……
<span style="color: #ff0000;">发现问题</span>：Apache有时会莫名kill掉进程，查看log有类似“child pid *** exit signal Segmentation fault”的错误，重启Apache后正常，但过儿又会异常依旧…

这种情况虽然偶尔出现，但却是不可忽视的隐患。经google，感觉似乎是由于PHP升级后，和模块间兼容性的bug。

所以迫不得已，只能rollback回之前的PHP版本，然后用<a href="http://blog.madtech.cx/2006/12/08/debian-etch-libapache2-mod-php5-with-bundled-libgd-gdlib/">Debian Etch libapache2-mod-php5 with bundled libgd (GDLib)</a>一文中提到的方法，并实践成功！这个办法虽然麻烦些，但对系统影响最小，首推这个。<p class='read-more'><a href='http://imdonkey.com/blog/archives/7'>阅读全文 »</a></p>]]></description>
			<content:encoded><![CDATA[<div>
<p>这里介绍的方法是经过试验可行的（虽然后来遇到了其他问题，见文章下面），在此感谢原作者的贡献！</p>
<p><span style="color: #ffffff;"><span style="color: #000000;">原文地址：</span><a title="  You are herehow to enable php imagerotate function on ubuntu how to enable php imagerotate function on ubuntu" href="http://voae.com/enable-php-imagerotate-gd" target="_blank">http://voae.com/enable-php-imagerotate-gd</a></span></p>
<p>Here is the steps for Ubuntu Server 8.04.1 and PHP5. Like Djamu said it will install a GD pre-compiled working version. It is a complete bundled (forked) GD libraries:<br />
这是在Ubuntu Server 8.04.1 和 PHP5环境下的步骤（注：Debian下也成功了）。就像Djamu所说，这个方法安装的GD是预编译的可用版本。是完全绑定的GD库：</p>
<p><strong>1</strong>. If not already done removing your current GD package and its configurations.<br />
先删除你当前的GD包及其配置信息</p>
<p>sudo apt-get &#8211;purge remove</p>
<p><strong>2</strong>. Adding 2 lines to your file /etc/apt/sources.list.<br />
将上面两行加到系统的源列表文件/etc/apt/sources.list</p>
<p>deb <a title="http://packages.dotdeb.org" href="http://packages.dotdeb.org/">http://packages.dotdeb.org</a> stable all<br />
deb-src <a title="http://packages.dotdeb.org" href="http://packages.dotdeb.org/">http://packages.dotdeb.org</a> stable all</p>
<p><strong>3</strong>. Updating your current apt-get list.<br />
更新你的apt-get列表</p>
<p>apt-get update</p>
<p><strong>4</strong>. Installing working GD package.<br />
安装可用的GD包</p>
<p>apt-get install php5-gd</p>
<p>It will complain about non-authenticated sources, just ignore, it will also update some additional php libs.<br />
When prompt select keep_current modified php.ini.<br />
它会警告这是没有身份验证的源，甭管它。它还会更新一些其他的php库。<br />
当出现提示信息时，选择“keep_current modified php.ini”（保留之前所用的php.ini）</p>
<p><strong>5</strong>. Restarting Apache<br />
重启Apache。<br />
/etc/init.d/apache2 restart</p>
<p>如果重启Apache失败，可能是由于某个模块版本不匹配，需要重新编译一下，具体哪个模块的问题要看error信息是什么。</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-华丽的分割线&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<p><span style="color: #ff0000;">发现问题</span>：Apache有时会莫名kill掉进程，查看log有类似“child pid *** exit signal Segmentation fault”的错误，重启Apache后正常，但过儿又会异常依旧…<br />
这种情况虽然偶尔出现，但却是不可忽视的隐患。经google，感觉似乎是由于PHP升级后，和模块间兼容性的bug。</p>
<p>所以迫不得已，只能rollback回之前的PHP版本，然后用<a href="http://blog.madtech.cx/2006/12/08/debian-etch-libapache2-mod-php5-with-bundled-libgd-gdlib/">Debian Etch libapache2-mod-php5 with bundled libgd (GDLib)</a>一文中提到的方法，并实践成功！这个办法虽然麻烦些，但对系统影响最小，首推这个。（前面写了一大堆，最后首推另外一个，真不好意思）</p>
<p>其他可能会对你有帮助的链接：<br />
<a href="http://rashost.com/blog/ubuntu-php5-gd-compile" target="_blank">Ubuntu 下安装php5-gd 不能使用imagerotate函数的解决方法</a><br />
<a href="http://blog.madtech.cx/2006/12/08/debian-etch-libapache2-mod-php5-with-bundled-libgd-gdlib/">Debian Etch libapache2-mod-php5 with bundled libgd (GDLib)</a><br />
<a href="http://topic.csdn.net/u/20070926/14/e2031693-964d-44cb-ae01-76e0d387c78e.html" target="_blank">imageRotate()函数不能用!!</a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://imdonkey.com/blog/archives/7/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
