<?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@laoer.com &#187; PHP</title>
	<atom:link href="http://i.laoer.com/category/php/feed" rel="self" type="application/rss+xml" />
	<link>http://i.laoer.com</link>
	<description>技术、生活、感悟 -- Laoer的博客</description>
	<lastBuildDate>Mon, 15 Feb 2010 08:36:53 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Nginx下alias支持PHP的问题</title>
		<link>http://i.laoer.com/nginx-alias-php.html</link>
		<comments>http://i.laoer.com/nginx-alias-php.html#comments</comments>
		<pubDate>Wed, 06 Jan 2010 02:01:04 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Nginx]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=411</guid>
		<description><![CDATA[这几天在配置Nginx，PHP用FastCGI，想装一个phpMyAdmin管理数据库，phpMyAdmin不想放在网站根目录下，这样不容易和网站应用混在一起，这样phpMyAdmin的目录就放在别处，在Apache里，有alias，比较方便，在Nginx下没有虚拟目录概念的，是用location配合alias使用，我先试了简单的配置方式
location /web/ {
alias  /data/web/;
index  index.html index.htm index.php;
}
location ~ .*\.(php&#124;php5)?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
我用http://localhost/web/可以访问到/data/web目录下的静态文件，但访问php文件，却报No input file specified.的错误，而且在Nginx的error日志上却什么信息也没有，我在网上搜索了一下，判断应该是php文件并没有被后端的FastCGI运行，我又继续搜索一些文章，试着增加了一段配置
location /web/ {
alias  /data/web/;
index  index.html index.htm index.php;
}
location ~ ^/web/.+\.php$ {
root /data/;
rewrite /web/(.*\.php?) /$1 break;
include fcgi.conf;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  index.php;
fastcgi_param SCRIPT_FILENAME /data/web$fastcgi_script_name;
}
location ~ .*\.(php&#124;php5)?$ {
fastcgi_pass  127.0.0.1:9000;
fastcgi_index index.php;
include fcgi.conf;
}
这下可以了，原理应该是采用rewrite的方法，对于/web/下php类型的的请求交给后端的FastCGI处理，并且指定了php脚本的位置，这样我们就可以配置phpMyAdmin了，配置如下
location /phpmyadmin/ {
alias  /data/phpmyadmin/;
index  index.html index.htm index.php;
}
location ~ ^/phpmyadmin/.+\.php$ {
root /data/;
rewrite /phpmyadmin/(.*\.php?) /$1 break;
include fcgi.conf;
fastcgi_pass   127.0.0.1:9000;
fastcgi_index  [...]]]></description>
			<content:encoded><![CDATA[<p>这几天在配置Nginx，PHP用FastCGI，想装一个phpMyAdmin管理数据库，phpMyAdmin不想放在网站根目录下，这样不容易和网站应用混在一起，这样phpMyAdmin的目录就放在别处，在Apache里，有alias，比较方便，在Nginx下没有虚拟目录概念的，是用location配合alias使用，我先试了简单的配置方式</p>
<p>location /web/ {<br />
alias  /data/web/;<br />
index  index.html index.htm index.php;<br />
}</p>
<p>location ~ .*\.(php|php5)?$ {<br />
fastcgi_pass  127.0.0.1:9000;<br />
fastcgi_index index.php;<br />
include fcgi.conf;<br />
}</p>
<p>我用http://localhost/web/可以访问到/data/web目录下的静态文件，但访问php文件，却报No input file specified.的错误，而且在Nginx的error日志上却什么信息也没有，我在网上搜索了一下，判断应该是php文件并没有被后端的FastCGI运行，我又继续搜索一些文章，试着增加了一段配置</p>
<p>location /web/ {<br />
alias  /data/web/;<br />
index  index.html index.htm index.php;<br />
}</p>
<p>location ~ ^/web/.+\.php$ {<br />
root /data/;<br />
rewrite /web/(.*\.php?) /$1 break;<br />
include fcgi.conf;<br />
fastcgi_pass   127.0.0.1:9000;<br />
fastcgi_index  index.php;<br />
fastcgi_param SCRIPT_FILENAME /data/web$fastcgi_script_name;<br />
}</p>
<p>location ~ .*\.(php|php5)?$ {<br />
fastcgi_pass  127.0.0.1:9000;<br />
fastcgi_index index.php;<br />
include fcgi.conf;<br />
}</p>
<p>这下可以了，原理应该是采用rewrite的方法，对于/web/下php类型的的请求交给后端的FastCGI处理，并且指定了php脚本的位置，这样我们就可以配置phpMyAdmin了，配置如下</p>
<p>location /phpmyadmin/ {<br />
alias  /data/phpmyadmin/;<br />
index  index.html index.htm index.php;<br />
}</p>
<p>location ~ ^/phpmyadmin/.+\.php$ {<br />
root /data/;<br />
rewrite /phpmyadmin/(.*\.php?) /$1 break;<br />
include fcgi.conf;<br />
fastcgi_pass   127.0.0.1:9000;<br />
fastcgi_index  index.php;<br />
fastcgi_param SCRIPT_FILENAME /data/phpmyadmin$fastcgi_script_name;<br />
}</p>
<p>location ~ .*\.(php|php5)?$ {<br />
fastcgi_pass  127.0.0.1:9000;<br />
fastcgi_index index.php;<br />
include fcgi.conf;<br />
}</p>
<p>要注意的是</p>
<p>location ~ .*\.(php|php5)?$ {<br />
fastcgi_pass  127.0.0.1:9000;<br />
fastcgi_index index.php;<br />
include fcgi.conf;<br />
}</p>
<p>这段，要放在phpmyadmin的后面，放在前面就有问题，这是和Nginx的location规则有关，具体看Nginx的文档，另外，phpMyAdmin里要配置一下URI的绝对路径，就可以了。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/nginx-alias-php.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在hostmonster主机上安装MediaWiki出现的500问题</title>
		<link>http://i.laoer.com/mediawiki-on-hostmonster-500.html</link>
		<comments>http://i.laoer.com/mediawiki-on-hostmonster-500.html#comments</comments>
		<pubDate>Tue, 03 Nov 2009 02:34:53 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MediaWiki]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=381</guid>
		<description><![CDATA[今天在hostmonster主机上安装MediaWiki，按照文档要求把config目录更改权限
chmod a+w config
但做初始化配置时出现了500服务器内部错误，非常奇怪，我搜了一下相关信息，发现是config目录权限有问题，还是改回755，之后安装，就没有问题了。
]]></description>
			<content:encoded><![CDATA[<p>今天在hostmonster主机上安装MediaWiki，按照文档要求把config目录更改权限</p>
<p>chmod a+w config</p>
<p>但做初始化配置时出现了500服务器内部错误，非常奇怪，我搜了一下相关信息，发现是config目录权限有问题，还是改回755，之后安装，就没有问题了。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/mediawiki-on-hostmonster-500.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wordpress升级到2.8遇到的问题</title>
		<link>http://i.laoer.com/wordpress-2-8-upgrade-problem.html</link>
		<comments>http://i.laoer.com/wordpress-2-8-upgrade-problem.html#comments</comments>
		<pubDate>Mon, 15 Jun 2009 09:18:57 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=353</guid>
		<description><![CDATA[上周末的时候看到后台提示可以升级到wordpress2.8，我就简单做了一个文章导出，之后在线升级到2.8，我之前的版本是2.7.1，提示升级成功，但转到“控制板”之后，提示错误
Allowed memory size of  xxxxxxxxx bytes exhausted
2.8难道有问题，我可没有做完整的备份，2.8的数据库有改动，如果2.8真的有问题就麻烦了，这个错误是说PHP分配内存太小，只要修改php.ini就可以，但我现在用的是虚拟主机，不能修改php.ini的，还是网上搜一下吧，很快，找到了答案，只要在wp-settings.php里修改为
define(&#8216;WP_MEMORY_LIMIT&#8217;, &#8216;64M&#8217;);
就可以了（以前是32M，如果不行可以继续改大）。
Memory解决了，但后台还是提示有新版本2.8，要我升级，我不是已经升级成功了吗，奇怪，后来查了一下，由于我用的是中文版，所以在wp-includes/version.php里增加一行
$wp_local_package = &#8216;zh_CN&#8217;;
就不会再提示有新版本了。
]]></description>
			<content:encoded><![CDATA[<p>上周末的时候看到后台提示可以升级到wordpress2.8，我就简单做了一个文章导出，之后在线升级到2.8，我之前的版本是2.7.1，提示升级成功，但转到“控制板”之后，提示错误</p>
<p>Allowed memory size of  xxxxxxxxx bytes exhausted</p>
<p>2.8难道有问题，我可没有做完整的备份，2.8的数据库有改动，如果2.8真的有问题就麻烦了，这个错误是说PHP分配内存太小，只要修改php.ini就可以，但我现在用的是虚拟主机，不能修改php.ini的，还是网上搜一下吧，很快，找到了答案，只要在wp-settings.php里修改为</p>
<p>define(&#8216;WP_MEMORY_LIMIT&#8217;, &#8216;64M&#8217;);</p>
<p>就可以了（以前是32M，如果不行可以继续改大）。</p>
<p>Memory解决了，但后台还是提示有新版本2.8，要我升级，我不是已经升级成功了吗，奇怪，后来查了一下，由于我用的是中文版，所以在wp-includes/version.php里增加一行</p>
<p>$wp_local_package = &#8216;zh_CN&#8217;;</p>
<p>就不会再提示有新版本了。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/wordpress-2-8-upgrade-problem.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP中的时间时区运算</title>
		<link>http://i.laoer.com/php-datetimezone.html</link>
		<comments>http://i.laoer.com/php-datetimezone.html#comments</comments>
		<pubDate>Wed, 13 May 2009 04:45:14 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=321</guid>
		<description><![CDATA[我在测试twitter的API时，在它返回的用户信息里，关于用户时区的信息有两个
&#60;utc_offset&#62;28800&#60;/utc_offset&#62;
&#60;time_zone&#62;Beijing&#60;/time_zone&#62;
我希望利用这两个数值，得到用户的的DateTimeZone，直接new DateTimeZone(&#8216;Beijing&#8217;)是不行的，我看了PHP的API，时区里是没有“Beijing”的，中国的时区应该是“Asia/Shanghai”，看来这个“Beijing”只是用来显示的，我又查了DateTimeZone的API，里面也没有根据UTC Offset值取得DateTimeZone的方法，看来不能通过这样的方法来做了。
utc_offset这个值是应该表示与UTC标准时间相差的秒数，测试下面的代码
$datetimezone = new DateTimeZone(&#8216;Asia/Shanghai&#8217;);
$datetime = new DateTime(&#8220;now&#8221;,$datetimezone);
echo $datetime-&#62;getOffset();
结果显示28800，没错，时区“Asia/Shanghai”与UTC的时间差是28800秒，也就是8个小时（我们在东8区）。
在PHP中使用time()或是DateTime对象，在不指定DateTimeZone时，其默认的DateTimeZone就是UTC，产生的时间就是UTC时间，把这个时间加上Offset值之后，就可以显示出本时区的正确时间了，比如下面的代码
$datetime = time();
echo date(&#8220;y-m-d H:i:s&#8221;,$datetime);
echo &#8220;&#60;br/&#62;&#8221;;
$datetime = $datetime + 28800;
echo date(&#8220;y-m-d H:i:s&#8221;,$datetime);
输入的结果是
09-05-13 04:21:44
09-05-13 12:21:44
上面是UTC的时间，而下面的是北京时间。
在我们设计数据的时候，时间字段设计为长整数字段比较方便，存放UTC的time()的Unix时间戳，用户可以自己定义所在的时区，通过Offset，最终显示给用户其时区的时间。我感觉Java里的TimeZone似乎要更灵活一些，可以这样TimeZone.getTimeZone(&#8220;GMT+08:00&#8243;)
另外：在PHP里取得所有可用时区的方法是DateTimeZone::listIdentifiers()。
]]></description>
			<content:encoded><![CDATA[<p>我在测试twitter的API时，在它返回的用户信息里，关于用户时区的信息有两个</p>
<p>&lt;utc_offset&gt;28800&lt;/utc_offset&gt;<br />
&lt;time_zone&gt;Beijing&lt;/time_zone&gt;</p>
<p>我希望利用这两个数值，得到用户的的DateTimeZone，直接new DateTimeZone(&#8216;Beijing&#8217;)是不行的，我看了PHP的API，时区里是没有“Beijing”的，中国的时区应该是“Asia/Shanghai”，看来这个“Beijing”只是用来显示的，我又查了DateTimeZone的API，里面也没有根据UTC Offset值取得DateTimeZone的方法，看来不能通过这样的方法来做了。</p>
<p>utc_offset这个值是应该表示与UTC标准时间相差的秒数，测试下面的代码</p>
<p>$datetimezone = new DateTimeZone(&#8216;Asia/Shanghai&#8217;);<br />
$datetime = new DateTime(&#8220;now&#8221;,$datetimezone);<br />
echo $datetime-&gt;getOffset();</p>
<p>结果显示28800，没错，时区“Asia/Shanghai”与UTC的时间差是28800秒，也就是8个小时（我们在东8区）。</p>
<p>在PHP中使用time()或是DateTime对象，在不指定DateTimeZone时，其默认的DateTimeZone就是UTC，产生的时间就是UTC时间，把这个时间加上Offset值之后，就可以显示出本时区的正确时间了，比如下面的代码</p>
<p>$datetime = time();<br />
echo date(&#8220;y-m-d H:i:s&#8221;,$datetime);<br />
echo &#8220;&lt;br/&gt;&#8221;;<br />
$datetime = $datetime + 28800;<br />
echo date(&#8220;y-m-d H:i:s&#8221;,$datetime);</p>
<p>输入的结果是<br />
09-05-13 04:21:44<br />
09-05-13 12:21:44</p>
<p>上面是UTC的时间，而下面的是北京时间。</p>
<p>在我们设计数据的时候，时间字段设计为长整数字段比较方便，存放UTC的time()的Unix时间戳，用户可以自己定义所在的时区，通过Offset，最终显示给用户其时区的时间。我感觉Java里的TimeZone似乎要更灵活一些，可以这样TimeZone.getTimeZone(&#8220;GMT+08:00&#8243;)</p>
<p>另外：在PHP里取得所有可用时区的方法是DateTimeZone::listIdentifiers()。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/php-datetimezone.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sphinx+Mysql初使用体验</title>
		<link>http://i.laoer.com/sphinx-mysql.html</link>
		<comments>http://i.laoer.com/sphinx-mysql.html#comments</comments>
		<pubDate>Fri, 08 May 2009 06:44:02 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[Mysql]]></category>
		<category><![CDATA[Sphinx]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=311</guid>
		<description><![CDATA[应用越来越多的需要全文搜索技术来支撑，在Java中可以使用Lucene，一个非常优秀的引擎，在Hibernate中也整合了Lucene来做检索，但在使用PHP的过程中迫切需要找一个优秀的全文搜索引擎（虽然也可以把PHP和Lucene结合起来使用，但有些另类，有些生产环境也不能同时支持），以前在网上看到一些Sphinx的文章，一直没有实践，昨天我就花了一天的时间，配置测试了一下Sphinx。
由于我的PHP没有编译Sphinx模块，所以我主要是配置Sphinx+Mysql，在Mysql上测试全文搜索的效果，Mysql、Sphinx、中文分词的编译安装过程不详述，下面两篇文章挺好，安装时可以参考
Mysql+sphinx+中文分词简介
基于Sphinx+MySQL的千万级数据全文检索（搜索引擎）架构设计
我的编译安装过程没有遇到什么麻烦，就是编译Mysql的时候比较长，而且要注意把Innodb的引擎编译进去，我的Mysql编译参数如下
./configure &#8211;with-plugins=sphinx,innobase,heap &#8211;prefix=/usr/local/mysql &#8211;enable-assembler &#8211;with-charset=utf8 &#8211;with-extra-charsets=all &#8211;enable-thread-safe-client &#8211;with-big-tables &#8211;with-readline &#8211;with-ssl &#8211;with-embedded-server &#8211;enable-local-infile
比较奇怪的是innodb是支持了，heap不支持，这个问题下次再研究。
通过编译Mysql，使Mysql支持了Sphinx存储引擎，试了一下Sphinx的例子，成功搜索到了数据，如果我们要对自己的数据做索引，就要研究一下Sphinx的配置文件了。
Sphinx的配置文件在其安装目录下的etc目录下，你可以参考其例子的sphinx.conf创建自己的配置文件，在sphinx里有主要要配置的有两大块，一部分是source（数据源），另一部分是index（索引），source里面定义了连接数据库的参数，取得源数据的SQL，也就是你要索引的数据的取得 SQL（Sphinx是支持不同数据源的，我这里只测试SQL），source可以有继承关系，继承的source可以用来做取得增量数据，index里面定义了使用哪个source，index存放的路径、字符集、辞典等等，index也可以继承，继承的index用来做增量索引。由此可见source 和index都是根据你的需要配置的，可以取得多个数据源的数据，可以建立多个索引。
增量索引的小困惑，我在数据库中增加了2条记录，执行
/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1stemmed
看到有两个文档被加入索引（增量部分），之后我执行
/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;merge test1 test1stemmed &#8211;merge-dst-range deleted 0 0
将增量索引并入主索引，这是可以查询到新插入的数据，这时我再继续插入一条数据，执行
/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1stemmed
提示信息是有3个文档被加入索引，让我非常奇怪，因为上两条纪录已经并入主索引了，这次怎么还会索引呢？之后我执行
/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1
更新主索引，之后再执行/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1stemmed提示没有索引加入，这样就正确了，如果按照测试的结果，增量索引和主索引更新执行的时间要计划好。
关于中文分词&#8211;LibMMSeg：LibMMSeg 是Coreseek.com为 Sphinx 全文搜索引擎设计的中文分词软件包，其在GPL协议下发行的中文分词法，采用Chih-Hao Tsai的MMSEG算法。
同时Coreseek.com提供了一份Sphinx的中文文档，里面有比较详细的配置说明，是很好的参考资料，非常感谢开源人士做出的贡献。
]]></description>
			<content:encoded><![CDATA[<p>应用越来越多的需要全文搜索技术来支撑，在Java中可以使用Lucene，一个非常优秀的引擎，在Hibernate中也整合了Lucene来做检索，但在使用PHP的过程中迫切需要找一个优秀的全文搜索引擎（虽然也可以把PHP和Lucene结合起来使用，但有些另类，有些生产环境也不能同时支持），以前在网上看到一些<a href="http://www.sphinxsearch.com/" target="_blank">Sphinx</a>的文章，一直没有实践，昨天我就花了一天的时间，配置测试了一下Sphinx。</p>
<p>由于我的PHP没有编译Sphinx模块，所以我主要是配置Sphinx+Mysql，在Mysql上测试全文搜索的效果，Mysql、Sphinx、中文分词的编译安装过程不详述，下面两篇文章挺好，安装时可以参考</p>
<p><a href="http://www.cnblogs.com/hushixiu/articles/1295605.html" target="_blank">Mysql+sphinx+中文分词简介</a></p>
<p><a href="http://blog.s135.com/post/360/" target="_blank">基于Sphinx+MySQL的千万级数据全文检索（搜索引擎）架构设计</a></p>
<p>我的编译安装过程没有遇到什么麻烦，就是编译Mysql的时候比较长，而且要注意把Innodb的引擎编译进去，我的Mysql编译参数如下</p>
<p>./configure &#8211;with-plugins=sphinx,innobase,heap &#8211;prefix=/usr/local/mysql &#8211;enable-assembler &#8211;with-charset=utf8 &#8211;with-extra-charsets=all &#8211;enable-thread-safe-client &#8211;with-big-tables &#8211;with-readline &#8211;with-ssl &#8211;with-embedded-server &#8211;enable-local-infile</p>
<p>比较奇怪的是innodb是支持了，heap不支持，这个问题下次再研究。</p>
<p>通过编译Mysql，使Mysql支持了Sphinx存储引擎，试了一下Sphinx的例子，成功搜索到了数据，如果我们要对自己的数据做索引，就要研究一下Sphinx的配置文件了。</p>
<p>Sphinx的配置文件在其安装目录下的etc目录下，你可以参考其例子的sphinx.conf创建自己的配置文件，在sphinx里有主要要配置的有两大块，一部分是source（数据源），另一部分是index（索引），source里面定义了连接数据库的参数，取得源数据的SQL，也就是你要索引的数据的取得 SQL（Sphinx是支持不同数据源的，我这里只测试SQL），source可以有继承关系，继承的source可以用来做取得增量数据，index里面定义了使用哪个source，index存放的路径、字符集、辞典等等，index也可以继承，继承的index用来做增量索引。由此可见source 和index都是根据你的需要配置的，可以取得多个数据源的数据，可以建立多个索引。</p>
<p>增量索引的小困惑，我在数据库中增加了2条记录，执行</p>
<p>/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1stemmed</p>
<p>看到有两个文档被加入索引（增量部分），之后我执行</p>
<p>/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;merge test1 test1stemmed &#8211;merge-dst-range deleted 0 0</p>
<p>将增量索引并入主索引，这是可以查询到新插入的数据，这时我再继续插入一条数据，执行</p>
<p>/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1stemmed</p>
<p>提示信息是有3个文档被加入索引，让我非常奇怪，因为上两条纪录已经并入主索引了，这次怎么还会索引呢？之后我执行</p>
<p>/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1</p>
<p>更新主索引，之后再执行/usr/local/sphinx/bin/indexer &#8211;rotate &#8211;config /usr/local/sphinx/etc/sphinx.conf test1stemmed提示没有索引加入，这样就正确了，如果按照测试的结果，增量索引和主索引更新执行的时间要计划好。</p>
<p>关于中文分词&#8211;<a href="http://www.coreseek.com/opensource/mmseg/" target="_blank">LibMMSeg</a>：LibMMSeg 是Coreseek.com为 Sphinx 全文搜索引擎设计的中文分词软件包，其在GPL协议下发行的中文分词法，采用<a href="http://chtsai.org/" target="_blank">Chih-Hao Tsai</a>的MMSEG算法。</p>
<p>同时Coreseek.com提供了一份Sphinx的<a href="http://www.coreseek.com/uploads/pdf/sphinx_doc_zhcn_0.9.pdf" target="_blank">中文文档</a>，里面有比较详细的配置说明，是很好的参考资料，非常感谢开源人士做出的贡献。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/sphinx-mysql.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Short Url（短网址）实现方式</title>
		<link>http://i.laoer.com/short-url.html</link>
		<comments>http://i.laoer.com/short-url.html#comments</comments>
		<pubDate>Mon, 27 Apr 2009 06:18:43 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[Short Url]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=306</guid>
		<description><![CDATA[现在提供Short Url(短网址)的网站越来越多了，特别是Twitter的助Short Url的一臂之力，越来越多的人开始使用Short Url-短网址，现在比较流行的几个Short Url网站有
TinyURL
http://tinyurl.com/
Bit.Ly
http://bit.ly/
Is.Gd
http://is.gd/
等等，Short Url的作用在于把长的Url缩成短的Url，比如，我前两天些的一篇博客，Url是http://i.laoer.com/think-about-http-get-chinese-encode-error.html，我们采用TinyURL，转成的Url是http://tinyurl.com/d4zw8x，只有25个字符，短了很多，请求http://tinyurl.com/d4zw8x的时候，tinyurl会把请求通过HTTP 301转到http://i.laoer.com/think-about-http-get-chinese-encode-error.html上。
实现Short Url的功能并不复杂，但最关键的就是这个短代码要够短，而且需要唯一，我们的例子是“d4zw8x”，6位，还有就是用户输入的同一个Url，应该返回唯一的Short Url，用户在请求长的Url之后，先从数据库查找一下这个长Url是否存在，如果存在，就直接取出其对应的短代码，如果不存在，则生成短代码，与用户的长Url同时保存在数据库中。
最核心的这个短代码的实现方式，我在网上找了两个
第一个是纯随机数的算法，来自Short URL Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function random&#40;$length, $pool = ''&#41;
    &#123;
        $random = '';
&#160;
        if &#40;empty&#40;$pool&#41;&#41; &#123;
            $pool    = [...]]]></description>
			<content:encoded><![CDATA[<p>现在提供Short Url(短网址)的网站越来越多了，特别是Twitter的助Short Url的一臂之力，越来越多的人开始使用Short Url-短网址，现在比较流行的几个Short Url网站有</p>
<p>TinyURL<br />
<a href="http://tinyurl.com/" target="_blank">http://tinyurl.com/</a></p>
<p>Bit.Ly<br />
<a href="http://bit.ly/" target="_blank">http://bit.ly/</a></p>
<p>Is.Gd<br />
<a href="http://is.gd/" target="_blank">http://is.gd/</a></p>
<p>等等，Short Url的作用在于把长的Url缩成短的Url，比如，我前两天些的一篇博客，Url是http://i.laoer.com/think-about-http-get-chinese-encode-error.html，我们采用TinyURL，转成的Url是http://tinyurl.com/d4zw8x，只有25个字符，短了很多，请求http://tinyurl.com/d4zw8x的时候，tinyurl会把请求通过HTTP 301转到http://i.laoer.com/think-about-http-get-chinese-encode-error.html上。</p>
<p>实现Short Url的功能并不复杂，但最关键的就是这个短代码要够短，而且需要唯一，我们的例子是“d4zw8x”，6位，还有就是用户输入的同一个Url，应该返回唯一的Short Url，用户在请求长的Url之后，先从数据库查找一下这个长Url是否存在，如果存在，就直接取出其对应的短代码，如果不存在，则生成短代码，与用户的长Url同时保存在数据库中。</p>
<p>最核心的这个短代码的实现方式，我在网上找了两个</p>
<p>第一个是纯随机数的算法，来自<a href="http://www.gentlesource.com/" target="_blank">Short URL Script</a></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> random<span style="color: #009900;">&#40;</span><span style="color: #000088;">$length</span><span style="color: #339933;">,</span> <span style="color: #000088;">$pool</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$random</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pool</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$pool</span>    <span style="color: #339933;">=</span> <span style="color: #0000ff;">'abcdefghkmnpqrstuvwxyz'</span><span style="color: #339933;">;</span>
            <span style="color: #000088;">$pool</span>   <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'23456789'</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #990000;">srand</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>double<span style="color: #009900;">&#41;</span><span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">1000000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$length</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> 
        <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$random</span> <span style="color: #339933;">.=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pool</span><span style="color: #339933;">,</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">%</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strlen</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pool</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</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: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$random</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>另一个算法来自<a href="http://www.snippetit.com/2009/04/php-short-url-algorithm-implementation/" target="_blank">http://www.snippetit.com/2009/04/php-short-url-algorithm-implementation/</a></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> shorturl<span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$base32</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span> <span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'a'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'b'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'c'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'d'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'e'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'f'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'h'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'i'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'j'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'k'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'l'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'m'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'n'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'o'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'p'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'q'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'s'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'t'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'u'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'v'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'w'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'x'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'y'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'z'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'1'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'2'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'3'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'4'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'5'</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$hex</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$input</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$hexLen</span> <span style="color: #339933;">=</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$hex</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$subHexLen</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$hexLen</span> <span style="color: #339933;">/</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #000088;">$subHexLen</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$subHex</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$hex</span><span style="color: #339933;">,</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">*</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$int</span> <span style="color: #339933;">=</span> <span style="color: #208080;">0x3FFFFFFF</span> <span style="color: #339933;">&amp;</span> <span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span> <span style="color: #339933;">*</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'0x'</span><span style="color: #339933;">.</span><span style="color: #000088;">$subHex</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$out</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">6</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$val</span> <span style="color: #339933;">=</span> <span style="color: #208080;">0x0000001F</span> <span style="color: #339933;">&amp;</span> <span style="color: #000088;">$int</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$out</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$base32</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$val</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$int</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$int</span> <span style="color: #339933;">&gt;&gt;</span> <span style="color: #cc66cc;">5</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000088;">$output</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$out</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>其返回的是一个4个元素的数组，应为存在可能的重复性，你可以依次使用这4个元素。</p>
<p>Short Url的算法应该还有一些，Short Url网站的作用除了缩短网址以外，在使用者不断增加之后，可以积累庞大的网址信息，这对统计分析是很有用的。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/short-url.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Kohana的Cache</title>
		<link>http://i.laoer.com/kohana-cache-memcached.html</link>
		<comments>http://i.laoer.com/kohana-cache-memcached.html#comments</comments>
		<pubDate>Wed, 15 Apr 2009 09:42:25 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Kohana]]></category>
		<category><![CDATA[Memcached]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=274</guid>
		<description><![CDATA[Kohana里有个Cache Library，我今天就测试了一下。
首先要配置，将system/config下的cache.php复制到application/config下，打开cache.php文件，我们看一下内容

1
2
3
4
5
6
7
$config&#91;'default'&#93; = array
&#40;
    'driver'   =&#62; 'file',
    'params'   =&#62; APPPATH.'cache',
    'lifetime' =&#62; 1800,
    'requests' =&#62; 1000
&#41;;

这是一个默认配置，&#8217;driver&#8217;为驱动的缓存方式，Kohana支持6种不同的驱动，分别是File、SQlite、Memcache、APC、Eaccelerator、Xcache，配置文件默认使用的file，其原理是，写缓存时把对象序列化写入文件，读缓存时从文件读出文本反序列化，所以在文件方式下，缓存是基于I/O的，在文件多而且大的时候，性能会有下降， &#8216;params&#8217;是驱动参数，在file驱动模式下，就是cache文件路径，&#8217;lifetime&#8217;是cache的生命周期，单位为秒，超过这个时间，内容将被清除（设置为0代表不自动清除），&#8217;requests&#8217;为在达到请求数量之前自动垃圾回收。
在应用中，可能需要不止一个缓存，所以可以配置多个缓存，增加$config数组即可，还有在file方式下可以为每个缓存设置单独文件路径，但前提是文件路径要存在，例如我们增加一个

1
2
3
4
5
6
7
$config&#91;'my'&#93; = array
&#40;
    'driver'   =&#62; 'file',
    'params'   =&#62; APPPATH.'cache/my',
    'lifetime' [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Kohana" href="http://kohanaphp.com/" target="_blank">Kohana</a>里有个Cache Library，我今天就测试了一下。</p>
<p>首先要配置，将system/config下的cache.php复制到application/config下，打开cache.php文件，我们看一下内容</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'default'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'driver'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'file'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'params'</span>   <span style="color: #339933;">=&gt;</span> APPPATH<span style="color: #339933;">.</span><span style="color: #0000ff;">'cache'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'lifetime'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1800</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'requests'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1000</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>这是一个默认配置，&#8217;driver&#8217;为驱动的缓存方式，Kohana支持6种不同的驱动，分别是File、SQlite、Memcache、APC、Eaccelerator、Xcache，配置文件默认使用的file，其原理是，写缓存时把对象序列化写入文件，读缓存时从文件读出文本反序列化，所以在文件方式下，缓存是基于I/O的，在文件多而且大的时候，性能会有下降， &#8216;params&#8217;是驱动参数，在file驱动模式下，就是cache文件路径，&#8217;lifetime&#8217;是cache的生命周期，单位为秒，超过这个时间，内容将被清除（设置为0代表不自动清除），&#8217;requests&#8217;为在达到请求数量之前自动垃圾回收。</p>
<p>在应用中，可能需要不止一个缓存，所以可以配置多个缓存，增加$config数组即可，还有在file方式下可以为每个缓存设置单独文件路径，但前提是文件路径要存在，例如我们增加一个</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'my'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'driver'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'file'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'params'</span>   <span style="color: #339933;">=&gt;</span> APPPATH<span style="color: #339933;">.</span><span style="color: #0000ff;">'cache/my'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'lifetime'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1800</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'requests'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1000</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>接下来我们在Controller里调用cache</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Mycache_Controller <span style="color: #000000; font-weight: bold;">extends</span> Controller <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$mychache</span> <span style="color: #339933;">=</span> Cache<span style="color: #339933;">::</span><span style="color: #004000;">instance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;my&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$mychache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;laoer&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;OK&quot;</span><span style="color: #339933;">;</span>   
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$mychache</span><span style="color: #339933;">=</span> Cache<span style="color: #339933;">::</span><span style="color: #004000;">instance</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;my&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$mychache</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>   
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Cache::instance(&#8220;my&#8221;)实例化配置里$config['my']的cache，如果用Cache::instance()就是实例化配置里$config['default']的cache，在浏览器里执行，已经可以存取了，在application/cache/my/文件下可以看到一个名为&#8221;name~~0&#8243;的文件，里面就是序列化的数据。</p>
<p>文件cache还是有一定的局限性，现在越来越的网站开始使用<a href="http://www.danga.com/memcached/" target="_blank">Memcached</a>所谓缓存的解决方案，Kohana的缓存驱动里，有Memcached的支持，但它的文档却没有给出Memcached的配置例子，看来要自己摸索一下。</p>
<p>将system/config下的cache_memcache.php复制到application/config下，cache_memcache.php的内容如下</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * @package  Cache:Memcache
 *
 * memcache server configuration.
 */</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'servers'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
	<span style="color: #990000;">array</span>
	<span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'host'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'127.0.0.1'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'port'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">11211</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'persistent'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Enable cache data compression.
 */</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'compression'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">FALSE</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>根据你自己的情况修改Memcached的服务地址和端口，在application/config/cache.php里再加一段</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mem'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span>
<span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'driver'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'memcache'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'params'</span>   <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'lifetime'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1800</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'requests'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1000</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>在Controller里把Cache::instance(&#8220;my&#8221;)改为Cache::instance(&#8220;mem&#8221;)，运行看看结果，已经可以从Memcahced里存取了。</p>
<p>Kohana的Memcached驱动还是有些缺陷，现在只能使用一组Memcached，即$config['servers']这个参数，我觉得Memcacahed组也应该是多个，因为从业务角度会根据功能对cache做划分，我大概看了一下system/libraries/drivers/Cache/Memcache.php文件，应该是可以改造的，还有一点，编译PHP的时候要安装Memcached的支持。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/kohana-cache-memcached.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP SOAP实践</title>
		<link>http://i.laoer.com/php-soap-webservice.html</link>
		<comments>http://i.laoer.com/php-soap-webservice.html#comments</comments>
		<pubDate>Fri, 27 Mar 2009 07:00:56 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[Web Service]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=215</guid>
		<description><![CDATA[我现在公司里的系统都是SOA/面向服务架构的，用Java编写的Web Service，理论上Web Service支持异构语言的，我想测试一下用PHP来调用Java的Web Service是否方便。
首先用Java建立一个Web Service服务端（用CXF，JAX-WS实现），下面是公布出来的WSDL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
&#60;?xml version='1.0' encoding='UTF-8'?&#62;&#60;wsdl:definitions name=&#34;SampleWebService&#34; targetNamespace=&#34;http://www.abc.net/WS/2008&#34; xmlns:ns1=&#34;http://webservice.passport.abc.net/&#34; xmlns:soap=&#34;http://schemas.xmlsoap.org/wsdl/soap/&#34; xmlns:tns=&#34;http://www.abc.net/WS/2008&#34; xmlns:wsdl=&#34;http://schemas.xmlsoap.org/wsdl/&#34; xmlns:xsd=&#34;http://www.w3.org/2001/XMLSchema&#34;&#62;
  &#60;wsdl:import location=&#34;http://192.168.19.42:8080/sample/service/SampleWebService?wsdl=SampleWebService.wsdl&#34; namespace=&#34;http://webservice.passport.abc.net/&#34;&#62;
    &#60;/wsdl:import&#62;
  &#60;wsdl:message name=&#34;helloUser&#34;&#62;
    &#60;wsdl:part element=&#34;ns1:helloUser&#34; name=&#34;parameters&#34;&#62;
    &#60;/wsdl:part&#62;
  &#60;/wsdl:message&#62;
  &#60;wsdl:message name=&#34;helloUserResponse&#34;&#62;
    &#60;wsdl:part element=&#34;ns1:helloUserResponse&#34; name=&#34;parameters&#34;&#62;
    &#60;/wsdl:part&#62;
  &#60;/wsdl:message&#62;
  &#60;wsdl:binding name=&#34;SampleWebServiceSoapBinding&#34; [...]]]></description>
			<content:encoded><![CDATA[<p>我现在公司里的系统都是SOA/面向服务架构的，用Java编写的Web Service，理论上Web Service支持异构语言的，我想测试一下用PHP来调用Java的Web Service是否方便。</p>
<p>首先用Java建立一个Web Service服务端（用<a href="http://cxf.apache.org/" target="_blank">CXF</a>，JAX-WS实现），下面是公布出来的WSDL</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">'1.0'</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">'UTF-8'</span><span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #000000; font-weight: bold;">&lt;wsdl:definitions</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;SampleWebService&quot;</span> <span style="color: #000066;">targetNamespace</span>=<span style="color: #ff0000;">&quot;http://www.abc.net/WS/2008&quot;</span> <span style="color: #000066;">xmlns:ns1</span>=<span style="color: #ff0000;">&quot;http://webservice.passport.abc.net/&quot;</span> <span style="color: #000066;">xmlns:soap</span>=<span style="color: #ff0000;">&quot;http://schemas.xmlsoap.org/wsdl/soap/&quot;</span> <span style="color: #000066;">xmlns:tns</span>=<span style="color: #ff0000;">&quot;http://www.abc.net/WS/2008&quot;</span> <span style="color: #000066;">xmlns:wsdl</span>=<span style="color: #ff0000;">&quot;http://schemas.xmlsoap.org/wsdl/&quot;</span> <span style="color: #000066;">xmlns:xsd</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:import</span> <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;http://192.168.19.42:8080/sample/service/SampleWebService?wsdl=SampleWebService.wsdl&quot;</span> <span style="color: #000066;">namespace</span>=<span style="color: #ff0000;">&quot;http://webservice.passport.abc.net/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:import<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:message</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;helloUser&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:part</span> <span style="color: #000066;">element</span>=<span style="color: #ff0000;">&quot;ns1:helloUser&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;parameters&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:part<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:message</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;helloUserResponse&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:part</span> <span style="color: #000066;">element</span>=<span style="color: #ff0000;">&quot;ns1:helloUserResponse&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;parameters&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:part<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:message<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:binding</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;SampleWebServiceSoapBinding&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;ns1:SampleWebService&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:binding</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;document&quot;</span> <span style="color: #000066;">transport</span>=<span style="color: #ff0000;">&quot;http://schemas.xmlsoap.org/soap/http&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:operation</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;helloUser&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:operation</span> <span style="color: #000066;">soapAction</span>=<span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #000066;">style</span>=<span style="color: #ff0000;">&quot;document&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:input</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;helloUser&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:body</span> <span style="color: #000066;">use</span>=<span style="color: #ff0000;">&quot;literal&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:input<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:output</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;helloUserResponse&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:body</span> <span style="color: #000066;">use</span>=<span style="color: #ff0000;">&quot;literal&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:output<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:operation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:service</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;SampleWebService&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:port</span> <span style="color: #000066;">binding</span>=<span style="color: #ff0000;">&quot;tns:SampleWebServiceSoapBinding&quot;</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;SampleWebServicePort&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:address</span> <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;http://192.168.19.42:8080/sample/service/SampleWebService&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:service<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:definitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>这个Web Service有个“helloUser”方法，传入一个参数，它返回一段文本“Hello 参数!”，</p>
<p>PHP5之后已经加入了SOAP的支持，我最开始用PHP5的SOAP函数来调用，下面是代码</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> SoapClient<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://192.168.19.42:8080/sample/service/SampleWebService?wsdl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span>__getFunctions<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>但报错Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: &lt;message&gt; &#8216;helloUser&#8217; already defined in &#8230;，我搜了PHP网站上的相关文档也没找到答案，没办法，我只能找其他SOAP的组件，找到了<a href="http://sourceforge.net/projects/nusoap/" target="_blank">NuSOAP</a>，它最近发布的版本是0.7.3，是在2007年发布的，现在已经2009了，用用试试吧，参考nusoap的例子，写好自己代码</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'nusoap.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> nusoap_client<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://192.168.19.42:8080/sample/service/SampleWebService?wsdl'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'wsdl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$err</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getError</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$err</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Constructor error&lt;/h2&gt;&lt;p&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$err</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$param</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'arg0'</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">'laoer'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">call</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'helloUser'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'parameters'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$param</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;http://webservice.passport.abc.net/&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;document&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;literal&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fault</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Fault&lt;/h2&gt;&lt;p&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">print_r</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// Check for errors</span>
	<span style="color: #000088;">$err</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getError</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$err</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Display the error</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Error&lt;/h2&gt;&lt;p&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$err</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Display the result</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Result&lt;/h2&gt;&lt;p&gt;'</span><span style="color: #339933;">;</span>
		<span style="color: #666666; font-style: italic;">//print_r($result);</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$result</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;return&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Request&lt;/h2&gt;&lt;p&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">htmlspecialchars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">request</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;h2&gt;Response&lt;/h2&gt;&lt;p&gt;'</span> <span style="color: #339933;">.</span> <span style="color: #990000;">htmlspecialchars</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">response</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">ENT_QUOTES</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>执行结果</p>
<p>Result<br />
Hello laoer!</p>
<p>Request<br />
POST /sample/service/SampleWebService HTTP/1.0<br />
Host: 192.168.19.42:8080<br />
User-Agent: NuSOAP/0.7.3 (1.114)<br />
Content-Type: text/xml; charset=UTF-8<br />
SOAPAction: &#8220;&#8221;<br />
Content-Length: 436</p>
<p>我们可以看到Request的SOAP文本</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;SOAP-ENV:Envelope</span> <span style="color: #000066;">xmlns:SOAP-ENV</span>=<span style="color: #ff0000;">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span> <span style="color: #000066;">xmlns:xsd</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema&quot;</span> <span style="color: #000066;">xmlns:xsi</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span> <span style="color: #000066;">xmlns:SOAP-ENC</span>=<span style="color: #ff0000;">&quot;http://schemas.xmlsoap.org/soap/encoding/&quot;</span> <span style="color: #000066;">xmlns:ns1</span>=<span style="color: #ff0000;">&quot;http://webservice.passport.abc.net/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;SOAP-ENV:Body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;helloUser</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;arg0</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>laoer<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/arg0<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/helloUser<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/SOAP-ENV:Body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/SOAP-ENV:Envelope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>Response<br />
HTTP/1.1 200 OK<br />
Server: Apache-Coyote/1.1<br />
SOAPAction: &#8220;&#8221;<br />
Content-Type: text/xml;charset=UTF-8<br />
Content-Length: 237<br />
Date: Fri, 27 Mar 2009 04:27:11 GMT<br />
Connection: close</p>
<p>Response的SOAP文本</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:Envelope</span> <span style="color: #000066;">xmlns:soap</span>=<span style="color: #ff0000;">&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:Body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ns2:helloUserResponse</span> <span style="color: #000066;">xmlns:ns2</span>=<span style="color: #ff0000;">&quot;http://webservice.passport.abc.net/&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
			<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;return<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Hello laoer!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/return<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
		<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ns2:helloUserResponse<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
	<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/soap:Body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/soap:Envelope<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></td></tr></table></div>

<p>碰到一个小问题就是PHP给方法传参数，看是我不知道怎么填，后来我用soapUI，做了一个SOAP Request的例子，发现参数的Name是arg0，如果是多个参数，则arg0、arg1、arg2&#8230;以此类推，所以我们定义的参数是$param = array(&#8216;arg0&#8242;=>&#8217;laoer&#8217;)，还有就是nusoap里对返回信息的编码有点问题，如果你Web Service放回的编码是UTF-8，则nusoap多转换了一次，在nusoap.php文件nusoap_client类里把$decode_utf8置为false就可以了。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/php-soap-webservice.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP RSA研究</title>
		<link>http://i.laoer.com/php-rsa.html</link>
		<comments>http://i.laoer.com/php-rsa.html#comments</comments>
		<pubDate>Thu, 19 Mar 2009 09:19:05 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[RSA]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=183</guid>
		<description><![CDATA[最近研究了一下QQ邮箱的登录过程，发现QQ邮箱登录比较严谨，加了一些小技巧，其中一点就是用JavaScript对用户的密码做了一下RSA的加密，在它的登录页面里有一段

1
2
3
4
5
6
7
8
var PublicKey = &#34;CF87D7B4C864F4842F1D337491A48FFF54B73A17300E8E42FA365420393AC0346AE55D8AFAD975DFA175FAF0106CBA81AF1DDE4ACEC284DAC6ED9A0D8FEB1CC070733C58213EFFED46529C54CEA06D774E3CC7E073346AEBD6C66FC973F299EB74738E400B22B1E7CDC54E71AED059D228DFEB5B29C530FF341502AE56DDCFE9&#34;;
var RSA = new RSAKey&#40;&#41;;
RSA.setPublic&#40;PublicKey, &#34;10001&#34;&#41;;
var Res = RSA.encrypt&#40;document.form1.pp.value + '\n' + document.form1.ts.value + '\n'&#41;;
if &#40;Res&#41;
&#123;
document.form1.p.value = hex2b64&#40;Res&#41;;
&#125;

再看看RSAKey的相关源码，应该是在http://m367.mail.qq.com/zh_CN/htmledition/js/safeauth.js里，看了一下还是蛮复杂的，我就在Google上搜一下有没有相关的资料，找到了这个网站《BigIntegers and RSA in JavaScript》，看了一下他们的代码，和QQ里的基本一样嘛，估计QQ也是用了人家的代码，这篇文章里有密钥对的生成、加密解密的测试页面，由此推断QQ代码里的PublicKey，应该是密钥对的modulus（也可以理解为公钥吧），并且QQ用的是1024位的密钥，那我们是否可以用这个modulus，使用别的语言（比如PHP）来做密码加密呢？
想到就做，我在Google上搜索一下“PHP RSA”，找到了这个网站http://www.edsko.net/misc/，里面有PHP RSA的实现，不过我对它的rsa_encrypt($message, $public_key, $modulus, $keylength)方法产生了疑惑，它有4个参数，第一个是要加密的字串，那后面三个怎么填，我们现在仅知道的就是modulus了，而$public_key和$keylength从何而来呢，真有点摸不着头脑了，还是看看它带的例子吧，原来它例子里是从密钥对文件中取得相关的信息，QQ的密钥对文件自然取不到，那我只能自己生成一个密钥对文件，来看看有什么规律吧，在Linux下用openssl做
openssl genrsa -out key.pem 1024
生成了一个1024位的密钥对文件，可以打开看看，里面应该是Base64编码的，之后我们通过下面的命令可以得到modulus

1
2
openssl rsa -in key.pem -noout -modulus
Modulus=D192471B8699640F931FE6F4FACC3E990B894F894CEA5BEE0DCBD7A4B76752F7345CF9B5F1271001B724F7A0ABF0A6E911E309536F4BE4749E92DCC531B8E36B95969D206649C9DD2371B413A8DFD9B92569660B1499A5CD310B86A8FDE24988E456897A416D2E7B0B649F0714F322C57EF92563B21A448D1072FF3806C34C75

比照QQ的，位数是一样的，接下来我们用命令
openssl rsa -in key.pem -text -noout
输出的内容如下：
Private-Key: (1024 bit)
modulus:
00:d1:92:47:1b:86:99:64:0f:93:1f:e6:f4:fa:cc:
3e:99:0b:89:4f:89:4c:ea:5b:ee:0d:cb:d7:a4:b7:
67:52:f7:34:5c:f9:b5:f1:27:10:01:b7:24:f7:a0:
ab:f0:a6:e9:11:e3:09:53:6f:4b:e4:74:9e:92:dc:
c5:31:b8:e3:6b:95:96:9d:20:66:49:c9:dd:23:71:
b4:13:a8:df:d9:b9:25:69:66:0b:14:99:a5:cd:31:
0b:86:a8:fd:e2:49:88:e4:56:89:7a:41:6d:2e:7b:
0b:64:9f:07:14:f3:22:c5:7e:f9:25:63:b2:1a:44:
8d:10:72:ff:38:06:c3:4c:75
publicExponent: 65537 (0&#215;10001)
privateExponent:
00:83:d3:d9:08:f6:95:3c:bd:13:56:29:09:07:4e:
3d:3e:36:64:8c:74:98:be:7f:4f:72:bc:3c:0c:f0:
15:7d:b9:e4:e5:6b:6a:c8:a4:42:cc:61:71:4e:97:
72:30:f2:3d:80:33:e9:a4:e3:48:c1:0f:9e:c4:51:
3d:75:f6:90:8e:f3:c3:f8:ce:45:59:2a:67:42:a8:
c6:d0:4c:1d:12:c4:cf:53:f8:b1:58:b4:e1:23:71:
0e:e9:e9:e0:40:3d:9a:99:e3:5f:e1:93:04:e2:0a:
60:34:77:56:be:f9:8f:e6:4e:87:23:46:48:ba:38:
9d:dd:46:ce:20:b7:82:27:cd
prime1:
00:ee:a9:e4:70:9c:d4:fe:bf:cd:87:5c:00:cb:ea:
ef:82:92:e1:88:f7:99:6a:42:09:f4:fd:78:93:bd:
30:28:1f:2e:ed:c1:cd:d3:60:8b:34:52:89:a7:ac:
98:37:cd:96:81:1e:57:2f:46:08:0e:8d:fb:13:92:
8d:f5:7a:50:5f
prime2:
00:e0:cb:65:5e:31:f2:3b:c0:7f:93:ae:d9:6c:35:
75:e5:ce:8b:37:7d:39:ce:82:dd:9b:43:00:09:a6:
d8:c1:ab:bc:10:fe:3d:56:34:fe:bd:38:fe:fc:6c:
f2:74:a8:d6:40:25:e5:5a:35:7b:d0:24:71:44:8d:
53:23:71:83:ab
exponent1:
4b:d5:7f:d8:a8:7c:a5:55:9c:a0:de:03:02:c8:6b:
c2:39:99:a0:43:cc:63:8f:08:4a:e8:1f:60:12:45:
32:fa:75:96:e6:75:d8:2c:5d:0f:0b:0a:e2:54:5d:
29:9e:11:ac:85:4f:7e:9d:ea:01:75:eb:c9:94:4f:
b7:28:5e:51
exponent2:
00:9b:9f:d4:56:a8:e7:55:3c:88:55:fa:97:a5:55:
41:80:ce:44:0d:2f:51:a4:c9:6e:97:fd:83:7a:2b:
1b:26:c1:38:da:de:d8:21:e5:60:72:29:92:45:b9:
3b:05:4e:99:bd:21:3f:2d:fb:96:f2:db:37:db:48:
a7:c5:02:e2:2f
coefficient:
00:c2:75:38:a5:02:24:39:1e:0e:e9:ec:56:6a:31:
5d:38:82:ca:3e:9b:67:cb:40:7e:7b:2f:91:26:bb:
4e:64:3d:60:53:f1:21:67:8b:b7:af:f8:2e:95:f7:
af:cf:42:75:ab:6c:5c:42:97:42:17:94:17:ff:e0:
b9:cb:c9:e8:6d
通过它例子的代码，我明白了，$public_key应该是1024，$keylength就是65537，$modulus不能直接用这段文字，要先转成BigInteger，再转成文本传进去，BigInteger实现在PEAR里有，http://pear.php.net/package/Math_BigInteger
我们接下来就写程序吧

1
2
3
4
5
6
7
8
9
10
11
include&#40;'rsa.php'&#41;;
include&#40;'BigInteger.php'&#41;;
&#160;
$public = 65537;
$modulus = &#34;D192471B8699640F931FE6F4FACC3E990B894F894CEA5BEE0DCBD7A4B76752F7345CF9B5F1271001B724F7A0ABF0A6E911E309536F4BE4749E92DCC531B8E36B95969D206649C9DD2371B413A8DFD9B92569660B1499A5CD310B86A8FDE24988E456897A416D2E7B0B649F0714F322C57EF92563B21A448D1072FF3806C34C75&#34;;
$keylength = 1024;
$modulus_16 = [...]]]></description>
			<content:encoded><![CDATA[<p>最近研究了一下QQ邮箱的登录过程，发现QQ邮箱登录比较严谨，加了一些小技巧，其中一点就是用JavaScript对用户的密码做了一下RSA的加密，在它的登录页面里有一段</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> PublicKey <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;CF87D7B4C864F4842F1D337491A48FFF54B73A17300E8E42FA365420393AC0346AE55D8AFAD975DFA175FAF0106CBA81AF1DDE4ACEC284DAC6ED9A0D8FEB1CC070733C58213EFFED46529C54CEA06D774E3CC7E073346AEBD6C66FC973F299EB74738E400B22B1E7CDC54E71AED059D228DFEB5B29C530FF341502AE56DDCFE9&quot;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> RSA <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> RSAKey<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
RSA.<span style="color: #660066;">setPublic</span><span style="color: #009900;">&#40;</span>PublicKey<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;10001&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> Res <span style="color: #339933;">=</span> RSA.<span style="color: #660066;">encrypt</span><span style="color: #009900;">&#40;</span>document.<span style="color: #660066;">form1</span>.<span style="color: #660066;">pp</span>.<span style="color: #660066;">value</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span> <span style="color: #339933;">+</span> document.<span style="color: #660066;">form1</span>.<span style="color: #660066;">ts</span>.<span style="color: #660066;">value</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'<span style="color: #000099; font-weight: bold;">\n</span>'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>Res<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
document.<span style="color: #660066;">form1</span>.<span style="color: #660066;">p</span>.<span style="color: #660066;">value</span> <span style="color: #339933;">=</span> hex2b64<span style="color: #009900;">&#40;</span>Res<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>再看看RSAKey的相关源码，应该是在http://m367.mail.qq.com/zh_CN/htmledition/js/safeauth.js里，看了一下还是蛮复杂的，我就在Google上搜一下有没有相关的资料，找到了这个网站<a href="http://www-cs-students.stanford.edu/~tjw/jsbn/" target="_blank">《BigIntegers and RSA in JavaScript》</a>，看了一下他们的代码，和QQ里的基本一样嘛，估计QQ也是用了人家的代码，这篇文章里有密钥对的生成、加密解密的测试页面，由此推断QQ代码里的PublicKey，应该是密钥对的modulus（也可以理解为公钥吧），并且QQ用的是1024位的密钥，那我们是否可以用这个modulus，使用别的语言（比如PHP）来做密码加密呢？</p>
<p>想到就做，我在Google上搜索一下“PHP RSA”，找到了这个网站<a href="http://www.edsko.net/misc/" target="_blank">http://www.edsko.net/misc/</a>，里面有PHP RSA的实现，不过我对它的rsa_encrypt($message, $public_key, $modulus, $keylength)方法产生了疑惑，它有4个参数，第一个是要加密的字串，那后面三个怎么填，我们现在仅知道的就是modulus了，而$public_key和$keylength从何而来呢，真有点摸不着头脑了，还是看看它带的例子吧，原来它例子里是从密钥对文件中取得相关的信息，QQ的密钥对文件自然取不到，那我只能自己生成一个密钥对文件，来看看有什么规律吧，在Linux下用openssl做</p>
<p>openssl genrsa -out key.pem 1024</p>
<p>生成了一个1024位的密钥对文件，可以打开看看，里面应该是Base64编码的，之后我们通过下面的命令可以得到modulus</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">openssl rsa <span style="color: #660033;">-in</span> key.pem <span style="color: #660033;">-noout</span> <span style="color: #660033;">-modulus</span>
<span style="color: #007800;">Modulus</span>=D192471B8699640F931FE6F4FACC3E990B894F894CEA5BEE0DCBD7A4B76752F7345CF9B5F1271001B724F7A0ABF0A6E911E309536F4BE4749E92DCC531B8E36B95969D206649C9DD2371B413A8DFD9B92569660B1499A5CD310B86A8FDE24988E456897A416D2E7B0B649F0714F322C57EF92563B21A448D1072FF3806C34C75</pre></td></tr></table></div>

<p>比照QQ的，位数是一样的，接下来我们用命令</p>
<p>openssl rsa -in key.pem -text -noout</p>
<p>输出的内容如下：<br />
Private-Key: (1024 bit)<br />
modulus:<br />
00:d1:92:47:1b:86:99:64:0f:93:1f:e6:f4:fa:cc:<br />
3e:99:0b:89:4f:89:4c:ea:5b:ee:0d:cb:d7:a4:b7:<br />
67:52:f7:34:5c:f9:b5:f1:27:10:01:b7:24:f7:a0:<br />
ab:f0:a6:e9:11:e3:09:53:6f:4b:e4:74:9e:92:dc:<br />
c5:31:b8:e3:6b:95:96:9d:20:66:49:c9:dd:23:71:<br />
b4:13:a8:df:d9:b9:25:69:66:0b:14:99:a5:cd:31:<br />
0b:86:a8:fd:e2:49:88:e4:56:89:7a:41:6d:2e:7b:<br />
0b:64:9f:07:14:f3:22:c5:7e:f9:25:63:b2:1a:44:<br />
8d:10:72:ff:38:06:c3:4c:75<br />
publicExponent: 65537 (0&#215;10001)<br />
privateExponent:<br />
00:83:d3:d9:08:f6:95:3c:bd:13:56:29:09:07:4e:<br />
3d:3e:36:64:8c:74:98:be:7f:4f:72:bc:3c:0c:f0:<br />
15:7d:b9:e4:e5:6b:6a:c8:a4:42:cc:61:71:4e:97:<br />
72:30:f2:3d:80:33:e9:a4:e3:48:c1:0f:9e:c4:51:<br />
3d:75:f6:90:8e:f3:c3:f8:ce:45:59:2a:67:42:a8:<br />
c6:d0:4c:1d:12:c4:cf:53:f8:b1:58:b4:e1:23:71:<br />
0e:e9:e9:e0:40:3d:9a:99:e3:5f:e1:93:04:e2:0a:<br />
60:34:77:56:be:f9:8f:e6:4e:87:23:46:48:ba:38:<br />
9d:dd:46:ce:20:b7:82:27:cd<br />
prime1:<br />
00:ee:a9:e4:70:9c:d4:fe:bf:cd:87:5c:00:cb:ea:<br />
ef:82:92:e1:88:f7:99:6a:42:09:f4:fd:78:93:bd:<br />
30:28:1f:2e:ed:c1:cd:d3:60:8b:34:52:89:a7:ac:<br />
98:37:cd:96:81:1e:57:2f:46:08:0e:8d:fb:13:92:<br />
8d:f5:7a:50:5f<br />
prime2:<br />
00:e0:cb:65:5e:31:f2:3b:c0:7f:93:ae:d9:6c:35:<br />
75:e5:ce:8b:37:7d:39:ce:82:dd:9b:43:00:09:a6:<br />
d8:c1:ab:bc:10:fe:3d:56:34:fe:bd:38:fe:fc:6c:<br />
f2:74:a8:d6:40:25:e5:5a:35:7b:d0:24:71:44:8d:<br />
53:23:71:83:ab<br />
exponent1:<br />
4b:d5:7f:d8:a8:7c:a5:55:9c:a0:de:03:02:c8:6b:<br />
c2:39:99:a0:43:cc:63:8f:08:4a:e8:1f:60:12:45:<br />
32:fa:75:96:e6:75:d8:2c:5d:0f:0b:0a:e2:54:5d:<br />
29:9e:11:ac:85:4f:7e:9d:ea:01:75:eb:c9:94:4f:<br />
b7:28:5e:51<br />
exponent2:<br />
00:9b:9f:d4:56:a8:e7:55:3c:88:55:fa:97:a5:55:<br />
41:80:ce:44:0d:2f:51:a4:c9:6e:97:fd:83:7a:2b:<br />
1b:26:c1:38:da:de:d8:21:e5:60:72:29:92:45:b9:<br />
3b:05:4e:99:bd:21:3f:2d:fb:96:f2:db:37:db:48:<br />
a7:c5:02:e2:2f<br />
coefficient:<br />
00:c2:75:38:a5:02:24:39:1e:0e:e9:ec:56:6a:31:<br />
5d:38:82:ca:3e:9b:67:cb:40:7e:7b:2f:91:26:bb:<br />
4e:64:3d:60:53:f1:21:67:8b:b7:af:f8:2e:95:f7:<br />
af:cf:42:75:ab:6c:5c:42:97:42:17:94:17:ff:e0:<br />
b9:cb:c9:e8:6d</p>
<p>通过它例子的代码，我明白了，$public_key应该是1024，$keylength就是65537，$modulus不能直接用这段文字，要先转成BigInteger，再转成文本传进去，BigInteger实现在PEAR里有，<a href="http://pear.php.net/package/Math_BigInteger" target="_blank">http://pear.php.net/package/Math_BigInteger</a></p>
<p>我们接下来就写程序吧</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'rsa.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BigInteger.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$public</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">65537</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$modulus</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;D192471B8699640F931FE6F4FACC3E990B894F894CEA5BEE0DCBD7A4B76752F7345CF9B5F1271001B724F7A0ABF0A6E911E309536F4BE4749E92DCC531B8E36B95969D206649C9DD2371B413A8DFD9B92569660B1499A5CD310B86A8FDE24988E456897A416D2E7B0B649F0714F322C57EF92563B21A448D1072FF3806C34C75&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$keylength</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1024</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$modulus_16</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Math_BigInteger<span style="color: #009900;">&#40;</span><span style="color: #000088;">$modulus</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$mend</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$modulus_16</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$encrypted</span> <span style="color: #339933;">=</span> rsa_encrypt<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;test&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$public</span><span style="color: #339933;">,</span> <span style="color: #000088;">$mend</span><span style="color: #339933;">,</span> <span style="color: #000088;">$keylength</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #990000;">bin2hex</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$encrypted</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//这里也可以用Base64，QQ就是Base64</span></pre></td></tr></table></div>

<p>最后说一下我对于RSA的理解，首先生成了公钥/私钥的密钥对，之后把公钥发布出去，外部系统用公钥加密，传给内部系统用私钥解密。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/php-rsa.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>用Google API来取得Google帐户的联系人列表</title>
		<link>http://i.laoer.com/grab-google-contacts-by-google-api.html</link>
		<comments>http://i.laoer.com/grab-google-contacts-by-google-api.html#comments</comments>
		<pubDate>Thu, 12 Mar 2009 03:34:37 +0000</pubDate>
		<dc:creator>Laoer</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web2.0]]></category>
		<category><![CDATA[Google]]></category>

		<guid isPermaLink="false">http://i.laoer.com/?p=153</guid>
		<description><![CDATA[昨天写了一篇从Web Mail里取得用户通讯录的方法的文章，里面提到了Google的Account Authentication API，今天我们就用Account Authentication API和Google Contacts Data API来做一个取得Google帐户联系人的测试。
首先我们要看一下Account Authentication API，对于网络应用来说我们选择对网络应用程序的验证，对网络应用程序的验证也提供了 OAuth 和 AuthSub 两种认证方式，我们选择AuthSub的认证方式，认证过程如下图

用户在第三方Web应用上向Google Accounts Authentication发送AuthSub的HTTP请求，如果用户没有登录Google，则会显示登录页面，用户登录之后，会提示用户是否接受或拒绝这个第三方Web应用的访问请求，如果用户同意，Google就会生成一个token，转回第三方Web应用，第三方Web应用凭此token，可以请求Google的相关Sevice，比如联系人的服务，从而取得相关数据。
AuthSub有两种接口，一个是AuthSubRequest(A call to this method sends the user to a Google Accounts web page, where the user is given the opportunity to log in and grant Google account access to the web application. If successful, Google provides a single-use [...]]]></description>
			<content:encoded><![CDATA[<p>昨天写了一篇从Web Mail里取得用户通讯录的方法的文章，里面提到了Google的<a href="http://code.google.com/intl/zh-CN/apis/accounts/" target="_blank">Account Authentication API</a>，今天我们就用<a href="http://code.google.com/intl/zh-CN/apis/accounts/" target="_blank">Account Authentication API</a>和<a href="http://code.google.com/apis/contacts/" target="_blank">Google Contacts Data API</a>来做一个取得Google帐户联系人的测试。</p>
<p>首先我们要看一下<a href="http://code.google.com/intl/zh-CN/apis/accounts/" target="_blank">Account Authentication API</a>，对于网络应用来说我们选择<a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/AuthForWebApps.html">对网络应用程序的验证</a>，对网络应用程序的验证也提供了 <a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/OAuth.html">OAuth</a> 和 <a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/AuthSub.html">AuthSub</a> 两种认证方式，我们选择AuthSub的认证方式，认证过程如下图</p>
<p><img class="alignnone size-full wp-image-154" title="Google Authsub Diagram" src="http://i.laoer.com/wp-content/uploads/2009/03/authsubdiagram.png" alt="Google Authsub Diagram" width="600" /></p>
<p>用户在第三方Web应用上向Google Accounts Authentication发送AuthSub的HTTP请求，如果用户没有登录Google，则会显示登录页面，用户登录之后，会提示用户是否接受或拒绝这个第三方Web应用的访问请求，如果用户同意，Google就会生成一个token，转回第三方Web应用，第三方Web应用凭此token，可以请求Google的相关Sevice，比如联系人的服务，从而取得相关数据。</p>
<p>AuthSub有两种接口，一个是<a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/AuthSub.html#AuthSubRequest">AuthSubRequest</a>(A call to this method sends the user to a Google Accounts web page, where the user is given the opportunity to log in and grant Google account access to the web application. If successful, Google provides a single-use authentication token, which the web application can use to access the user&#8217;s Google service data.)另一个是<a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/AuthSub.html#AuthSubSessionToken">AuthSubSessionToken</a>(A call to this method allows the web application to exchange a single-use token for a session token)，按照Google文档的理解，<a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/AuthSub.html#AuthSubRequest">AuthSubRequest</a>是一个单次的认证，<a href="http://code.google.com/intl/zh-CN/apis/accounts/docs/AuthSub.html#AuthSubSessionToken">AuthSubSessionToken</a>应该是带会话(Session)的。</p>
<p>我们就举Google提供的例子</p>
<pre>https://www.google.com/accounts/AuthSubRequest?
   next=http%3A%2F%2Fwww.yourwebapp.com%2Fshowcalendar.html
   &amp;scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F
   &amp;session=1
   &amp;secure=1</pre>
<p>https://www.google.com/accounts/AuthSubRequest就是AuthSub请求的地址，next表示认证之后要转回的地址，一般就是第三方Web应用的地址，也就是你网站的一个地址，Google会把token附带到这个地址后面，scope是你要请求的Google服务地址，这个例子里是要访问Google日历的数据，另外两个参数看Google的文档吧。</p>
<p>接下来，我们要取得Google帐户的联系人，我们先看看Google提供了多少可以访问的服务吧，访问<a href="http://code.google.com/intl/zh-CN/apis/gdata/" target="_blank">Google数据API</a>，Google提供的数据还着不少，有日历、文档、图书搜索、网路相册等等，当然也包括我们所需要的<a href="http://code.google.com/intl/zh-CN/apis/contacts/" target="_blank">联系人的API</a>，Google数据API要好好了解一下，总体来说Google提供一个Gdata的数据格式，和RSS的feed类似的格式，通过相关服务的访问地址，就可以返回Gdata数据，至于Gdata的读取，已经有了很多程序语言的封装好的程序(<a href="http://code.google.com/intl/zh-CN/apis/gdata/clientlibs.html" targer="_blank">http://code.google.com/intl/zh-CN/apis/gdata/clientlibs.html</a>)，直接用就可以了，我们用PHP举例，PHP对Gdata的封装，是Zend Framework里的Gdata包，在<a href="http://framework.zend.com/download/gdata" target="_blank">http://framework.zend.com/download/gdata</a>下载就可以了，但是现在Zend Gdata的包里没有直接的Google contacts的组件，但不要紧，通过Zend Gdata里基础数据的访问，可以取得Google contacts。</p>
<p>我们看看Google Contacts Data API的<a href="http://code.google.com/intl/zh-CN/apis/contacts/developers_guide_protocol.html" target="_blank">开发人员指南</a>吧，取得联系人的Feed URL是</p>
<pre>http://www.google.com/m8/feeds/contacts/<var>userEmail</var>/full
或 

http://www.google.com/m8/feeds/contacts/default/full</pre>
<p>那我们就用PHP来写一个取得联系人的程序吧</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Loader.php'</span><span style="color: #339933;">;</span>
Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">loadClass</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Zend_Gdata'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">loadClass</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Zend_Gdata_AuthSub'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">loadClass</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Zend_Gdata_ClientLogin'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">loadClass</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Zend_Gdata_Query'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Zend_Loader<span style="color: #339933;">::</span><span style="color: #004000;">loadClass</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Zend_Gdata_Feed'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$my_contacts</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://www.google.com/m8/feeds/contacts/default/full'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span> <span style="color: #990000;">isset</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_SESSION</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cal_token'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_GET</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</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;">// You can convert the single-use token to a session token.</span>
		<span style="color: #000088;">$session_token</span> <span style="color: #339933;">=</span> Zend_Gdata_AuthSub<span style="color: #339933;">::</span><span style="color: #004000;">getAuthSubSessionToken</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_GET</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'token'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #666666; font-style: italic;">// Store the session token in our session.</span>
		<span style="color: #000088;">$_SESSION</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cal_token'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$session_token</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Display link to generate single-use token</span>
		<span style="color: #000088;">$googleUri</span> <span style="color: #339933;">=</span> Zend_Gdata_AuthSub<span style="color: #339933;">::</span><span style="color: #004000;">getAuthSubTokenUri</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'http://'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'SERVER_NAME'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$my_contacts</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Click &lt;a href='<span style="color: #006699; font-weight: bold;">$googleUri</span>'&gt;here&lt;/a&gt; &quot;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;to authorize this application.&quot;</span><span style="color: #339933;">;</span>
		<span style="color: #990000;">exit</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: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Create an authenticated HTTP Client to talk to Google.</span>
<span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> Zend_Gdata_AuthSub<span style="color: #339933;">::</span><span style="color: #004000;">getHttpClient</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_SESSION</span> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cal_token'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$gdata</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Gdata <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$client</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Gdata_Query <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$my_contacts</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//$query-&gt;setMaxResults(10);</span>
<span style="color: #000088;">$query</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setMaxResults</span> <span style="color: #009900;">&#40;</span> <span style="color: #cc66cc;">2000</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$feed</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$gdata</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getFeed</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$query</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$feed</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$entry</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$parts</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$entry</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getExtensionElements</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span> <span style="color: #000088;">$parts</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$p</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$element</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$p</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getDOM</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">switch</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">tagName</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'email'</span> <span style="color: #339933;">:</span>
				<span style="color: #b1b100;">print</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Email: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getAttribute</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'address'</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;&lt;br/&gt;&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">case</span> <span style="color: #0000ff;">'phoneNumber'</span> <span style="color: #339933;">:</span>
				<span style="color: #b1b100;">print</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;Phone: &quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">nodeValue</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">&quot;&lt;br/&gt;&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
			<span style="color: #b1b100;">default</span> <span style="color: #339933;">:</span>
				<span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>放在你服务器上运行一下吧（别忘了Zend Gdata包要加进去）。</p>
]]></content:encoded>
			<wfw:commentRss>http://i.laoer.com/grab-google-contacts-by-google-api.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
