<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Akii Snow</title><link>http://www.akii.org</link><description>Happiness is Grasp now!</description><language>en</language><lastBuildDate>Wed, 04 Nov 2009 09:17:28 PST</lastBuildDate><generator>http://wordpress.org/?v=2.8.5</generator><sy:updatePeriod xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">hourly</sy:updatePeriod><sy:updateFrequency xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">1</sy:updateFrequency><itunes:explicit>no</itunes:explicit><itunes:subtitle>Happiness is Grasp now!</itunes:subtitle><creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by/3.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/akii" type="application/rss+xml" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fakii" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fakii" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fakii" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/akii" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fakii" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fakii" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fakii" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item><title>ghs.google.com可用IP全部沦陷</title><link>http://feedproxy.google.com/~r/akii/~3/PH5plfPLFGg/</link><category>industry</category><category>gae</category><category>ghs.google.com</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Wed, 04 Nov 2009 09:17:28 PST</pubDate><guid isPermaLink="false">http://www.akii.org/2009-11/ghs-google-com-available-ip-all-the-fall/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/X4ynXbRTDxGDAxfyTAFv5OOyJvY/0/da"><img src="http://feedads.g.doubleclick.net/~a/X4ynXbRTDxGDAxfyTAFv5OOyJvY/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/X4ynXbRTDxGDAxfyTAFv5OOyJvY/1/da"><img src="http://feedads.g.doubleclick.net/~a/X4ynXbRTDxGDAxfyTAFv5OOyJvY/1/di" border="0" ismap="true"></img></a></p><p>今天发现调用我gae上的图片居然显示不了了。直觉就是ghs.google.com的一个可用的IP又被墙了。</p>
<p>禾蟹的力量太大了。我们仅仅是想用一些google的服务而已。</p>
<p>什么自由什么人权，我们不谈，也不敢谈，更不要说政治。那跟我们没关系，我们谈的是php,python,jquery,前端，后端等等，我们仅仅是出于技术上的爱好来应用一些google的免费服务而已。</p>
<p>这点小小的要求都不让我得得逞。My God&#8230;. 要多无语有多无语，脑袋上布满了黑线:(||||</p>
<p>谁有可用的可否通知一下，不胜感激。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=PH5plfPLFGg:wCUaBTmrJ50:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=PH5plfPLFGg:wCUaBTmrJ50:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=PH5plfPLFGg:wCUaBTmrJ50:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=PH5plfPLFGg:wCUaBTmrJ50:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/PH5plfPLFGg" height="1" width="1"/>]]></content:encoded><description>今天发现调用我gae上的图片居然显示不了了。直觉就是ghs.google.com的一个可用的IP又被墙了。
禾蟹的力量太大了。我们仅仅是想用一些google的服务而已。
什么自由什么人权，我们不谈，也不敢谈，更不要说政治。那跟我们没关系，我们谈的是php,python,jquery,前端，后端等等，我们仅仅是出于技术上的爱好来应用一些google的免费服务而已。
这点小小的要求都不让我得得逞。My God&amp;#8230;. 要多无语有多无语，脑袋上布满了黑线:(&amp;#124;&amp;#124;&amp;#124;&amp;#124;
谁有可用的可否通知一下，不胜感激。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-11/ghs-google-com-available-ip-all-the-fall/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><feedburner:origLink>http://www.akii.org/2009-11/ghs-google-com-available-ip-all-the-fall/</feedburner:origLink></item><item><title>firefox3.6 Beta 1发布</title><link>http://feedproxy.google.com/~r/akii/~3/7FXUlwrOpKs/</link><category>industry</category><category>firefox</category><category>firefox3.6</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Wed, 04 Nov 2009 07:08:26 PST</pubDate><guid isPermaLink="false">http://www.akii.org/2009-11/firefox3-6-beta-1-released/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/9hPzJbc1bRrPqs6SCDcaA2H0GS4/0/da"><img src="http://feedads.g.doubleclick.net/~a/9hPzJbc1bRrPqs6SCDcaA2H0GS4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/9hPzJbc1bRrPqs6SCDcaA2H0GS4/1/da"><img src="http://feedads.g.doubleclick.net/~a/9hPzJbc1bRrPqs6SCDcaA2H0GS4/1/di" border="0" ismap="true"></img></a></p><p>距离Firefox 3.5发布才不过三个月的时间,不过Mozilla已经在考虑该版本的初步终止日期了.原因很简单,即将到来的升级版本Firefox 3.6只是3.5版本的较小升级,Mozilla没有必要同时提供3.5和3.6两种版本的升级.<br />
在询问Firefox 3.6发布后是不是不再有Firefox 3.5.X的升级时,Firefox主管Mike Beltzner回答道:“这个并没有百分百确定,不过,如果我们真的把Firefox 3.6定位在较小升级,那么,是的,我们将不再为1.9.1(Gecko 1.9.1渲染引擎)提供支持.”</p>
<p>Mozilla向开发和测试人员发放了Firefox 3.6的第一个Alpha预览测试版，初步加入了诸多新特性。正式版计划今年晚些时候发布。Firefox 3.6开发代号“Namoroka”，基于Gecko 1.9.2渲染引擎(Firefox 3.5是Gecko 1.9.1)，不过该渲染平台目前也是预发布版本。Gecko 1.9.2引擎主要新特性：</p>
<p>1、整体改善程序的启动和响应速度。<br />
2、加快了TraceMonkey JavaScript引擎的速度。<br />
3、Compositor(第一阶段)：每个顶级内容文档使用一个原生Widget。更多细节见此。<br />
4、新的聚焦模型。<br />
5、一些新的CSS3属性，包括定义背景大小、背景图片渐变等。<br />
6、hromedir属性替换为pseudoclass。<br />
<span id="more-1125"></span><br />
随后Mozilla又发表专门文章，详细介绍了Firefox 3.6里的诸多新特性，当然其中大多数都还在开发之中，完善尚需时日。</p>
<p>一、用户体验<br />
1、自动完成条目不再按字母顺序排列，而是根据使用频率排列，所以最可能使用的条目会出现在前边；同时，输入的字符会在此前输入的整个字符串中搜索，而不是只搜索开头字符。<br />
2、按下Ctrl+Tab快捷键会切换到此前使用的标签，而不是标签栏的下一个。<br />
3、按住Ctrl+Tab快捷键，会看到当前正在使用和最近使用的五个标签页的预览，点击下方的显示所有标签选项就会给出所有已打开标签页的预览，并增加一个搜索框。该功能原计划在Firefox 3.0/3.5中加入，但被撤销，现在又回来了。<br />
4、新的标签切换方式和预览默认是关闭，需要在about:config配置页面里将browser.ctrlTab.mostRecentlyUsed、browser.ctrlTab.previews的属性值都设置为True。<br />
5、在自定义工具栏对话框中加入了新的全屏按钮，方便喜欢用鼠标浏览的用户，当然也可以用快捷键F11来切换全屏状态。</p>
<p>二、性能<br />
之前已经说过，TraceMonkey JS引擎的性能得到了优化和提升，并且默认打开。<br />
事实上Firefox 3.0/3.5里也有此功能，但默认关闭，需要在about:config配置页面里将javascript.options.jit.chrome的属性值设为True。</p>
<p>三、Web开发<br />
Web开发方面完善了对CSS3的支持，在Acid3规范兼容性测试中得分也达到了94，比Firefox 3.5高一分。</p>
<p>Firefox 3.5基于Gecko 1.9.1,而年底即将发布的Firefox 3.6则采用了Gecko 1.9.2.按照Beltzner的说法,Firefox 3.5用户在Firefox 3.6发布后就需要升级到最新版本,或者停留在一个不再有安全或稳定性补丁的版本.</p>
<p>按照当前的计划,11月份Firefox 3.6将正式发布,随后是明年3月份的Firefox 3.7,另一个重大版本就是2010年10月的Firefox 4.0.Mozilla的惯例是在一个新的重大版本发布后至多6各月内全面终止上一个重大版本,比如说2010年1月也就是Firefox 3.5发布后6个月之前Firefox 3.0.X将彻底退出历史舞台.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=7FXUlwrOpKs:G0KBC1tcoPk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=7FXUlwrOpKs:G0KBC1tcoPk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=7FXUlwrOpKs:G0KBC1tcoPk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=7FXUlwrOpKs:G0KBC1tcoPk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/7FXUlwrOpKs" height="1" width="1"/>]]></content:encoded><description>距离Firefox 3.5发布才不过三个月的时间,不过Mozilla已经在考虑该版本的初步终止日期了.原因很简单,即将到来的升级版本Firefox 3.6只是3.5版本的较小升级,Mozilla没有必要同时提供3.5和3.6两种版本的升级.
在询问Firefox 3.6发布后是不是不再有Firefox 3.5.X的升级时,Firefox主管Mike Beltzner回答道:“这个并没有百分百确定,不过,如果我们真的把Firefox 3.6定位在较小升级,那么,是的,我们将不再为1.9.1(Gecko 1.9.1渲染引擎)提供支持.”
Mozilla向开发和测试人员发放了Firefox 3.6的第一个Alpha预览测试版，初步加入了诸多新特性。正式版计划今年晚些时候发布。Firefox 3.6开发代号“Namoroka”，基于Gecko 1.9.2渲染引擎(Firefox 3.5是Gecko 1.9.1)，不过该渲染平台目前也是预发布版本。Gecko 1.9.2引擎主要新特性：
1、整体改善程序的启动和响应速度。
2、加快了TraceMonkey JavaScript引擎的速度。
3、Compositor(第一阶段)：每个顶级内容文档使用一个原生Widget。更多细节见此。
4、新的聚焦模型。
5、一些新的CSS3属性，包括定义背景大小、背景图片渐变等。
6、hromedir属性替换为pseudoclass。

随后Mozilla又发表专门文章，详细介绍了Firefox 3.6里的诸多新特性，当然其中大多数都还在开发之中，完善尚需时日。
一、用户体验
1、自动完成条目不再按字母顺序排列，而是根据使用频率排列，所以最可能使用的条目会出现在前边；同时，输入的字符会在此前输入的整个字符串中搜索，而不是只搜索开头字符。
2、按下Ctrl+Tab快捷键会切换到此前使用的标签，而不是标签栏的下一个。
3、按住Ctrl+Tab快捷键，会看到当前正在使用和最近使用的五个标签页的预览，点击下方的显示所有标签选项就会给出所有已打开标签页的预览，并增加一个搜索框。该功能原计划在Firefox 3.0/3.5中加入，但被撤销，现在又回来了。
4、新的标签切换方式和预览默认是关闭，需要在about:config配置页面里将browser.ctrlTab.mostRecentlyUsed、browser.ctrlTab.previews的属性值都设置为True。
5、在自定义工具栏对话框中加入了新的全屏按钮，方便喜欢用鼠标浏览的用户，当然也可以用快捷键F11来切换全屏状态。
二、性能
之前已经说过，TraceMonkey JS引擎的性能得到了优化和提升，并且默认打开。
事实上Firefox 3.0/3.5里也有此功能，但默认关闭，需要在about:config配置页面里将javascript.options.jit.chrome的属性值设为True。
三、Web开发
Web开发方面完善了对CSS3的支持，在Acid3规范兼容性测试中得分也达到了94，比Firefox 3.5高一分。
Firefox 3.5基于Gecko 1.9.1,而年底即将发布的Firefox 3.6则采用了Gecko 1.9.2.按照Beltzner的说法,Firefox 3.5用户在Firefox 3.6发布后就需要升级到最新版本,或者停留在一个不再有安全或稳定性补丁的版本.
按照当前的计划,11月份Firefox 3.6将正式发布,随后是明年3月份的Firefox 3.7,另一个重大版本就是2010年10月的Firefox 4.0.Mozilla的惯例是在一个新的重大版本发布后至多6各月内全面终止上一个重大版本,比如说2010年1月也就是Firefox 3.5发布后6个月之前Firefox 3.0.X将彻底退出历史舞台.</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-11/firefox3-6-beta-1-released/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.akii.org/2009-11/firefox3-6-beta-1-released/</feedburner:origLink></item><item><title>申请了lenovo的win7升级光盘</title><link>http://feedproxy.google.com/~r/akii/~3/_3ffC0P4Jas/</link><category>心情随笔</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Sun, 25 Oct 2009 07:38:59 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/2009-10/applied-for-a-lenovos-win7-upgrade-cd-rom/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/v2drb78eMs-HBjUt4e05Ektpwdo/0/da"><img src="http://feedads.g.doubleclick.net/~a/v2drb78eMs-HBjUt4e05Ektpwdo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/v2drb78eMs-HBjUt4e05Ektpwdo/1/da"><img src="http://feedads.g.doubleclick.net/~a/v2drb78eMs-HBjUt4e05Ektpwdo/1/di" border="0" ismap="true"></img></a></p><p>参加了lenovo的win7升级计划。<br />
虽然买的是水货，并且早于今年6月份，但是也提交了一份。</p>
<p>因为我的机器是CTO机型的，所以不需要提交购买凭证。51nb上也有此说法。<br />
86.5元人民币，弄一套win7的光盘也不错，关键还有一个COA标签。</p>
<p>万一要是可以安装在其它的机器上就赚了。。。<br />
等待中。<br />
今年的十月真是很的激情的十月，win7正式版发布，ubuntu9.1.0还有４天发布。<br />
都好期待ing&#8230;.<br />
看来我的电脑又要面临一次彻底的折腾了。。。。<br />
同时，期待lenovo的win7恢复光盘尽快出。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=_3ffC0P4Jas:9WWbCGFVHcY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=_3ffC0P4Jas:9WWbCGFVHcY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=_3ffC0P4Jas:9WWbCGFVHcY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=_3ffC0P4Jas:9WWbCGFVHcY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/_3ffC0P4Jas" height="1" width="1"/>]]></content:encoded><description>参加了lenovo的win7升级计划。
虽然买的是水货，并且早于今年6月份，但是也提交了一份。
因为我的机器是CTO机型的，所以不需要提交购买凭证。51nb上也有此说法。
86.5元人民币，弄一套win7的光盘也不错，关键还有一个COA标签。
万一要是可以安装在其它的机器上就赚了。。。
等待中。
今年的十月真是很的激情的十月，win7正式版发布，ubuntu9.1.0还有４天发布。
都好期待ing&amp;#8230;.
看来我的电脑又要面临一次彻底的折腾了。。。。
同时，期待lenovo的win7恢复光盘尽快出。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-10/applied-for-a-lenovos-win7-upgrade-cd-rom/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://www.akii.org/2009-10/applied-for-a-lenovos-win7-upgrade-cd-rom/</feedburner:origLink></item><item><title>令人怀念+遗憾的饭否的精典语录</title><link>http://feedproxy.google.com/~r/akii/~3/Y1AQXVI-Y0g/</link><category>心情随笔</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Sat, 24 Oct 2009 10:46:27 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/2009-10/it-is-regrettable-that-the-rice-miss-any-of-the-classics-quotations/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/qnb_Rb7LUdwzQKeaWOyXeOjoX0k/0/da"><img src="http://feedads.g.doubleclick.net/~a/qnb_Rb7LUdwzQKeaWOyXeOjoX0k/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/qnb_Rb7LUdwzQKeaWOyXeOjoX0k/1/da"><img src="http://feedads.g.doubleclick.net/~a/qnb_Rb7LUdwzQKeaWOyXeOjoX0k/1/di" border="0" ismap="true"></img></a></p><p>1.我这人从不记仇,一般有仇当场我就报了。</p>
<p>2.别在我的坟前哭。脏了我轮回的路。</p>
<p>3.已经将整个青春都用来检讨青春，还要把整个生命都用来怀疑生<br />
命。</p>
<p>4.是这样的张总，妳在家里的电脑上按了CTRL+C，然后在公司的电脑上再按CTRL+V是肯定不行的。即使同一篇文章也不行。不不，多贵的电脑都不行。</p>
<p>5.你要是鲜花，以后牛都不敢拉粪了！</p>
<p>6.我以为你只是1和3中间的数，没想到你还是1和3俩数的组合。</p>
<p>7.在网易看到一条评论：我指着一盆花，淡淡地说：草。我指着天空，淡淡地说：日。<br />
<span id="more-1122"></span><br />
8.先是《中国不高兴》，然后是《中国为什么不高兴》，接下来是《中国凭什么不高兴》、《中国怎么那么不高兴》、《你说中国怎么那么不高兴》、《凭什么让我说中国怎么那么不高兴》、《凭什么不能让你说中国怎么那么不高兴》、《我他妈哪知道中国怎么那么不高兴》……</p>
<p>10.自己选择45°仰视别人，就休怪他人135°俯视着看你。</p>
<p>11.Ralph W. Sockman说：当我们是少数时，可以测试自己的勇气；当我们是多数时，可以测试自己的宽容。</p>
<p>12.牧羊，一辈子都在急；金牛，一辈子都在守；双子，一辈子都在徘徊；巨蟹，一辈子都在等；狮子，一辈子都在控制；处女，一辈子都在准备；天秤，一辈子都在权衡；天蝎，一辈子都在猜疑；射手，一辈子都在玩儿；摩羯，一辈子都在奋斗；水瓶，一辈子都在做梦；双鱼一 辈子都不知道自己在做什么。</p>
<p>13.在职场中就应该像柯南那样，有一种我走到哪就让别人死到哪的霸气。</p>
<p>14.一食人族上班，经理再三交代不能吃同事，答应。过几天忍不住，偷吃一个清洁工人，当即被发现。其感悟是：千万别吃真正做事的人。</p>
<p>15.李碧华说过： 什么叫多余？夏天的棉袄，冬天的蒲扇，还有等我已经心冷后你的殷勤。</p>
<p>16.永远年轻，永远装嫩，永远不知好歹，永远热泪盈眶。</p>
<p>17.很多时候你只是某个人的练爱对象而非恋爱对象。</p>
<p>18.钱钟书先生对杨绛女士有这样一段评价，后来被社会学家视为理想婚姻的典范： 1、在遇到她以前，我从未想过结婚的事。 2、和她在一起这么多年，从未后悔过娶她做妻子。 3、也从未想过娶别的女人。</p>
<p>19.你攒够四块五，我也攒够四块五，我们就可以去民政局结婚了。</p>
<p>20.个人感觉，在网络上要转向“慢”了，资讯越快，越是要等几天让事实浮现，第一时间人肉，第一时间谴责，第一时间落泪，都无太多必要。</p>
<p>21.我爸面对我发胖一事发表了看法：没有韩红的命，还得了韩红的病。</p>
<p>22.你来我信你不会走，你走我当你没来过。——我们该这样对待缘分与爱。</p>
<p>23.你觉得别人牛B，他不一定觉得你牛B，但你要觉得别人傻B，在他眼里你也是一傻B,所以我认为牛B像单恋，傻B则是两情相悦。</p>
<p>24.“上了年纪最大的好处就是：年轻时得不到的东西，现在你不想要了。”</p>
<p>25.世界上所有男人都是骗子。不管是漂亮还是不漂亮的女人都会被骗。有所不同的是，幸运的女人找到了一个大骗子，骗了她一辈子。 不幸的女人找到了一个小骗子，骗了她一阵子。</p>
<p>26.人最软弱的地方，是舍不得。舍不得一段不再精采的感情，舍不得一份虚荣，舍不得掌声。我们永远以为最好的日子是会很长很长的，不必那麽快离开。就在我们心软和缺乏勇气的时候，最好的日子毫不留情地逝去了。</p>
<p>27.曾以为我是那崖畔的一枝花，后来才知道，不过是人海一粒渣。</p>
<p>28.现在你骂我，是因为你还不了解我，等你以后了解了我，你一定会动手打我的。</p>
<p>29.一日不读书，无人看得出；一周不读书，开始会爆粗；一月不读书，智商输给猪。</p>
<p>30.当前我国女性成功大概有如下四种途径：第一，学好英语，嫁老外。第二，学好英语，出国读书，嫁老外。第三，学好英语，出国读书，学成归国，嫁老外。第四，学好英语，出国读书，学成归国，努力打拼，嫁老外。</p>
<p>31.有的人聪明得像天气，多变；有的人傻得像天气预报，变天它都看不出来。</p>
<p>32.马不停蹄的错过，轻而易举的辜负，不知不觉的陌路。</p>
<p>33.石头记告诉我们：凡是真心爱的最后都散了，凡是混搭的最后都团圆了。</p>
<p>34.如果你不是经常遇到挫折，这表明你做的事情没有很大的创新性-伍迪.艾伦</p>
<p>35.爱情生活里，比找不到安全感更可怕的是什么？是找不到安全套。</p>
<p>36.两个人在一起，更多的不是改变了对方，而是接受了，所以说包容呢，如果光想着改变，那不是生活，那是战争。</p>
<p>37.一切问题最终都是时间问题，一切烦恼其实都是自寻烦恼。</p>
<p>38.人永远不知道谁哪次不经意的跟你说了再见之后就真的再也不见了。</p>
<p>39.很多事都介于“不说憋屈“和“说了矫情“之间。</p>
<p>40.通往成功的路，总是在施工中。</p>
<p>41.【你喜欢我天使的脸孔，还是魔鬼的身材？】【我就喜欢你这种幽默感。】</p>
<p>42.下车时导游小姐说：“请带好您的贵重物品。”他拉着我的手说：“快走，贵重物品”。</p>
<p>43.我不下地狱，谁爱下谁下</p>
<p>44.猜一句英文：「ABABBBAAAAAABBBABAAAABBBBAABBBAAAAA」？〈答案：Long time no C〉</p>
<p>45.自己选择的路，跪着也要走完</p>
<p>46.我也不是非你不可。你也不是非我不可。真是一场误会。</p>
<p>47.想你的眉目，想到模糊。——突然觉得，思念大都如此，越来越淡</p>
<p>48.广播体操现在开始：╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗</p>
<p>49.在经年后，感叹，那两个少年：一个惊艳了时光，一个温柔了岁月。</p>
<p>50.你永远也无法理解，为了让自己对生活发生兴趣，我们付出了多大的努力。</p>
<p>51.孔子曰，中午不睡，下午崩溃；孟子曰，孔子说的对</p>
<p>52.9个橙子分给13个小朋友，怎么分才公平？-杀死4个小朋友。</p>
<p>53.如果她（他）对你说：”忘了我吧。＂你告诉对方：”我一直没记住。＂</p>
<p>54.20岁看体力；30岁看学历；40岁看经历；50岁看智力；60岁看病历；70岁看日历；80岁看黄历；90岁看舍利。</p>
<p>55.史上最神秘的部门：有关部门；史上最神秘的人：知情人士；史上最权威的人：砖家叫兽。</p>
<p>56.“恋”是个很强悍的字。它的上半部取自“变态”的“变”，下半部取自“变态”的“态”。</p>
<p>57.就算是一坨屎，也有遇见屎壳郎的那天。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=Y1AQXVI-Y0g:0esGWiQ-MaQ:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=Y1AQXVI-Y0g:0esGWiQ-MaQ:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=Y1AQXVI-Y0g:0esGWiQ-MaQ:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=Y1AQXVI-Y0g:0esGWiQ-MaQ:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/Y1AQXVI-Y0g" height="1" width="1"/>]]></content:encoded><description>1.我这人从不记仇,一般有仇当场我就报了。
2.别在我的坟前哭。脏了我轮回的路。
3.已经将整个青春都用来检讨青春，还要把整个生命都用来怀疑生
命。
4.是这样的张总，妳在家里的电脑上按了CTRL+C，然后在公司的电脑上再按CTRL+V是肯定不行的。即使同一篇文章也不行。不不，多贵的电脑都不行。
5.你要是鲜花，以后牛都不敢拉粪了！
6.我以为你只是1和3中间的数，没想到你还是1和3俩数的组合。
7.在网易看到一条评论：我指着一盆花，淡淡地说：草。我指着天空，淡淡地说：日。

8.先是《中国不高兴》，然后是《中国为什么不高兴》，接下来是《中国凭什么不高兴》、《中国怎么那么不高兴》、《你说中国怎么那么不高兴》、《凭什么让我说中国怎么那么不高兴》、《凭什么不能让你说中国怎么那么不高兴》、《我他妈哪知道中国怎么那么不高兴》……
10.自己选择45°仰视别人，就休怪他人135°俯视着看你。
11.Ralph W. Sockman说：当我们是少数时，可以测试自己的勇气；当我们是多数时，可以测试自己的宽容。
12.牧羊，一辈子都在急；金牛，一辈子都在守；双子，一辈子都在徘徊；巨蟹，一辈子都在等；狮子，一辈子都在控制；处女，一辈子都在准备；天秤，一辈子都在权衡；天蝎，一辈子都在猜疑；射手，一辈子都在玩儿；摩羯，一辈子都在奋斗；水瓶，一辈子都在做梦；双鱼一 辈子都不知道自己在做什么。
13.在职场中就应该像柯南那样，有一种我走到哪就让别人死到哪的霸气。
14.一食人族上班，经理再三交代不能吃同事，答应。过几天忍不住，偷吃一个清洁工人，当即被发现。其感悟是：千万别吃真正做事的人。
15.李碧华说过： 什么叫多余？夏天的棉袄，冬天的蒲扇，还有等我已经心冷后你的殷勤。
16.永远年轻，永远装嫩，永远不知好歹，永远热泪盈眶。
17.很多时候你只是某个人的练爱对象而非恋爱对象。
18.钱钟书先生对杨绛女士有这样一段评价，后来被社会学家视为理想婚姻的典范： 1、在遇到她以前，我从未想过结婚的事。 2、和她在一起这么多年，从未后悔过娶她做妻子。 3、也从未想过娶别的女人。
19.你攒够四块五，我也攒够四块五，我们就可以去民政局结婚了。
20.个人感觉，在网络上要转向“慢”了，资讯越快，越是要等几天让事实浮现，第一时间人肉，第一时间谴责，第一时间落泪，都无太多必要。
21.我爸面对我发胖一事发表了看法：没有韩红的命，还得了韩红的病。
22.你来我信你不会走，你走我当你没来过。——我们该这样对待缘分与爱。
23.你觉得别人牛B，他不一定觉得你牛B，但你要觉得别人傻B，在他眼里你也是一傻B,所以我认为牛B像单恋，傻B则是两情相悦。
24.“上了年纪最大的好处就是：年轻时得不到的东西，现在你不想要了。”
25.世界上所有男人都是骗子。不管是漂亮还是不漂亮的女人都会被骗。有所不同的是，幸运的女人找到了一个大骗子，骗了她一辈子。 不幸的女人找到了一个小骗子，骗了她一阵子。
26.人最软弱的地方，是舍不得。舍不得一段不再精采的感情，舍不得一份虚荣，舍不得掌声。我们永远以为最好的日子是会很长很长的，不必那麽快离开。就在我们心软和缺乏勇气的时候，最好的日子毫不留情地逝去了。
27.曾以为我是那崖畔的一枝花，后来才知道，不过是人海一粒渣。
28.现在你骂我，是因为你还不了解我，等你以后了解了我，你一定会动手打我的。
29.一日不读书，无人看得出；一周不读书，开始会爆粗；一月不读书，智商输给猪。
30.当前我国女性成功大概有如下四种途径：第一，学好英语，嫁老外。第二，学好英语，出国读书，嫁老外。第三，学好英语，出国读书，学成归国，嫁老外。第四，学好英语，出国读书，学成归国，努力打拼，嫁老外。
31.有的人聪明得像天气，多变；有的人傻得像天气预报，变天它都看不出来。
32.马不停蹄的错过，轻而易举的辜负，不知不觉的陌路。
33.石头记告诉我们：凡是真心爱的最后都散了，凡是混搭的最后都团圆了。
34.如果你不是经常遇到挫折，这表明你做的事情没有很大的创新性-伍迪.艾伦
35.爱情生活里，比找不到安全感更可怕的是什么？是找不到安全套。
36.两个人在一起，更多的不是改变了对方，而是接受了，所以说包容呢，如果光想着改变，那不是生活，那是战争。
37.一切问题最终都是时间问题，一切烦恼其实都是自寻烦恼。
38.人永远不知道谁哪次不经意的跟你说了再见之后就真的再也不见了。
39.很多事都介于“不说憋屈“和“说了矫情“之间。
40.通往成功的路，总是在施工中。
41.【你喜欢我天使的脸孔，还是魔鬼的身材？】【我就喜欢你这种幽默感。】
42.下车时导游小姐说：“请带好您的贵重物品。”他拉着我的手说：“快走，贵重物品”。
43.我不下地狱，谁爱下谁下
44.猜一句英文：「ABABBBAAAAAABBBABAAAABBBBAABBBAAAAA」？〈答案：Long time no C〉
45.自己选择的路，跪着也要走完
46.我也不是非你不可。你也不是非我不可。真是一场误会。
47.想你的眉目，想到模糊。——突然觉得，思念大都如此，越来越淡
48.广播体操现在开始：╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗╔囧╗╔囧╝╚囧╝╚囧╗
49.在经年后，感叹，那两个少年：一个惊艳了时光，一个温柔了岁月。
50.你永远也无法理解，为了让自己对生活发生兴趣，我们付出了多大的努力。
51.孔子曰，中午不睡，下午崩溃；孟子曰，孔子说的对
52.9个橙子分给13个小朋友，怎么分才公平？-杀死4个小朋友。
53.如果她（他）对你说：”忘了我吧。＂你告诉对方：”我一直没记住。＂
54.20岁看体力；30岁看学历；40岁看经历；50岁看智力；60岁看病历；70岁看日历；80岁看黄历；90岁看舍利。
55.史上最神秘的部门：有关部门；史上最神秘的人：知情人士；史上最权威的人：砖家叫兽。
56.“恋”是个很强悍的字。它的上半部取自“变态”的“变”，下半部取自“变态”的“态”。
57.就算是一坨屎，也有遇见屎壳郎的那天。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-10/it-is-regrettable-that-the-rice-miss-any-of-the-classics-quotations/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.akii.org/2009-10/it-is-regrettable-that-the-rice-miss-any-of-the-classics-quotations/</feedburner:origLink></item><item><title>五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT)</title><link>http://feedproxy.google.com/~r/akii/~3/t-sCWjyhMFI/</link><category>software</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Sun, 18 Oct 2009 21:12:49 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/2009-10/comparison-of-the-five-open-source-agreement-bsd-apache-gpl-lgpl-mit/</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/vmyfEfEDZFv_BJ4Jr5Nk_fvS5g4/0/da"><img src="http://feedads.g.doubleclick.net/~a/vmyfEfEDZFv_BJ4Jr5Nk_fvS5g4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/vmyfEfEDZFv_BJ4Jr5Nk_fvS5g4/1/da"><img src="http://feedads.g.doubleclick.net/~a/vmyfEfEDZFv_BJ4Jr5Nk_fvS5g4/1/di" border="0" ismap="true"></img></a></p><p>当Adobe、Microsoft、Sun等一系列巨头开始表现出对”开源”的青睐时，”开源”的时代即将到来！</p>
<p>现今存在的开源协议很多，而经过Open Source Initiative组织通过批准的开源协议目前有58种（<a href="http://www.opensource.org/licenses/alphabetical">http://www.opensource.org/licenses/alphabetical</a>）。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码，最好也是选择这些被批准的开源协议。</p>
<p>这里我们来看四种最常用的开源协议及它们的适用范围，供那些准备开源或者使用开源产品的开发人员/厂家参考。</p>
<p><strong>BSD开源协议（</strong><a href="http://www.fsf.org/licensing/licenses/index_html#OriginalBSD">original BSD license</a><strong>、</strong><a id="FreeBSD" name="FreeBSD" href="http://www.freebsd.org/copyright/freebsd-license.html">FreeBSD license</a><strong>、</strong><a id="OriginalBSD" name="OriginalBSD" href="http://www.xfree86.org/3.3.6/COPYRIGHT2.html#6">Original BSD license</a><strong>）</strong></p>
<p>BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。</p>
<p>但”为所欲为”的前提当你发布使用了BSD协议的代码，或则以BSD协议代码为基础做二次开发自己的产品时，需要满足三个条件：</p>
<ol>
<li>如果再发布的产品中包含源代码，则在源代码中必须带有原来代码中的BSD协议。</li>
<li>如果再发布的只是二进制类库/软件，则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。</li>
<li>不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。</li>
</ol>
<p>BSD 代码鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，因此是对 商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二次开发。<br />
<span id="more-1117"></span><br />
<strong>Apache Licence 2.0（</strong><a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>、<a href="http://www.apache.org/LICENSE-1.1">Apache License, Version 1.1</a>、<a href="http://www.apache.org/LICENSE-1.0">Apache License, Version 1.0</a><strong>）</strong></p>
<p>Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似，同样鼓励代码共享和尊重原作者的著作权，同样允许代码修改，再发布（作为开源或商业软件）。需要满足的条件也和BSD类似：</p>
<ol>
<li>需要给代码的用户一份Apache Licence</li>
<li>如果你修改了代码，需要再被修改的文件中说明。</li>
<li>在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。</li>
<li>如果再发布的产品中包含一个Notice文件，则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可，但不可以表现为对Apache Licence构成更改。</li>
</ol>
<p>Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。</p>
<p><strong>GPL（</strong><a id="GNUGPL" name="GNUGPL" href="http://www.fsf.org/licensing/licenses/gpl.html">GNU General Public License</a><strong>）</strong></p>
<p>我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用，但不允许修改后和衍生的代 码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux，包括商业公司的linux和linux上各种各样的由个人，组织，以及商 业软件公司开发的免费软件了。</p>
<p>GPL协议的主要内容是只要在一个软件中使用(”使用”指类库引用，修改后的代码或者衍生代码)GPL 协议的产品，则该软件产品必须也采用GPL协议，既必须也是开源和免费。<strong>这就是所谓的”传染性”</strong>。GPL协议的产品作为一个单独的产品使用没有任何问题，还可以享受免费的优势。</p>
<p>由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议，对于使用GPL协议的开源代码，商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。</p>
<p>其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。</p>
<p><strong>LGPL（</strong><a id="LGPL" name="LGPL" href="http://www.fsf.org/licensing/licenses/lgpl.html">GNU Lesser General Public License</a><strong>）</strong></p>
<p>LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。</p>
<p>但是如果修改LGPL协议的代码或者衍生，则所有修改的代码，涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源 代码很适合作为第三方类库被商业软件引用，但不适合希望以LGPL协议代码为基础，通过修改和衍生的方式做二次开发的商业软件采用。</p>
<p>GPL/LGPL都保障原作者的知识产权，避免有人利用开源代码复制并开发类似的产品</p>
<p><strong>MIT（<a href="http://www.opensource.org/licenses/mit-license.php">MIT</a>）</strong></p>
<p>MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.</p>
<p>本文转自：<a href="http://www.awflasher.com/blog/archives/939" target="_blank">http://www.awflasher.com/blog/archives/939</a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=t-sCWjyhMFI:eVTxHeQ7CvY:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=t-sCWjyhMFI:eVTxHeQ7CvY:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=t-sCWjyhMFI:eVTxHeQ7CvY:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=t-sCWjyhMFI:eVTxHeQ7CvY:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/t-sCWjyhMFI" height="1" width="1"/>]]></content:encoded><description>当Adobe、Microsoft、Sun等一系列巨头开始表现出对”开源”的青睐时，”开源”的时代即将到来！
现今存在的开源协议很多，而经过Open Source Initiative组织通过批准的开源协议目前有58种（http://www.opensource.org/licenses/alphabetical）。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码，最好也是选择这些被批准的开源协议。
这里我们来看四种最常用的开源协议及它们的适用范围，供那些准备开源或者使用开源产品的开发人员/厂家参考。
BSD开源协议（original BSD license、FreeBSD license、Original BSD license）
BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。
但”为所欲为”的前提当你发布使用了BSD协议的代码，或则以BSD协议代码为基础做二次开发自己的产品时，需要满足三个条件：

如果再发布的产品中包含源代码，则在源代码中必须带有原来代码中的BSD协议。
如果再发布的只是二进制类库/软件，则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

BSD 代码鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，因此是对 商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二次开发。

Apache Licence 2.0（Apache License, Version 2.0、Apache License, Version 1.1、Apache License, Version 1.0）
Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似，同样鼓励代码共享和尊重原作者的著作权，同样允许代码修改，再发布（作为开源或商业软件）。需要满足的条件也和BSD类似：

需要给代码的用户一份Apache Licence
如果你修改了代码，需要再被修改的文件中说明。
在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。
如果再发布的产品中包含一个Notice文件，则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可，但不可以表现为对Apache Licence构成更改。

Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。
GPL（GNU General Public License）
我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用，但不允许修改后和衍生的代 码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux，包括商业公司的linux和linux上各种各样的由个人，组织，以及商 业软件公司开发的免费软件了。
GPL协议的主要内容是只要在一个软件中使用(”使用”指类库引用，修改后的代码或者衍生代码)GPL 协议的产品，则该软件产品必须也采用GPL协议，既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题，还可以享受免费的优势。
由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议，对于使用GPL协议的开源代码，商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。
其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。
LGPL（GNU Lesser General Public License）
LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。
但是如果修改LGPL协议的代码或者衍生，则所有修改的代码，涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源 代码很适合作为第三方类库被商业软件引用，但不适合希望以LGPL协议代码为基础，通过修改和衍生的方式做二次开发的商业软件采用。
GPL/LGPL都保障原作者的知识产权，避免有人利用开源代码复制并开发类似的产品
MIT（MIT）
MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.
本文转自：http://www.awflasher.com/blog/archives/939</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-10/comparison-of-the-five-open-source-agreement-bsd-apache-gpl-lgpl-mit/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.akii.org/2009-10/comparison-of-the-five-open-source-agreement-bsd-apache-gpl-lgpl-mit/</feedburner:origLink></item><item><title>Php在移动领域的开发及探索</title><link>http://feedproxy.google.com/~r/akii/~3/C1WkN-H6528/</link><category>PHP&amp;MYSQL</category><category>php</category><category>widget</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Wed, 16 Sep 2009 03:36:51 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/?p=1113</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/jHP6yFTNslVdq2ZaGRZRIdk4huo/0/da"><img src="http://feedads.g.doubleclick.net/~a/jHP6yFTNslVdq2ZaGRZRIdk4huo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/jHP6yFTNslVdq2ZaGRZRIdk4huo/1/da"><img src="http://feedads.g.doubleclick.net/~a/jHP6yFTNslVdq2ZaGRZRIdk4huo/1/di" border="0" ismap="true"></img></a></p><p>当今在WWW是世界里，PHP已经是一个不可忽视的强大力量，身为开源的先锋，已经为各种的开源产品作出了表率作用，用现在流行的话就是，草根的力量，星 星之火可以燎原，众多的一流网站国外的facebook，Iyohoo,国内有开心网，都是用以前被很多专家看不起的PHP来开发的，开源的产品成为主流 已经成为可能。近几年，随着智能手机普及，手机硬件性能的不断提高，手机已经进入了一个新的阶段，PC机上的众多软件移植到手机系统上已经是大势所趋，移 动系统软件已经成为，软件开发的重要增长点，PHP在移动市场的前景是什么呢？让我们来探索一下。<br />
要说PHP在移动领域的开发，我们首先要先来介绍一个对与PHP和移动领域都很重要的名词“Widget”，要说到Widget，很多人可能都听说过，因 为当今Widget是一个十分有人气的技术概念，在很多的领域都有应用，但恐怕真正知道什么是Widget的人就很少了，下面我先给大家介绍一下什么是 Widget吧，简单的说 Widget就是轻量级的UI控件，为用户展示不同的个性化的信息。<br />
目前Widget主要有4个大类： <span id="more-1113"></span><br />
一．	操作系统Widget（如苹果、Windows widget）</p>
<p>二．	网站应用Widget（例如：Facebook、iGoogle。）。</p>
<p>三．	迷你应用程序Widget(Yahoo Widget)。</p>
<p>四．	手机Widget（OphoneOS widget,Android widget,诺基亚widgets）。<br />
下面我介绍一下用PHP来开发widget的一段应用样例：<br />
让我们来看看PHP-GTK<br />
PHP-GTK是PHP的延伸模组，它可以让程式设计师写出在客户端执行的、且独立的GUI的程式。这个模组不允许在浏览器上显视GTK+的程式，它一开始就是开发来写独立的GUI程式的。<br />
Widget是一个GUI程式中基本的functions和forms。最常用的几个Widget是：label、button、window、 frame和text box。所有的widget都是来自於一个抽象的基本class─GtkWidget。每个widget都是一个class</p>
<p>一个Widget一生大概都有五个时期：<br />
1. 建立(Creation)：宣告一个物件(declaring an object)<br />
2. 放置(Placement)：将它加入一个容器中(adding it to a container)<br />
3. 信号连接(Signal Connection)：接收信号以及进行动作(the action it will perform)<br />
4. 显示(Display)：它是否是可见的(whether it is viewable or not)<br />
5. 删除(Destruction)：关闭程式(closing of a program)<br />
Container是一个可以包含其他widget的widget。大部分的widget都是container，例如：GtkWindow、 GtkTable和GtkBox。除了这点之外，container跟其他的widget没两样，也可以被放到其他container去。 Signal(s)当程式设计师在程式中做了一个动作时，程式需要有一个动作来回应使用者的动作。Signals使程式可以知道使用者做了动作并可以触发 适合的回应。Callback就是当signal送出之後，被signal唤起的function。Callback会执行function传回一个值或 是做一个动作。Callback就是signal的handler funciton。它可以是该signal的预设handler或着是程式设计师定义的function。要建立一个callback，就必须把 function connect 到 signal。Signal Inheritance(继承)和methods一样，signals可以被物件继承。一个widget可以送出任何它的parent widget可以送出的还有它自己特有的signal。<br />
你必须为PHP-GTK指定一个callback function当signal送出时来对signal做回应。把一个signal连接到一个function可以用connect() 这个object 方法达成。</p>
<p>如下：<br />
&lt;?php<br />
//建立一个GtkWindow<br />
$window = &amp;new GtkWindow();<br />
//将&#8221;destroy&#8221; signal用connect() 方法连接到shutdown函式<br />
$window-&gt;connect(&#8221;destroy&#8221;, &#8220;shutdown&#8221;);<br />
//建立一个GtkButton，按钮文字为&#8221;按我&#8221;<br />
$button = &amp;new GtkButton(&#8221;按我&#8221;);<br />
$button-&gt;connect(&#8221;clicked&#8221;, &#8220;you_clicked&#8221;);<br />
//把GtkButton放到是container的GtkWindow中<br />
$window-&gt;add($button);<br />
//显示$window以及它的所有child widget<br />
$window-&gt;show_all();<br />
//进入程式主回圈(即程式启动之意)<br />
gtk::main();<br />
?&gt;</p>
<p>执行它的话，就会出现一个视窗，里面有一个写着&#8221;按我&#8221;的按钮，按下按钮程式就会执行you_clicked函式。在这个程式中，$window物件 的&#8221;destroy&#8221; signal是在使用者按下视窗右上角的&#8221;X&#8221;时会送出的；而$button物件的&#8221;clicked&#8221; signal是在使用者按下该按钮的时候会送出的。最後那一行的gtk::main() 是一定要执行的，这样才能告诉电脑要开始执行程式，既然有开始执行，那就一定有停止吧? 没错，用gtk::main_quit() 就可以停止程式了。<br />
介绍了PHP的widget应用，然后让我们看一下widget未来可能存在的巨大前景，在手机平台上widget的应用可以说是现在的热点，可以说 widget的巨大前景就是在手机市场上，手机和Widget的关系可以说是已经十分密切了，几乎所有新兴手机操作系统平台都有对Widget的支持，而 且都把widget看成很重要的一个部分，比如android和OphoneOS，webOS，从操作系统来看，手机巨大的市场价值和潜力让widget 在未来有很巨大的市场。</p>
<p>现在在手机操作系统方面，和PHP同样是开源的操作系统android和OphoneOS可以说是未来widget的最好搭档，重所周知，android 和OphoneOS的核心都是linux，而linux也是现在PHP在服务器市场的最佳搭档，从安全和开源的角度来看都将是未来手机平台的巨大推动力 量。android和OphoneOS必然是未来widget的最佳发展平台。<br />
Android 是Google开发的基于Linux平台的开源手机操作系统.象wm,Symbian一样 。同时用户界面UI设计得比Iphone还漂亮，估计未来市场也会不错。对于开发人员或公司来说，不需要购买license，这样极大地节省了开发费用。<br />
OphoenOS是,中国移动主导开发的，采用了linux2.6的系统内核，而且兼容android所有应用的智能手机操作系统。也具备开源软件的所有 优点。同时用户界面UI设计更加人性化，内置了中移动类似移动梦网等主要3G特色业务，未来的网络业务使用起来将非常便利。<br />
从中国移动一贯的市场运作能力来说，这款操作系统以及手机，未来在移动自身的庞大用户市场上推广，可以预计会有比较不错的表现。做为开发人员来说不能不对 它关注。未来的市场，和由此产生的高收入岗位空间，以及给个人创业带来的机会，都是不可小靓的。移动最近又刚推出了在线手机商店，都会进一步推动市场快速 发展。如果大家有兴趣了解Android和Ophone，我给大家推荐2个地址：<br />
学习Gphone Android可以去这里看看<a href="http://www.android.com/" target="_blank">http://www.android.com</a>。有很多开发经验交流内容。<br />
想了解OphoenOS，可以去官方网站<a href="http://www.ophonesdn.com/" target="_blank">http://www.ophonesdn.com</a>，入门教程很实用，有很多开发、移植方法经验交流的文章和帖子，入门不错。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=C1WkN-H6528:1WWbhPslsH0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=C1WkN-H6528:1WWbhPslsH0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=C1WkN-H6528:1WWbhPslsH0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=C1WkN-H6528:1WWbhPslsH0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/C1WkN-H6528" height="1" width="1"/>]]></content:encoded><description>当今在WWW是世界里，PHP已经是一个不可忽视的强大力量，身为开源的先锋，已经为各种的开源产品作出了表率作用，用现在流行的话就是，草根的力量，星 星之火可以燎原，众多的一流网站国外的facebook，Iyohoo,国内有开心网，都是用以前被很多专家看不起的PHP来开发的，开源的产品成为主流 已经成为可能。近几年，随着智能手机普及，手机硬件性能的不断提高，手机已经进入了一个新的阶段，PC机上的众多软件移植到手机系统上已经是大势所趋，移 动系统软件已经成为，软件开发的重要增长点，PHP在移动市场的前景是什么呢？让我们来探索一下。
要说PHP在移动领域的开发，我们首先要先来介绍一个对与PHP和移动领域都很重要的名词“Widget”，要说到Widget，很多人可能都听说过，因 为当今Widget是一个十分有人气的技术概念，在很多的领域都有应用，但恐怕真正知道什么是Widget的人就很少了，下面我先给大家介绍一下什么是 Widget吧，简单的说 Widget就是轻量级的UI控件，为用户展示不同的个性化的信息。
目前Widget主要有4个大类： 
一．	操作系统Widget（如苹果、Windows widget）
二．	网站应用Widget（例如：Facebook、iGoogle。）。
三．	迷你应用程序Widget(Yahoo Widget)。
四．	手机Widget（OphoneOS widget,Android widget,诺基亚widgets）。
下面我介绍一下用PHP来开发widget的一段应用样例：
让我们来看看PHP-GTK
PHP-GTK是PHP的延伸模组，它可以让程式设计师写出在客户端执行的、且独立的GUI的程式。这个模组不允许在浏览器上显视GTK+的程式，它一开始就是开发来写独立的GUI程式的。
Widget是一个GUI程式中基本的functions和forms。最常用的几个Widget是：label、button、window、 frame和text box。所有的widget都是来自於一个抽象的基本class─GtkWidget。每个widget都是一个class
一个Widget一生大概都有五个时期：
1. 建立(Creation)：宣告一个物件(declaring an object)
2. 放置(Placement)：将它加入一个容器中(adding it to a container)
3. 信号连接(Signal Connection)：接收信号以及进行动作(the action it will perform)
4. 显示(Display)：它是否是可见的(whether it is viewable or not)
5. 删除(Destruction)：关闭程式(closing of a program)
Container是一个可以包含其他widget的widget。大部分的widget都是container，例如：GtkWindow、 GtkTable和GtkBox。除了这点之外，container跟其他的widget没两样，也可以被放到其他container去。 Signal(s)当程式设计师在程式中做了一个动作时，程式需要有一个动作来回应使用者的动作。Signals使程式可以知道使用者做了动作并可以触发 适合的回应。Callback就是当signal送出之後，被signal唤起的function。Callback会执行function传回一个值或 是做一个动作。Callback就是signal的handler funciton。它可以是该signal的预设handler或着是程式设计师定义的function。要建立一个callback，就必须把 function connect 到 signal。Signal Inheritance(继承)和methods一样，signals可以被物件继承。一个widget可以送出任何它的parent widget可以送出的还有它自己特有的signal。
你必须为PHP-GTK指定一个callback function当signal送出时来对signal做回应。把一个signal连接到一个function可以用connect() 这个object 方法达成。
如下：
&amp;#60;?php
//建立一个GtkWindow
$window = &amp;#38;new GtkWindow();
//将&amp;#8221;destroy&amp;#8221; [...]</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-09/php-in-the-mobile-field-development-and-exploration/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments><feedburner:origLink>http://www.akii.org/2009-09/php-in-the-mobile-field-development-and-exploration/</feedburner:origLink></item><item><title>囚徒困境下的中国(转)</title><link>http://feedproxy.google.com/~r/akii/~3/S_Z3fQJXokY/</link><category>心情随笔</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Mon, 14 Sep 2009 00:34:53 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/?p=1109</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/wzBhgi2gFGus_RAIJ_4OZQB6bQk/0/da"><img src="http://feedads.g.doubleclick.net/~a/wzBhgi2gFGus_RAIJ_4OZQB6bQk/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/wzBhgi2gFGus_RAIJ_4OZQB6bQk/1/da"><img src="http://feedads.g.doubleclick.net/~a/wzBhgi2gFGus_RAIJ_4OZQB6bQk/1/di" border="0" ismap="true"></img></a></p><p>博弈论里有个著名的“囚徒困境”理论，它实际上说的是在一定环境下人人都怕吃亏而率先作出损人利己的行为。我觉得囚徒困境能够解释当代中国的个人和企业行为。</p>
<p>有过出国经历的人都知道，欧美包括日本等国的老百姓非常遵守法制，具备很高水平的社会公德，如地铁里的上下车，在那里等待上车的人很规矩的在门侧等候，让上面的人先下来再自己上；开车保持一定的车距而不用担心有车会突然插入抢道；晚上没有人看着的时候也会自觉遵守交通信号灯的指挥；这种广泛的对社会公德的遵守，有人说是一个集体理性的表现。从经济学角度讲，达到了纳什均衡。 我觉得是一个有限理性的结果。<br />
<span id="more-1109"></span><br />
而在中国我们看到的是相反的现象。地铁和电梯永远是不等人下来就开始往上挤了，开车经常被抢道插入，任何事情甚至包括看病，人们首先想到的是找关系，通路子。 我觉得这是一个囚徒困境的现象：人人都怕吃亏而率先作出损人利己的行为。</p>
<p>实际上从经济学角度来讲，欧美日的的社会效率是很高的，对社会公德的遵守减低了很多无谓的社会成本，有人研究过，由于保持车距和遵守交通规则，日本一个绿灯时可以通过的车比中国的多；而中国的社会成本很高，比如交通，大多数浪费的时间就是因为这些互不相让的行为。</p>
<p>这些成本上的道理实际上有点智商的人都懂。但为什么还会有这么大的区别呢？有人总喜欢说人的素质不同，或者说文化不同。</p>
<p>我不相信人种的区别，更不认同文化区别的说法，我觉得日本人遵纪守法有制度上的原因。日本历史上一直是一个封建的制度，有时甚至有上百个番王和及其统治的领地，这实际上形成了制度竞争的良性环境。 因为任何一个番王的制度不好，就会失去竞争力。长此以往，日本人对公平的制度有信心，在公平的制度里，人们知道利人也是利己，而形成了遵纪守法的道德和行为方式。 实际上，选择移民的中国人都心知肚明，他们潜意识里就是对这些外国的制度有信心。</p>
<p>因为一个好制度肯定是全民参与讨价还价的结果，所以一定是公平的，或者是制度竞争的结果，也照顾了公平性。所以对制度的信心就是民众对集体行为或者别人行为不损害自己的信心的体现。奥巴马作为第一个有色人种当选总统实际上说明美国人对制度有信心。而台湾马英九必须靠形象和廉洁自律当选实际上说明民众对制度还缺乏信心。</p>
<p>那么从制度上怎么看中国存在的严重的囚徒困局问题呢？中国从秦以后就不再是一个封建国家，缺少制度竞争的环境是产生不了好制度的，大一统国家要想稳定只能靠不断的对反对派的政治压迫，和必须培养依附于制度的利益集团，所有的制度都是为了这些利益集团服务的。这种制度的不公平会使人人都想成为利益集团的成员，其结果是形成了体制化的利己甚至损人利己的行为方式和价值观。</p>
<p>所以，在中国，寻租行为在建立规则的时候就开始了。香港大学教授丁学良总结到：中国现在是由利益集团和为利益集团服务的专家立法，他们往往在制定规则时就已经为自己准备好了自己可以利用的漏洞。这几年的包括大小非的方案，就是服务于一个国有资产这样一个大利益集团。计划生育的国策一直没有成功，而成功国家的经验，如提高教育水平，不会被拿来运用等等，因为中国的计划生育已经形成了一个利益集团，它控制着有关计划生育的一切利益。而搞教育的利益则归属教育部门了，是另一个利益集团的事情了。</p>
<p>丁学良教授认为，在这种制度里，利益的大头由利益集团拿，而成本的大部分由不知情的民众来贡献。从股改为国企的三角债解套开始，哪一个政策不是验证了老百姓买单利益集团得利的说法。每次新政策出台，表面上让老百姓感觉是利国利民的事情，但等政策出来后，再看其结果，则一定是令人大失所望。</p>
<p>三鹿奶粉事件也是囚徒困境下的企业行为。我觉得三鹿知道如果它不这样做，可能就给了蒙牛和伊利赚便宜了，而且蒙牛和伊利多数会逃脱法律的制裁。所以，三鹿不这样做的话，它就没法竞争和生存了。</p>
<p>在这种制度环境里，人们会对任何规则产生怀疑，在可能的情况下，特别是对自己可能有利的时候就一定会践踏这些规则。 然后是这种行为的恶性循环。没有任何规则会得到遵守，而社会形成靠潜规则运行的习惯。</p>
<p>我相信人的行为是制度的结果。而且我认为文化也是制度结果的长期积累的结果。所以，囚徒困局下的中国，由于不信任规则的公平，人人追求个人的最优策略产生对所有参与者而言最糟糕的结果,是一个人人抱怨,抱怨人人的社会。</p>
<p>中国人喊了很多年从我做起的口号，毒奶事件后，最近也不断有人呼吁企业建立诚信。但如果人互相都没有诚信，企业的诚信如何建立？所以，我预测这种呼吁一定完全没有效果，也说明这从我做起的口号也是错的。目前的中国人实际想要的从你做起，我来享受。</p>
<p>有人把“囚徒困境”看成信息不足的结果，我不这么认为，我觉得信息完全是不可能的，可能的是建立互信。而公平制度就是互信的前提。</p>
<p>所以，中国和中国人的改变应该是从制度做起。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=S_Z3fQJXokY:kE-HpxVpQaw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=S_Z3fQJXokY:kE-HpxVpQaw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=S_Z3fQJXokY:kE-HpxVpQaw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=S_Z3fQJXokY:kE-HpxVpQaw:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/S_Z3fQJXokY" height="1" width="1"/>]]></content:encoded><description>博弈论里有个著名的“囚徒困境”理论，它实际上说的是在一定环境下人人都怕吃亏而率先作出损人利己的行为。我觉得囚徒困境能够解释当代中国的个人和企业行为。
有过出国经历的人都知道，欧美包括日本等国的老百姓非常遵守法制，具备很高水平的社会公德，如地铁里的上下车，在那里等待上车的人很规矩的在门侧等候，让上面的人先下来再自己上；开车保持一定的车距而不用担心有车会突然插入抢道；晚上没有人看着的时候也会自觉遵守交通信号灯的指挥；这种广泛的对社会公德的遵守，有人说是一个集体理性的表现。从经济学角度讲，达到了纳什均衡。 我觉得是一个有限理性的结果。

而在中国我们看到的是相反的现象。地铁和电梯永远是不等人下来就开始往上挤了，开车经常被抢道插入，任何事情甚至包括看病，人们首先想到的是找关系，通路子。 我觉得这是一个囚徒困境的现象：人人都怕吃亏而率先作出损人利己的行为。
实际上从经济学角度来讲，欧美日的的社会效率是很高的，对社会公德的遵守减低了很多无谓的社会成本，有人研究过，由于保持车距和遵守交通规则，日本一个绿灯时可以通过的车比中国的多；而中国的社会成本很高，比如交通，大多数浪费的时间就是因为这些互不相让的行为。
这些成本上的道理实际上有点智商的人都懂。但为什么还会有这么大的区别呢？有人总喜欢说人的素质不同，或者说文化不同。
我不相信人种的区别，更不认同文化区别的说法，我觉得日本人遵纪守法有制度上的原因。日本历史上一直是一个封建的制度，有时甚至有上百个番王和及其统治的领地，这实际上形成了制度竞争的良性环境。 因为任何一个番王的制度不好，就会失去竞争力。长此以往，日本人对公平的制度有信心，在公平的制度里，人们知道利人也是利己，而形成了遵纪守法的道德和行为方式。 实际上，选择移民的中国人都心知肚明，他们潜意识里就是对这些外国的制度有信心。
因为一个好制度肯定是全民参与讨价还价的结果，所以一定是公平的，或者是制度竞争的结果，也照顾了公平性。所以对制度的信心就是民众对集体行为或者别人行为不损害自己的信心的体现。奥巴马作为第一个有色人种当选总统实际上说明美国人对制度有信心。而台湾马英九必须靠形象和廉洁自律当选实际上说明民众对制度还缺乏信心。
那么从制度上怎么看中国存在的严重的囚徒困局问题呢？中国从秦以后就不再是一个封建国家，缺少制度竞争的环境是产生不了好制度的，大一统国家要想稳定只能靠不断的对反对派的政治压迫，和必须培养依附于制度的利益集团，所有的制度都是为了这些利益集团服务的。这种制度的不公平会使人人都想成为利益集团的成员，其结果是形成了体制化的利己甚至损人利己的行为方式和价值观。
所以，在中国，寻租行为在建立规则的时候就开始了。香港大学教授丁学良总结到：中国现在是由利益集团和为利益集团服务的专家立法，他们往往在制定规则时就已经为自己准备好了自己可以利用的漏洞。这几年的包括大小非的方案，就是服务于一个国有资产这样一个大利益集团。计划生育的国策一直没有成功，而成功国家的经验，如提高教育水平，不会被拿来运用等等，因为中国的计划生育已经形成了一个利益集团，它控制着有关计划生育的一切利益。而搞教育的利益则归属教育部门了，是另一个利益集团的事情了。
丁学良教授认为，在这种制度里，利益的大头由利益集团拿，而成本的大部分由不知情的民众来贡献。从股改为国企的三角债解套开始，哪一个政策不是验证了老百姓买单利益集团得利的说法。每次新政策出台，表面上让老百姓感觉是利国利民的事情，但等政策出来后，再看其结果，则一定是令人大失所望。
三鹿奶粉事件也是囚徒困境下的企业行为。我觉得三鹿知道如果它不这样做，可能就给了蒙牛和伊利赚便宜了，而且蒙牛和伊利多数会逃脱法律的制裁。所以，三鹿不这样做的话，它就没法竞争和生存了。
在这种制度环境里，人们会对任何规则产生怀疑，在可能的情况下，特别是对自己可能有利的时候就一定会践踏这些规则。 然后是这种行为的恶性循环。没有任何规则会得到遵守，而社会形成靠潜规则运行的习惯。
我相信人的行为是制度的结果。而且我认为文化也是制度结果的长期积累的结果。所以，囚徒困局下的中国，由于不信任规则的公平，人人追求个人的最优策略产生对所有参与者而言最糟糕的结果,是一个人人抱怨,抱怨人人的社会。
中国人喊了很多年从我做起的口号，毒奶事件后，最近也不断有人呼吁企业建立诚信。但如果人互相都没有诚信，企业的诚信如何建立？所以，我预测这种呼吁一定完全没有效果，也说明这从我做起的口号也是错的。目前的中国人实际想要的从你做起，我来享受。
有人把“囚徒困境”看成信息不足的结果，我不这么认为，我觉得信息完全是不可能的，可能的是建立互信。而公平制度就是互信的前提。
所以，中国和中国人的改变应该是从制度做起。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-09/china-under-the-prisoners-dilemma-change/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://www.akii.org/2009-09/china-under-the-prisoners-dilemma-change/</feedburner:origLink></item><item><title>php树型无限级分类结构[预排序遍历树算法]</title><link>http://feedproxy.google.com/~r/akii/~3/hOgbAQW2-3M/</link><category>PHP&amp;MYSQL</category><category>无限级分类</category><category>预排序遍历树算法</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Tue, 08 Sep 2009 11:15:19 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/?p=1107</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/KHAvVZeSZtVGAC128Cq6lMTGDMA/0/da"><img src="http://feedads.g.doubleclick.net/~a/KHAvVZeSZtVGAC128Cq6lMTGDMA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/KHAvVZeSZtVGAC128Cq6lMTGDMA/1/da"><img src="http://feedads.g.doubleclick.net/~a/KHAvVZeSZtVGAC128Cq6lMTGDMA/1/di" border="0" ismap="true"></img></a></p><h2><strong>预排序遍历树算法 modified preorder tree traversal algorithm</strong></h2>
<p>产品分类，多级的树状结构的论坛，邮件列表等许多地方我们都会遇到这样的问题：如何存储多级结构的数据？在PHP的应用中，提供后台数据存储的通常 是关系型数据库，它能够保存大量的数据，提供高效的数据检索和更新服务。然而关系型数据的基本形式是纵横交错的表，是一个平面的结构，如果要将多级树状结 构存储在关系型数据库里就需要进行合理的翻译工作。接下来我会将自己的所见所闻和一些实用的经验和大家探讨一下：</p>
<p>层级结构的数据保存在平面的数据库中基本上有两种常用设计方法：</p>
<p><strong>1、毗邻目录模式(adjacency list model) </strong></p>
<p><strong>2、预排序遍历树算法(modified preorder tree traversal algorithm) </strong></p>
<p>我不是计算机专业的，也没有学过什么数据结构的东西，所以这两个名字都是我自己按照字面的意思翻的，如果说错了还请多多指教。<br />
这两个东西听着好像很吓人，其实非常容易理解。这里我用一个简单食品目录作为我们的示例数据。<br />
<span id="more-1107"></span><br />
我们的数据结构是这样的</p>
<p>以下是代码：</p>
<pre>Food

|

|---Fruit

|    |

|    |---Red

|    |    |

|    |    |--Cherry

|    |

|    |---Yellow

|          |

|          |--Banana

|

|---Meat

     |

     |--Beef

     |

     |--Pork</pre>
<p>为了照顾那些英文一塌糊涂的PHP爱好者<br />
Food:食物<br />
Fruit:水果<br />
Red:红色<br />
Cherry:樱桃<br />
Yellow:黄色<br />
Banana:香蕉<br />
Meat:肉类<br />
Beef:牛肉<br />
Pork:猪肉</p>
<p>毗邻目录模式(adjacency list model)<br />
这种模式我们经常用到，很多的教程和书中也介绍过。我们通过给每个节点增加一个属性 parent 来表示这个节点的父节点从而将整个树状结构通过平面的表描述出来。根据这个原则，例子中的数据可以转化成如下的表：</p>
<p>以下是代码：</p>
<pre>+-----------------------+

|   parent |    name    |

+-----------------------+

|          |    Food    |

|   Food   |   Fruit    |

|   Fruit  |    Green   |

|   Green  |    Pear    |

|   Fruit  |    Red     |

|   Red    |    Cherry  |

|   Fruit  |    Yellow  |

|   Yellow |    Banana  |

|   Food   |    Meat    |

|   Meat   |    Beef    |

|   Meat   |    Pork    |

+-----------------------+</pre>
<p>我们看到 Pear 是Green的一个子节点，Green是Fruit的一个子节点。而根节点&#8217;Food&#8217;没有父节 点。 为了简单地描述这个问题， 这个例子中只用了name来表示一个记录。 在实际的数据库中，你需要用数字的id来标示每个节点，数据库的表结构大概 应该像这样：id, parent_id, name, descrīption。<br />
有了这样的表我们就可以通过数据库保存整个多级树状结构了。</p>
<p>显示多级树<br />
如果我们需要显示这样的一个多级结构需要一个递归函数。</p>
<p>以下是代码：</p>
<pre>&lt;?php

// $parent is the parent of the children we want to see

// $level is increased when we go deeper into the tree,

//        used to display a nice indented tree

function display_children($parent, $level) 

{

   // 获得一个 父节点 $parent 的所有子节点

   $result = mysql_query('SELECT name FROM tree '.

                          'WHERE parent="'.$parent.'";');

   // 显示每个子节点

   while ($row = mysql_fetch_array($result)) 

   {

       // 缩进显示节点名称

       echo str_repeat('  ',$level).$row['name']."n";

       //再次调用这个函数显示子节点的子节点

       display_children($row['name'], $level+1);

   }

}

?&gt;;</pre>
<p>对整个结构的根节点（Food）使用这个函数就可以打印出整个多级树结构，由于Food是根节点它的父节点是空的，所以这样调用: display_children(&#8221;,0)。将显示整个树的内容：</p>
<pre>Food 

Fruit 

 Red 

  Cherry 

 Yellow 

  Banana 

Meat 

 Beef 

 Pork</pre>
<p>如果你只想显示整个结构中的一部分，比如说水果部分，就可以这样调用：display_children(&#8217;Fruit&#8217;,0);</p>
<p>几 乎使用同样的方法我们可以知道从根节点到任意节点的路径。比如 Cherry 的路径是　 &#8220;Food &gt;; Fruit &gt;; Red&#8221;。 为了得到这样的一个路径我们需要从最深的一级&#8221;Cherry&#8221;开始， 查询得到它的父节 点&#8221;Red&#8221;把它添加到路径中， 然后我们再查询Red的父节点并把它也添加到路径中，以此类推直到最高层的&#8221;Food&#8221;</p>
<p>以下是代码：</p>
<pre>&lt;?php

// $node 是那个最深的节点

function get_path($node) 

{

   // 查询这个节点的父节点

   $result = mysql_query('SELECT parent FROM tree '.

                          'WHERE name="'.$node.'";');

   $row = mysql_fetch_array($result);

   // 用一个数组保存路径

   $path = array();

   // 如果不是根节点则继续向上查询

   // (根节点没有父节点)

   if ($row['parent']!='') 

   {

       // the last part of the path to $node, is the name

       // of the parent of $node

       $path[] = $row['parent'];

       // we should add the path to the parent of this node

       // to the path

       $path = array_merge(get_path($row['parent']), $path);

   }

   // return the path

   return $path;

}

?&gt;;</pre>
<p>如果对&#8221;Cherry&#8221;使用这个函数：print_r(get_path(&#8217;Cherry&#8217;))，就会得到这样的一个数组了：</p>
<pre>Array 

( 

  [0] =&gt;; Food 

  [1] =&gt;; Fruit 

  [2] =&gt;; Red 

)</pre>
<p>接下来如何把它打印成你希望的格式，就是你的事情了。</p>
<p>缺点：<br />
这种方法很简单，容易理解，好上手。但是也有一些缺点。主要是因为运行速度很慢，由于得到每个节点都需要进行数据库查询，数据量大的时候要进行很多查询才能完成一个树。另外由于要进行递归运算，递归的每一级都需要占用一些内存所以在空间利用上效率也比较低。</p>
<p>现在让我们看一看另外一种不使用递归计算，更加快速的方法，这就是预排序遍历树算法(modified preorder tree traversal algorithm)<br />
这种方法大家可能接触的比较少，初次使用也不像上面的方法容易理解，但是由于这种方法不使用递归查询算法，有更高的查询效率。</p>
<p>我 们首先将多级数据按照下面的方式画在纸上，在根节点Food的左侧写上 1 然后沿着这个树继续向下 在 Fruit 的左侧写上 2 然后继续前进，沿 着整个树的边缘给每一个节点都标上左侧和右侧的数字。最后一个数字是标在Food 右侧的 18。 在下面的这张图中你可以看到整个标好了数字的多级结 构。（没有看懂？用你的手指指着数字从1数到18就明白怎么回事了。还不明白，再数一遍，注意移动你的手指）。<br />
这些数字标明了各个节点之间的关系，&#8221;Red&#8221;的号是3和6，它是 &#8221;Food&#8221; 1-18 的子孙节点。 同样，我们可以看到 所有左值大于2和右值小于11的节点 都是&#8221;Fruit&#8221; 2-11 的子孙节点</p>
<p>以下是代码：</p>
<pre>                                1 Food 18

                                    |

                +-------------------------------------------+

                |                                                       |

            2 Fruit 11                                    12 Meat 17

                |                                                       |

    +------------------------+                   +-----------------------+

    |                                |                   |                              |

 3 Red 6               7 Yellow 10         13 Beef 14            15 Pork 16

    |                                |

4 Cherry 5               8 Banana 9</pre>
<p>这样整个树状结构可以通过左右值来存储到数据库中。继续之前，我们看一看下面整理过的数据表。</p>
<p>以下是代码：</p>
<pre>+-----------------------+-----+-----+

|   parent |    name  | lft   | rgt |

+-----------------------+-----+-----+

|              |    Food    | 1   | 18  |

|   Food   |   Fruit      | 2   | 11  |

|   Fruit    |    Red      | 3   |  6  |

|   Red     |    Cherry  | 4   |  5  |

|   Fruit    |    Yellow  | 7   | 10  |

|   Yellow |    Banana | 8   |  9  |

|   Food   |    Meat     | 12  | 17  |

|   Meat   |    Beef     | 13  | 14  |

|   Meat   |    Pork     | 15  | 16  |

+-----------------------+-----+-----+</pre>
<p>注意：由于&#8221;left&#8221;和&#8221;right&#8221;在 SQL中有特殊的意义，所以我们需要用&#8221;lft&#8221;和&#8221;rgt&#8221;来表示左右字段。 另外这种结构中不再需要&#8221;parent&#8221;字段来表示树状结构。也就是 说下面这样的表结构就足够了。</p>
<p>以下是代码：</p>
<pre>+------------+-----+-----+

|    name    | lft | rgt |

+------------+-----+-----+

|    Food    | 1   | 18  |

|   Fruit    | 2   | 11  |

|    Red     | 3   |  6  |

|    Cherry  | 4   |  5  |

|    Yellow  | 7   | 10  |

|    Banana  | 8   |  9  |

|    Meat    | 12  | 17  |

|    Beef    | 13  | 14  |

|    Pork    | 15  | 16  |

+------------+-----+-----+</pre>
<p>好了我们现在可以从数据库中获取数据了，例如我们需要得到&#8221;Fruit&#8221;项下的所有所有节点就可以这样写查询语句：<br />
SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;<br />
这个查询得到了以下的结果。</p>
<p>以下是代码：</p>
<pre>+------------+-----+-----+

|    name    | lft | rgt |

+------------+-----+-----+

|   Fruit    | 2   | 11  |

|    Red     | 3   |  6  |

|    Cherry  | 4   |  5  |

|    Yellow  | 7   | 10  |

|    Banana  | 8   |  9  |

+------------+-----+-----+</pre>
<p>看到了吧，只要一个查询就可以得到所有这些节点。为了能够像上面的递归函数那样显示整个树状结构，我们还需要对这样的查询进行排序。用节点的左值进行排序：</p>
<p>SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;</p>
<p>剩下的问题如何显示层级的缩进了。</p>
<p>以下是代码：</p>
<pre>&lt;?php

function display_tree($root) 

{

   // 得到根节点的左右值

   $result = mysql_query('SELECT lft, rgt FROM tree '.'WHERE name="'.$root.'";');

   $row = mysql_fetch_array($result);

   // 准备一个空的右值堆栈

   $right = array();

   // 获得根基点的所有子孙节点

   $result = mysql_query('SELECT name, lft, rgt FROM tree '.

                          'WHERE lft BETWEEN '.$row['lft'].' AND '.

                          $row['rgt'].' ORDER BY lft ASC;');

   // 显示每一行

   while ($row = mysql_fetch_array($result)) 

   {

       // only check stack if there is one

       if (count($right)&gt;;0) 

   {

           // 检查我们是否应该将节点移出堆栈

           while ($right[count($right)-1]&lt;$row['rgt']) 

   {

               array_pop($right);

           }

       }

       // 缩进显示节点的名称

       echo str_repeat('  ',count($right)).$row['name']."n";

       // 将这个节点加入到堆栈中

       $right[] = $row['rgt'];

   }

}

?&gt;;</pre>
<p>如果你运行一下以上的函数就会得到和递归函数一样的结果。只是我们的这个新的函数可能会更快一些，因为只有2次数据库查询。</p>
<p>要获知一个节点的路径就更简单了，如果我们想知道Cherry 的路径就利用它的左右值4和5来做一个查询。</p>
<p>SELECT name FROM tree WHERE lft &lt; 4 AND rgt &gt;; 5 ORDER BY lft ASC;</p>
<p>这样就会得到以下的结果：</p>
<p>以下是代码：</p>
<pre>+------------+

|    name    |

+------------+

|   Food     |

|   Fruit    |

|    Red     |

+------------+</pre>
<p>那么某个节点到底有多少子孙节点呢？很简单，子孙总数=(右值-左值-1)/2<br />
descendants = (right – left - 1) / 2<br />
不相信？自己算一算啦。<br />
用这个简单的公式，我们可以很快的算出&#8221;Fruit 2-11&#8243;节点有4个子孙节点，而&#8221;Banana 8-9&#8243;节点没有子孙节点，也就是说它不是一个父节点了。</p>
<p>很神奇吧？虽然我已经多次用过这个方法，但是每次这样做的时候还是感到很神奇。</p>
<p>这的确是个很好的办法，但是有什么办法能够帮我们建立这样有左右值的数据表呢？这里再介绍一个函数给大家，这个函数可以将name和parent结构的表自动转换成带有左右值的数据表。</p>
<p>以下是代码：</p>
<pre>&lt;?php

function rebuild_tree($parent, $left) {

   // the right value of this node is the left value + 1

   $right = $left+1;

   // get all children of this node

   $result = mysql_query('SELECT name FROM tree '.

                          'WHERE parent="'.$parent.'";');

   while ($row = mysql_fetch_array($result)) {

       // recursive execution of this function for each

       // child of this node

       // $right is the current right value, which is

       // incremented by the rebuild_tree function

       $right = rebuild_tree($row['name'], $right);

   }

   // we've got the left value, and now that we've processed

   // the children of this node we also know the right value

   mysql_query('UPDATE tree SET lft='.$left.', rgt='.

                $right.' WHERE name="'.$parent.'";');

   // return the right value of this node + 1

   return $right+1;

}

?&gt;;</pre>
<p>当然这个函数是一个递归函数，我们需要从根节点开始运行这个函数来重建一个带有左右值的树</p>
<p>rebuild_tree(&#8217;Food&#8217;,1);</p>
<p>这个函数看上去有些复杂，但是它的作用和手工对表进行编号一样，就是将立体多层结构的转换成一个带有左右值的数据表。</p>
<p>那么对于这样的结构我们该如何增加，更新和删除一个节点呢？</p>
<p>增加一个节点一般有两种方法：</p>
<p>第一种，保留原有的name 和parent结构，用老方法向数据中添加数据，每增加一条数据以后使用rebuild_tree函数对整个结构重新进行一次编号。</p>
<p>第 二种，效率更高的办法是改变所有位于新节点右侧的数值。举例来说：我们想增加一种新的水果&#8221;Strawberry&#8221;（草莓）它将成为&#8221;Red&#8221;节点的最后 一个子节点。首先我们需要为它腾出一些空间。&#8221;Red&#8221;的右值应当从6改成8，&#8221;Yellow 7-10 &#8221;的左右值则应当改成 9-12。 依次类推我 们可以得知，如果要给新的值腾出空间需要给所有左右值大于5的节点 （5 是&#8221;Red&#8221;最后一个子节点的右值） 加上2。 所以我们这样进行数据库操 作：</p>
<p>UPDATE tree SET rgt=rgt+2 WHERE rgt&gt;;5;<br />
UPDATE tree SET lft=lft+2 WHERE lft&gt;;5;</p>
<p>这样就为新插入的值腾出了空间，现在可以在腾出的空间里建立一个新的数据节点了， 它的左右值分别是6和7</p>
<p>INSERT INTO tree SET lft=6, rgt=7, name=&#8217;Strawberry&#8217;;</p>
<p>再做一次查询看看吧！怎么样？很快吧。</p>
<p>好了，现在你可以用两种不同的方法设计你的多级数据库结构了，采用何种方式完全取决于你个人的判断，但是对于层次多数量大的结构我更喜欢第二种方法。如果查询量较小但是需要频繁添加和更新的数据，则第一种方法更为简便。</p>
<p>另外，如果数据库支持的话 你还可以将rebuild_tree()和 腾出空间的操作写成数据库端的触发器函数， 在插入和更新的时候自动执行， 这样可以得到更好的运行效率， 而且你添加新节点的SQL语句会变得更加简单。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=hOgbAQW2-3M:aUZ-LlE94uk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=hOgbAQW2-3M:aUZ-LlE94uk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=hOgbAQW2-3M:aUZ-LlE94uk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=hOgbAQW2-3M:aUZ-LlE94uk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/hOgbAQW2-3M" height="1" width="1"/>]]></content:encoded><description>预排序遍历树算法 modified preorder tree traversal algorithm
产品分类，多级的树状结构的论坛，邮件列表等许多地方我们都会遇到这样的问题：如何存储多级结构的数据？在PHP的应用中，提供后台数据存储的通常 是关系型数据库，它能够保存大量的数据，提供高效的数据检索和更新服务。然而关系型数据的基本形式是纵横交错的表，是一个平面的结构，如果要将多级树状结 构存储在关系型数据库里就需要进行合理的翻译工作。接下来我会将自己的所见所闻和一些实用的经验和大家探讨一下：
层级结构的数据保存在平面的数据库中基本上有两种常用设计方法：
1、毗邻目录模式(adjacency list model) 
2、预排序遍历树算法(modified preorder tree traversal algorithm) 
我不是计算机专业的，也没有学过什么数据结构的东西，所以这两个名字都是我自己按照字面的意思翻的，如果说错了还请多多指教。
这两个东西听着好像很吓人，其实非常容易理解。这里我用一个简单食品目录作为我们的示例数据。

我们的数据结构是这样的
以下是代码：
Food

&amp;#124;

&amp;#124;---Fruit

&amp;#124;    &amp;#124;

&amp;#124;    &amp;#124;---Red

&amp;#124;    &amp;#124;    &amp;#124;

&amp;#124;    &amp;#124;    &amp;#124;--Cherry

&amp;#124;    &amp;#124;

&amp;#124;    &amp;#124;---Yellow

&amp;#124;          &amp;#124;

&amp;#124;          &amp;#124;--Banana

&amp;#124;

&amp;#124;---Meat

     &amp;#124;

     &amp;#124;--Beef

     &amp;#124;

     &amp;#124;--Pork
为了照顾那些英文一塌糊涂的PHP爱好者
Food:食物
Fruit:水果
Red:红色
Cherry:樱桃
Yellow:黄色
Banana:香蕉
Meat:肉类
Beef:牛肉
Pork:猪肉
毗邻目录模式(adjacency list model)
这种模式我们经常用到，很多的教程和书中也介绍过。我们通过给每个节点增加一个属性 parent 来表示这个节点的父节点从而将整个树状结构通过平面的表描述出来。根据这个原则，例子中的数据可以转化成如下的表：
以下是代码：
+-----------------------+

&amp;#124;   parent &amp;#124;    name    &amp;#124;

+-----------------------+

&amp;#124;          &amp;#124;    Food    &amp;#124;

&amp;#124;   Food   &amp;#124;   Fruit    &amp;#124;

&amp;#124;   Fruit  &amp;#124;    Green   &amp;#124;

&amp;#124;   Green  &amp;#124;    Pear    &amp;#124;

&amp;#124;   Fruit  &amp;#124;    Red     &amp;#124;

&amp;#124;   Red    &amp;#124;    Cherry  &amp;#124;

&amp;#124;   Fruit  &amp;#124;    Yellow  &amp;#124;

&amp;#124;   Yellow &amp;#124;    Banana  &amp;#124;

&amp;#124;   Food   &amp;#124;    Meat    &amp;#124;

&amp;#124;   Meat   &amp;#124;    Beef    &amp;#124;

&amp;#124;   Meat   &amp;#124;    Pork    &amp;#124;

+-----------------------+
我们看到 Pear 是Green的一个子节点，Green是Fruit的一个子节点。而根节点&amp;#8217;Food&amp;#8217;没有父节 点。 为了简单地描述这个问题， 这个例子中只用了name来表示一个记录。 在实际的数据库中，你需要用数字的id来标示每个节点，数据库的表结构大概 应该像这样：id, parent_id, name, descrīption。
有了这样的表我们就可以通过数据库保存整个多级树状结构了。
显示多级树
如果我们需要显示这样的一个多级结构需要一个递归函数。
以下是代码：
&amp;#60;?php

// $parent is the parent of the children we want to see

// $level is increased when we go deeper into the tree,

//        used to display a nice indented tree

function display_children($parent, $level) 

{

   // 获得一个 父节点 $parent 的所有子节点

   $result = mysql_query('SELECT name FROM tree '.

                          'WHERE parent="'.$parent.'";');

   // 显示每个子节点

   while ($row = mysql_fetch_array($result)) 

   {

       // 缩进显示节点名称

       echo str_repeat('  ',$level).$row['name']."n";

       //再次调用这个函数显示子节点的子节点

       display_children($row['name'], $level+1);

   }

}

?&amp;#62;;
对整个结构的根节点（Food）使用这个函数就可以打印出整个多级树结构，由于Food是根节点它的父节点是空的，所以这样调用: display_children(&amp;#8221;,0)。将显示整个树的内容：
Food 

Fruit 

 Red 

  Cherry 

 Yellow 

  Banana 

Meat 

 Beef 

 Pork
如果你只想显示整个结构中的一部分，比如说水果部分，就可以这样调用：display_children(&amp;#8217;Fruit&amp;#8217;,0);
几 乎使用同样的方法我们可以知道从根节点到任意节点的路径。比如 Cherry 的路径是　 &amp;#8220;Food &amp;#62;; Fruit &amp;#62;; Red&amp;#8221;。 为了得到这样的一个路径我们需要从最深的一级&amp;#8221;Cherry&amp;#8221;开始， 查询得到它的父节 点&amp;#8221;Red&amp;#8221;把它添加到路径中， 然后我们再查询Red的父节点并把它也添加到路径中，以此类推直到最高层的&amp;#8221;Food&amp;#8221;
以下是代码：
&amp;#60;?php

// $node 是那个最深的节点

function get_path($node) 

{

   // 查询这个节点的父节点

   $result = mysql_query('SELECT parent FROM tree '.

                          'WHERE name="'.$node.'";');

   $row = mysql_fetch_array($result);

   // 用一个数组保存路径

   $path = array();

   // 如果不是根节点则继续向上查询

   // (根节点没有父节点)

   if ($row['parent']!='') 

   {

       // the last part of the path to $node, is the name

       // of the parent of $node

       $path[] = $row['parent'];

       // we should add the path to the parent of this node

       // to the path

       $path = array_merge(get_path($row['parent']), $path);

   }

   // return the path

   return $path;

}

?&amp;#62;;
如果对&amp;#8221;Cherry&amp;#8221;使用这个函数：print_r(get_path(&amp;#8217;Cherry&amp;#8217;))，就会得到这样的一个数组了：
Array 

( 

  [0] =&amp;#62;; Food 

  [1] =&amp;#62;; Fruit 

  [2] =&amp;#62;; Red 

)
接下来如何把它打印成你希望的格式，就是你的事情了。
缺点：
这种方法很简单，容易理解，好上手。但是也有一些缺点。主要是因为运行速度很慢，由于得到每个节点都需要进行数据库查询，数据量大的时候要进行很多查询才能完成一个树。另外由于要进行递归运算，递归的每一级都需要占用一些内存所以在空间利用上效率也比较低。
现在让我们看一看另外一种不使用递归计算，更加快速的方法，这就是预排序遍历树算法(modified preorder tree traversal algorithm)
这种方法大家可能接触的比较少，初次使用也不像上面的方法容易理解，但是由于这种方法不使用递归查询算法，有更高的查询效率。
我 们首先将多级数据按照下面的方式画在纸上，在根节点Food的左侧写上 1 然后沿着这个树继续向下 在 Fruit 的左侧写上 2 然后继续前进，沿 着整个树的边缘给每一个节点都标上左侧和右侧的数字。最后一个数字是标在Food 右侧的 18。 在下面的这张图中你可以看到整个标好了数字的多级结 构。（没有看懂？用你的手指指着数字从1数到18就明白怎么回事了。还不明白，再数一遍，注意移动你的手指）。
这些数字标明了各个节点之间的关系，&amp;#8221;Red&amp;#8221;的号是3和6，它是 &amp;#8221;Food&amp;#8221; 1-18 的子孙节点。 同样，我们可以看到 所有左值大于2和右值小于11的节点 都是&amp;#8221;Fruit&amp;#8221; 2-11 的子孙节点
以下是代码：
                                1 Food 18

                                    &amp;#124;

                +-------------------------------------------+

                &amp;#124;                                                       &amp;#124;

            2 Fruit 11                                    12 Meat 17

                &amp;#124;                                                       &amp;#124;

    +------------------------+                   +-----------------------+

    &amp;#124;                                &amp;#124;                   &amp;#124;                              &amp;#124;

 3 Red 6               7 Yellow 10         13 Beef 14            15 Pork 16

    &amp;#124;                                &amp;#124;

4 Cherry 5               8 Banana 9
这样整个树状结构可以通过左右值来存储到数据库中。继续之前，我们看一看下面整理过的数据表。
以下是代码：
+-----------------------+-----+-----+

&amp;#124;   parent &amp;#124;    name  &amp;#124; lft   &amp;#124; rgt &amp;#124;

+-----------------------+-----+-----+

&amp;#124;              &amp;#124;    Food    &amp;#124; 1   &amp;#124; 18  &amp;#124;

&amp;#124;   Food   &amp;#124;   Fruit      &amp;#124; 2   &amp;#124; 11  &amp;#124;

&amp;#124;   Fruit    &amp;#124;    Red      &amp;#124; 3   &amp;#124;  6  &amp;#124;

&amp;#124;   Red     &amp;#124;    Cherry  &amp;#124; 4   &amp;#124;  5  &amp;#124;

&amp;#124;   Fruit    &amp;#124;    Yellow  &amp;#124; 7   &amp;#124; 10  &amp;#124;

&amp;#124;   Yellow &amp;#124;    Banana &amp;#124; 8   &amp;#124;  9  &amp;#124;

&amp;#124;   Food   &amp;#124;    Meat     &amp;#124; 12  &amp;#124; 17  &amp;#124;

&amp;#124;   Meat   &amp;#124;    Beef     &amp;#124; 13  &amp;#124; 14  &amp;#124;

&amp;#124;   Meat   &amp;#124;    Pork     &amp;#124; 15  &amp;#124; 16  &amp;#124;

+-----------------------+-----+-----+
注意：由于&amp;#8221;left&amp;#8221;和&amp;#8221;right&amp;#8221;在 SQL中有特殊的意义，所以我们需要用&amp;#8221;lft&amp;#8221;和&amp;#8221;rgt&amp;#8221;来表示左右字段。 另外这种结构中不再需要&amp;#8221;parent&amp;#8221;字段来表示树状结构。也就是 说下面这样的表结构就足够了。
以下是代码：
+------------+-----+-----+

&amp;#124;    name    &amp;#124; lft &amp;#124; rgt &amp;#124;

+------------+-----+-----+

&amp;#124;    Food    &amp;#124; 1   &amp;#124; 18  &amp;#124;

&amp;#124;   Fruit    &amp;#124; 2   &amp;#124; 11  &amp;#124;

&amp;#124;    Red     &amp;#124; 3   &amp;#124;  6  &amp;#124;

&amp;#124;    Cherry  &amp;#124; 4   &amp;#124;  5  &amp;#124;

&amp;#124;    Yellow  &amp;#124; 7   &amp;#124; 10  &amp;#124;

&amp;#124;    Banana  &amp;#124; 8   &amp;#124;  9  &amp;#124;

&amp;#124;    Meat    &amp;#124; 12  &amp;#124; 17  &amp;#124;

&amp;#124;    Beef    &amp;#124; 13  &amp;#124; 14  &amp;#124;

&amp;#124;    Pork    &amp;#124; 15  &amp;#124; 16  &amp;#124;

+------------+-----+-----+
好了我们现在可以从数据库中获取数据了，例如我们需要得到&amp;#8221;Fruit&amp;#8221;项下的所有所有节点就可以这样写查询语句：
SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;
这个查询得到了以下的结果。
以下是代码：
+------------+-----+-----+

&amp;#124;    name    &amp;#124; lft &amp;#124; rgt &amp;#124;

+------------+-----+-----+

&amp;#124;   Fruit    &amp;#124; 2   &amp;#124; 11  &amp;#124;

&amp;#124;    Red     &amp;#124; 3   &amp;#124;  6  &amp;#124;

&amp;#124;    Cherry  &amp;#124; 4   &amp;#124;  5  &amp;#124;

&amp;#124;    Yellow  &amp;#124; 7   &amp;#124; 10  &amp;#124;

&amp;#124;    Banana  &amp;#124; 8   &amp;#124;  9  &amp;#124;

+------------+-----+-----+
看到了吧，只要一个查询就可以得到所有这些节点。为了能够像上面的递归函数那样显示整个树状结构，我们还需要对这样的查询进行排序。用节点的左值进行排序：
SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;
剩下的问题如何显示层级的缩进了。
以下是代码：
&amp;#60;?php

function display_tree($root) 

{

   // 得到根节点的左右值

   $result = mysql_query('SELECT lft, rgt FROM tree '.'WHERE name="'.$root.'";');

   $row = mysql_fetch_array($result);

   // 准备一个空的右值堆栈

   $right = array();

   // 获得根基点的所有子孙节点

   $result = mysql_query('SELECT name, lft, rgt FROM tree '.

                          'WHERE lft BETWEEN '.$row['lft'].' AND '.

                          $row['rgt'].' ORDER BY lft ASC;');

   // 显示每一行

   while ($row = mysql_fetch_array($result)) 

   {

       // only check stack if there is one

       if (count($right)&amp;#62;;0) 

   {

           // 检查我们是否应该将节点移出堆栈

           while ($right[count($right)-1]&amp;#60;$row['rgt']) 

   {

               array_pop($right);

           }

       }

       // 缩进显示节点的名称

       echo str_repeat('  ',count($right)).$row['name']."n";

       // 将这个节点加入到堆栈中

       $right[] = $row['rgt'];

   }

}

?&amp;#62;;
如果你运行一下以上的函数就会得到和递归函数一样的结果。只是我们的这个新的函数可能会更快一些，因为只有2次数据库查询。
要获知一个节点的路径就更简单了，如果我们想知道Cherry 的路径就利用它的左右值4和5来做一个查询。
SELECT name FROM tree WHERE lft &amp;#60; 4 AND rgt &amp;#62;; 5 ORDER BY lft ASC;
这样就会得到以下的结果：
以下是代码：
+------------+

&amp;#124;    name    &amp;#124;

+------------+

&amp;#124;   Food     &amp;#124;

&amp;#124;   Fruit    &amp;#124;

&amp;#124;    Red     &amp;#124;

+------------+
那么某个节点到底有多少子孙节点呢？很简单，子孙总数=(右值-左值-1)/2
descendants = (right – left - 1) / 2
不相信？自己算一算啦。
用这个简单的公式，我们可以很快的算出&amp;#8221;Fruit 2-11&amp;#8243;节点有4个子孙节点，而&amp;#8221;Banana 8-9&amp;#8243;节点没有子孙节点，也就是说它不是一个父节点了。
很神奇吧？虽然我已经多次用过这个方法，但是每次这样做的时候还是感到很神奇。
这的确是个很好的办法，但是有什么办法能够帮我们建立这样有左右值的数据表呢？这里再介绍一个函数给大家，这个函数可以将name和parent结构的表自动转换成带有左右值的数据表。
以下是代码：
&amp;#60;?php

function rebuild_tree($parent, $left) {

   // the right value of this node is the left value + 1

   $right = $left+1;

   // get all children of this node

   $result = mysql_query('SELECT name FROM tree '.

                          'WHERE parent="'.$parent.'";');

   while ($row = mysql_fetch_array($result)) {

       // recursive execution of this function for each

       // child of this node

       // $right is the current right value, which is

       // incremented by the rebuild_tree function

       $right = rebuild_tree($row['name'], $right);

   }

   // we've got the left value, and now that we've processed

   // the children of this node we also know the right value

   mysql_query('UPDATE tree SET lft='.$left.', rgt='.

                $right.' WHERE name="'.$parent.'";');

   // return the right value of this node + 1

   return $right+1;

}

?&amp;#62;;
当然这个函数是一个递归函数，我们需要从根节点开始运行这个函数来重建一个带有左右值的树
rebuild_tree(&amp;#8217;Food&amp;#8217;,1);
这个函数看上去有些复杂，但是它的作用和手工对表进行编号一样，就是将立体多层结构的转换成一个带有左右值的数据表。
那么对于这样的结构我们该如何增加，更新和删除一个节点呢？
增加一个节点一般有两种方法：
第一种，保留原有的name 和parent结构，用老方法向数据中添加数据，每增加一条数据以后使用rebuild_tree函数对整个结构重新进行一次编号。
第 二种，效率更高的办法是改变所有位于新节点右侧的数值。举例来说：我们想增加一种新的水果&amp;#8221;Strawberry&amp;#8221;（草莓）它将成为&amp;#8221;Red&amp;#8221;节点的最后 一个子节点。首先我们需要为它腾出一些空间。&amp;#8221;Red&amp;#8221;的右值应当从6改成8，&amp;#8221;Yellow 7-10 &amp;#8221;的左右值则应当改成 9-12。 依次类推我 们可以得知，如果要给新的值腾出空间需要给所有左右值大于5的节点 （5 是&amp;#8221;Red&amp;#8221;最后一个子节点的右值） 加上2。 所以我们这样进行数据库操 作：
UPDATE tree SET rgt=rgt+2 WHERE rgt&amp;#62;;5;
UPDATE tree SET lft=lft+2 WHERE lft&amp;#62;;5;
这样就为新插入的值腾出了空间，现在可以在腾出的空间里建立一个新的数据节点了， 它的左右值分别是6和7
INSERT INTO tree SET lft=6, rgt=7, name=&amp;#8217;Strawberry&amp;#8217;;
再做一次查询看看吧！怎么样？很快吧。
好了，现在你可以用两种不同的方法设计你的多级数据库结构了，采用何种方式完全取决于你个人的判断，但是对于层次多数量大的结构我更喜欢第二种方法。如果查询量较小但是需要频繁添加和更新的数据，则第一种方法更为简便。
另外，如果数据库支持的话 你还可以将rebuild_tree()和 腾出空间的操作写成数据库端的触发器函数， 在插入和更新的时候自动执行， 这样可以得到更好的运行效率， 而且你添加新节点的SQL语句会变得更加简单。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-09/php-tree-level-classification-structure-infinite/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">1</slash:comments><feedburner:origLink>http://www.akii.org/2009-09/php-tree-level-classification-structure-infinite/</feedburner:origLink></item><item><title>yahoo $1.99域名注册及转移及补救措施</title><link>http://feedproxy.google.com/~r/akii/~3/N3w7U5DQQFQ/</link><category>domains</category><category>$1.99</category><category>yahoo</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Sat, 29 Aug 2009 10:52:30 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/?p=1105</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/VTywVa4S9t_VVAmDWZo5MOaSIZM/0/da"><img src="http://feedads.g.doubleclick.net/~a/VTywVa4S9t_VVAmDWZo5MOaSIZM/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/VTywVa4S9t_VVAmDWZo5MOaSIZM/1/da"><img src="http://feedads.g.doubleclick.net/~a/VTywVa4S9t_VVAmDWZo5MOaSIZM/1/di" border="0" ismap="true"></img></a></p><p>yahoo推出的$1.99注册或转移域名，确实是能省不少钱。尤其是专业炒米的人。</p>
<p>不过唯有一点不好，那就是一个帐号下只能有一个域名，即享受了一次$1.99那这个帐号就不能再享受第二次了。</p>
<p>本来也是嘛，人家域名注册便宜是为了让你用更多的服务，可是这个便宜被我们给占了，就不能要求太多。</p>
<p>下面说下注册及转移转出要注意的事项及误&#8221;cancel plan&#8221;的补救方法</p>
<p>注册肯定是要第一次享受$1.99的用户，注册链接：<span id="more-1105"></span></p>
<p><a href="http://order.sbs.yahoo.com/ds/ChooseDomain?d=&amp;.p=YD1&amp;m=dom&amp;.src=sbs&amp;.promo=BESTDEAL" target="_blank">yahoo $1.99域名注册</a> 或<a href="http://smallbusiness.yahoo.com/"> http://smallbusiness.yahoo.com/</a></p>
<p>可以信用卡或paypal付款，建议使用paypal付款。因为你只要paypal取消协议，yahoo就不能再自动扣款了。</p>
<p>下面就是要注意的事项，注册之后2个月后你就可以转走了，转到godaddy或name.com都行。强烈不建议转到国内的注册商（国内那也叫注册商？？？简直就是黑心管家婆）。</p>
<p>转移之后，记住要在控制面板中点Cancel Plan。这样就等于取消服务。否则yahoo会在第二年自动从你的信用卡中扣款（这也就是为什么推荐使用paypal了)，即便是使用paypal，建议在付完款后，马上取消关联协议。不取消他也可以从你的paypal上扣钱。</p>
<p>如果你在转移未成功的时候就cancel play了，那你就看不到控制面板了，只能再花$1.99 reactive一下。</p>
<p>我第一次使用这东西的时候，稀里糊涂的在注册完后就给cancel plan了。虽然在cancel plan的时候有提示Authorization Code，但默认域名是锁定状态的。锁定状态的域名是转移不了的。所以，只有重新花1.99去激活面板。</p>
<p>方法是：登陆你的那个ID然后再搜索你的那个米就会有个reactive的链接，然后点reactive的时候会有一个付款的提示，照着做就行了。如果先前已经取消了paypal关联，可以先从你的付款信息&#8221;Your Payment Information&#8221;中把付款方式删除了。再次付款的时候就会重新使用paypal.</p>
<p>另外其它国外域名转移的时候也要注意，第一：解除锁定，第二：你当然要有auth code这个国外注册商都会给你，第三：提前把whois隐藏给去掉。否则有可能收不到ICANN给你发的转移确认邮件（域名的注册人的邮件地址）。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=N3w7U5DQQFQ:Ovt-4RMFH7w:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=N3w7U5DQQFQ:Ovt-4RMFH7w:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=N3w7U5DQQFQ:Ovt-4RMFH7w:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=N3w7U5DQQFQ:Ovt-4RMFH7w:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/N3w7U5DQQFQ" height="1" width="1"/>]]></content:encoded><description>yahoo推出的$1.99注册或转移域名，确实是能省不少钱。尤其是专业炒米的人。
不过唯有一点不好，那就是一个帐号下只能有一个域名，即享受了一次$1.99那这个帐号就不能再享受第二次了。
本来也是嘛，人家域名注册便宜是为了让你用更多的服务，可是这个便宜被我们给占了，就不能要求太多。
下面说下注册及转移转出要注意的事项及误&amp;#8221;cancel plan&amp;#8221;的补救方法
注册肯定是要第一次享受$1.99的用户，注册链接：
yahoo $1.99域名注册 或 http://smallbusiness.yahoo.com/
可以信用卡或paypal付款，建议使用paypal付款。因为你只要paypal取消协议，yahoo就不能再自动扣款了。
下面就是要注意的事项，注册之后2个月后你就可以转走了，转到godaddy或name.com都行。强烈不建议转到国内的注册商（国内那也叫注册商？？？简直就是黑心管家婆）。
转移之后，记住要在控制面板中点Cancel Plan。这样就等于取消服务。否则yahoo会在第二年自动从你的信用卡中扣款（这也就是为什么推荐使用paypal了)，即便是使用paypal，建议在付完款后，马上取消关联协议。不取消他也可以从你的paypal上扣钱。
如果你在转移未成功的时候就cancel play了，那你就看不到控制面板了，只能再花$1.99 reactive一下。
我第一次使用这东西的时候，稀里糊涂的在注册完后就给cancel plan了。虽然在cancel plan的时候有提示Authorization Code，但默认域名是锁定状态的。锁定状态的域名是转移不了的。所以，只有重新花1.99去激活面板。
方法是：登陆你的那个ID然后再搜索你的那个米就会有个reactive的链接，然后点reactive的时候会有一个付款的提示，照着做就行了。如果先前已经取消了paypal关联，可以先从你的付款信息&amp;#8221;Your Payment Information&amp;#8221;中把付款方式删除了。再次付款的时候就会重新使用paypal.
另外其它国外域名转移的时候也要注意，第一：解除锁定，第二：你当然要有auth code这个国外注册商都会给你，第三：提前把whois隐藏给去掉。否则有可能收不到ICANN给你发的转移确认邮件（域名的注册人的邮件地址）。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-08/yahoo-1-99-domain-registration-and-transfer-of-and-remedial-measures/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments><feedburner:origLink>http://www.akii.org/2009-08/yahoo-1-99-domain-registration-and-transfer-of-and-remedial-measures/</feedburner:origLink></item><item><title>php中addslashes() ,mysql_real_escape_string() 和mysql_escape_string() 的区别</title><link>http://feedproxy.google.com/~r/akii/~3/6LlOQeW9fwU/</link><category>PHP&amp;MYSQL</category><category>addslashes</category><category>mysql_escape_string</category><category>mysql_real_escape_string</category><category>php</category><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">snow</dc:creator><pubDate>Mon, 24 Aug 2009 11:05:15 PDT</pubDate><guid isPermaLink="false">http://www.akii.org/?p=1102</guid><content:encoded xmlns:content="http://purl.org/rss/1.0/modules/content/"><![CDATA[
<p><a href="http://feedads.g.doubleclick.net/~a/jZEGDo-JEXcto99uqvH2WOn-bSo/0/da"><img src="http://feedads.g.doubleclick.net/~a/jZEGDo-JEXcto99uqvH2WOn-bSo/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/jZEGDo-JEXcto99uqvH2WOn-bSo/1/da"><img src="http://feedads.g.doubleclick.net/~a/jZEGDo-JEXcto99uqvH2WOn-bSo/1/di" border="0" ismap="true"></img></a></p><p>SQL注入攻击是黑客攻击网站最常用的手段。如果你的站点没有使用严格的用户输入检验，那么常容易遭到SQL注入攻击。SQL注入攻击通常通过给站点数据库提交不良的数据或查询语句来实现，很可能使数据库中的纪录遭到暴露，更改或被删除。</p>
<p>为了防止SQL注入攻击，PHP自带一个功能可以对输入的字符串进行处理，可以在较底层对输入进行安全上的初步处理，也即Magic Quotes。(php.ini magic_quotes_gpc)。如果magic_quotes_gpc选项启用，那么输入的字符串中的单引号，双引号和其它一些字符前将会被自动加 上反斜杠\。</p>
<p>但Magic Quotes并不是一个很通用的解决方案，没能屏蔽所有有潜在危险的字符，并且在许多服务器上Magic Quotes并没有被启用。所以，我们还需要使用其它多种方法来防止SQL注入。<br />
<span id="more-1102"></span><br />
许多数据库本身就提供这种输入数据处理功能。例如PHP的MySQL操作函数中有addslashes()、 mysql_real_escape_string()、mysql_escape_string()等函数，可将特殊字符和可能引起数据库操作出错的字 符转义。那么这三个功能函数之间有什么却别呢？下面我们就来详细讲述下。</p>
<p>虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入，还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于黑客 可以用0xbf27来代替单引号，而addslashes只是将0xbf27修改为0xbf5c27，成为一个有效的多字节字符，其中的0xbf5c仍会 被看作是单引号，所以addslashes无法成功拦截。</p>
<p>当然addslashes也不是毫无用处，它是用于单字节字符串的处理，多字节字符还是用mysql_real_escape_string吧。</p>
<p>另外对于php手册中get_magic_quotes_gpc的举例：<br />
if (!get_magic_quotes_gpc()) {<br />
$lastname = addslashes($_POST[‘lastname’]);<br />
} else {<br />
$lastname = $_POST[‘lastname’];<br />
}<br />
最好对magic_quotes_gpc已经开放的情况下，还是对$_POST[’lastname’]进行检查一下。</p>
<p>再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别：<br />
mysql_real_escape_string 必须在(PHP 4 &gt;= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ，两者的区别是：mysql_real_escape_string 考虑到连接的当前字符集，而mysql_escape_string 不考虑。</p>
<p>总结一下：</p>
<p>* addslashes() 是强行加\；<br />
* mysql_real_escape_string()  会判断字符集，但是对PHP版本有要求；<br />
* mysql_escape_string不考虑连接的当前字符集。</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/akii?a=6LlOQeW9fwU:zfXrf7Qlo0Q:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/akii?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=6LlOQeW9fwU:zfXrf7Qlo0Q:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/akii?i=6LlOQeW9fwU:zfXrf7Qlo0Q:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/akii?a=6LlOQeW9fwU:zfXrf7Qlo0Q:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/akii?d=7Q72WNTAKBA" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/akii/~4/6LlOQeW9fwU" height="1" width="1"/>]]></content:encoded><description>SQL注入攻击是黑客攻击网站最常用的手段。如果你的站点没有使用严格的用户输入检验，那么常容易遭到SQL注入攻击。SQL注入攻击通常通过给站点数据库提交不良的数据或查询语句来实现，很可能使数据库中的纪录遭到暴露，更改或被删除。
为了防止SQL注入攻击，PHP自带一个功能可以对输入的字符串进行处理，可以在较底层对输入进行安全上的初步处理，也即Magic Quotes。(php.ini magic_quotes_gpc)。如果magic_quotes_gpc选项启用，那么输入的字符串中的单引号，双引号和其它一些字符前将会被自动加 上反斜杠\。
但Magic Quotes并不是一个很通用的解决方案，没能屏蔽所有有潜在危险的字符，并且在许多服务器上Magic Quotes并没有被启用。所以，我们还需要使用其它多种方法来防止SQL注入。

许多数据库本身就提供这种输入数据处理功能。例如PHP的MySQL操作函数中有addslashes()、 mysql_real_escape_string()、mysql_escape_string()等函数，可将特殊字符和可能引起数据库操作出错的字 符转义。那么这三个功能函数之间有什么却别呢？下面我们就来详细讲述下。
虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入，还是建议大家加强中文防止SQL注入的检查。addslashes的问题在于黑客 可以用0xbf27来代替单引号，而addslashes只是将0xbf27修改为0xbf5c27，成为一个有效的多字节字符，其中的0xbf5c仍会 被看作是单引号，所以addslashes无法成功拦截。
当然addslashes也不是毫无用处，它是用于单字节字符串的处理，多字节字符还是用mysql_real_escape_string吧。
另外对于php手册中get_magic_quotes_gpc的举例：
if (!get_magic_quotes_gpc()) {
$lastname = addslashes($_POST[‘lastname’]);
} else {
$lastname = $_POST[‘lastname’];
}
最好对magic_quotes_gpc已经开放的情况下，还是对$_POST[’lastname’]进行检查一下。
再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别：
mysql_real_escape_string 必须在(PHP 4 &amp;#62;= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ，两者的区别是：mysql_real_escape_string 考虑到连接的当前字符集，而mysql_escape_string 不考虑。
总结一下：
* addslashes() 是强行加\；
* mysql_real_escape_string()  会判断字符集，但是对PHP版本有要求；
* mysql_escape_string不考虑连接的当前字符集。</description><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://www.akii.org/2009-08/php-in-the-addslashes-mysql_real_escape_string-and-mysql_escape_string-the-difference-between/feed/</wfw:commentRss><slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">0</slash:comments><feedburner:origLink>http://www.akii.org/2009-08/php-in-the-addslashes-mysql_real_escape_string-and-mysql_escape_string-the-difference-between/</feedburner:origLink></item><media:rating>nonadult</media:rating></channel></rss>
