<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title>微风实验室</title>
		<link>http://dev.meettea.com/</link>
		<description>Design,Develop,Program,SEO and UED</description>
		<copyright>Copyright (C) 2004 Security Angel Team [S4T] All Rights Reserved.</copyright>
		<generator>SaBlog-X Version 1.6 Build 20080806</generator>
		<lastBuildDate>Wed, 10 Mar 2010 23:25:16 +0000</lastBuildDate>
		<ttl>30</ttl>
		<item>
			<guid>http://dev.meettea.com/show-74-1.html</guid>
			<title>分享一个Nginx Rewrite的写法</title>
			<author>shiny</author>
			<description><![CDATA[<p>需要的功能：
访问的URL:   www.x.com/download/123.htm ,<br />
如果download模块存在(判断的标志是存在download文件夹以及index.php)<br />
则rewrite到www.x.com/download/index.php,<br />
否则就rewrite到www.x.com/index.php。</p>
<p>
<pre>
	    
	    set $module_name /index.php;
	    if ( $request_uri ~ ^/(\w+)/) {
		set $module_name /$1/index.php;
	    }
	    if ( !-e $document_root$module_name){
		set $module_name /index.php;
	    }
	    rewrite . $module_name;
</pre>
</p>
<p>
友情提示:用rewrite把nginx配置文件中的变量附加到php文件后面的参数里，然后用var_dump($_GET);帮助很大。
</p>]]></description>
			<link>http://dev.meettea.com/show-74-1.html</link>
			<category domain="http://dev.meettea.com/category-4-1.html">微风笔记</category>
			<pubDate>2010-03-06 14:43</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-73-1.html</guid>
			<title>pinyShop0.3新春正式版</title>
			<author>shiny</author>
			<description><![CDATA[<p>新年前的版本，也可能是最后一版。</p>
<p>再写下去可能就要和个性化的要求冲突了。
最好的功能就是nginx.conf。</p>
<b>pinyShop0.3特有功能</b>
<ol>
<li>PHP/Mysql/Nginx任意版本自动发现、使用功能</li>
<li>演示模式/调试模式两不误</li>
<li>Windows界面，状态监视</li>
<li>mysql等默认绑定127.0.0.1，空口令也安全</li>
<li><b>PHP-CGI运行监控，保持运行</b></li>
<li>调试模式下增加目录浏览功能</li>
<li>PHP更新到5.3.1,nginx更新到0.8.31</li>
<li>抛弃process.exe，使用系统自带命令，杀毒软件不再报可疑的程序</li>
</ol>

<p>较之元诞的内测版，这个版本完善了php.ini，增加了PHP-CGI保持运行的功能。</P>
<p>因为很久以前发现windows下php-cgi执行了一定次数的时候会退出，影响调试。
这个功能就是对这个现象的hack。</p>

<a href="http://pinyshop.nginxhome.com">要下载请到这里</a><!--doubanclaim3fb39415bb8d8894-->]]></description>
			<link>http://dev.meettea.com/show-73-1.html</link>
			<category domain="http://dev.meettea.com/category-6-1.html">发布与下载</category>
			<pubDate>2010-02-11 10:17</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-72-1.html</guid>
			<title>征友情链接</title>
			<author>shiny</author>
			<description><![CDATA[<p>为了PR保5争6，诚征友情链接，要求如下</p>
<ol>
<li>业内好友：80%以上原创、和技术相关、内容质量良好</li>
<li>其他人：PR>=5的正规站点；PR<5的，质量优秀的也很愿意交换链接</li>
<li>硬指标：内页免谈；不能被搜索引擎K；不诚者免谈；</li>
<li>撤下链接前请通知我；我撤下链接前也会通知你(不超过底线不会被撤下，底线指道德标准和上一条硬指标。)</li>
<li>郑重承诺：本博客8年内不会关闭(因不可抗力除外：比如全国大海蟹和世界末日)</li>
</ol>]]></description>
			<link>http://dev.meettea.com/show-72-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2010-02-10 10:16</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-71-1.html</guid>
			<title>sa-blog修改与优化</title>
			<author>shiny</author>
			<description><![CDATA[<ol>
<li>对评论使用external nofollow,在index.php里修改。</li>
<li>这个分类像鸡肋，把分类提到导航当作栏目来用。修改模板index即可。</li>
<li>友情链接仅仅在首页显示，这点还是在模板index修改。</li>
<li>评论使用自己的验证码程序，否则将招致垃圾留言robots的群殴。因为这个版本的sablog已经被盯上了。</li>
<li>风格修改(同时对用户体验进行了简单的优化)</li>
<li>title使得符合搜索引擎的要求，主要是在index.php修改$options['title']这个变量</li>
</ol>
<p>缺点(优点?):chrome下发表日志得自己写HTML代码。</p>
<p>喜欢这个blog想要源码的可以留下邮箱。</p>]]></description>
			<link>http://dev.meettea.com/show-71-1.html</link>
			<category domain="http://dev.meettea.com/category-5-1.html">PHP</category>
			<pubDate>2010-02-10 09:55</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-70-1.html</guid>
			<title>sina sae试用报告</title>
			<author>shiny</author>
			<description><![CDATA[近闻sina staff,sae已开放申请；不过因为计费系统测试中so不要抱很高的希望。

已申请到sina sae,对其试用一番。

<ol>
<li>经过简单修改就可以使用wordpress blog (这是一个open source project,我搭建了一个示例blog,<a href="http://wp4sae.sinaapp.com/">click here</a>)</li>
<li>集成了：Mysql，Storage，MemCache，Cron Jobs，Image，Fetch Url，Mail(并禁用一大堆函数和类)</li>
<li>禁用的函数和类的列表在<a href="http://wiki.sae.sina.com.cn/doku.php?id=sae%E5%BC%80%E5%8F%91%E8%80%85%E6%89%8B%E5%86%8C#运行环境简介">这里</a>,看得我眼睛麻花疼。</li>
<li>sina app目前还没有提供本地测试环境，原话如下：“因为本地环境的开发较为费时,且需要和线上保持同步更新,我们暂时还没有提供本地测试环境的计划.”</li>
<li><strike>sina app目前还无法绑定独立域名，原话如下：“考虑到备案和域名验证的原因,目前暂不开发独立域名绑定功能”</strike>目前已经能绑定了，用cname解析，但是“如果您使用独立域名,请先行备案,否则应用可能被关闭.”</li>
<li>上面的数据储存是：“目前是用MongoDB做的一个实现,未来有可能换成S3.”</li>
<li>对svn的支持：“目前暂时不提供.我们会在后期考虑svn/git服务.建议大家用公司的svn处理内部项目,用google code组织开源项目. upload的时候会提示是否只上传修改后的代码.目前暂时没有选择部分代码上传的功能.”</li>
<li>对.htaccess的支持：“.htaccess因为可能导致性能瓶颈暂时不支持,我们稍后会提供用于rewrite的替代方案.”</li>
<li>目前资源限制为：<ul>
<li><b>httpd</b><ul>
<li>请求次数	10000000 次</li>
<li>流入带宽	500000 KB</li>
<li>流出带宽	1000000 KB</li>
<li>CPU时间	10800000 MS</li>
</ul></li>
<li><b>Mysql</b><ul>
<li>查询次数	1000000 次</li>
<li>写入Mysql的数据量	1000000 KB</li>
<li>从Mysql读出的数据量	1000000 KB</li>
<li>CPU时间	10800000 MS</li>
<li>数据存储总量	195312.5 KB</li>
</ul></li>
<li><b>Memcache</b><ul>
<li>请求次数	10000000 次</li>
<li>写入MC的数据量	1000000 KB</li>
<li>从MC读出的数据量	1000000 KB</li>
</ul></li>
<li><b>Fetch URL</b><ul>
<li>请求次数	50000 次	</li>
<li>流入带宽	500000 KB</li>	
<li>流出带宽	500000 KB</li>	
</ul></li>
<li><b>数据存储</b><ul>
<li>请求次数	100000 次</li>
<li>流入带宽	976562.5 KB</li>
<li>流出带宽	976562.5 KB</li>
<li>数据存储总量	195312.5 KB</li>
</ul></li>
<li><b>图片处理</b><ul>
<li>请求次数	100000 次</li>
<li>流入带宽	976562.5 KB</li>
<li>流出带宽	976562.5 KB</li>
<li>CPU时间	36000000 MS</li>
</ul></li>
</ul></li>
<li>预计日后会推出收费版的服务</li>
<li>用am.php脚本管理项目,windows下还有一个exe，不过体验并不好，还是脚本简便。</li>
<li>懒了，不上图了，申请地址，<a href="http://sae.sina.com.cn/?m=inviterequest">http://sae.sina.com.cn/?m=inviterequest</a>，如果你只是想简单的使用，恐怕还不能通过。此外一天100个名额，早上申请可能比较合适。</li>
</ol>
shiny 如是记。
<p>PS：如果你的代码写得合理，能够很顺利就迁移到sina app上。</p>]]></description>
			<link>http://dev.meettea.com/show-70-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2010-02-03 09:15</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-69-1.html</guid>
			<title>沉默许久，近期纪要</title>
			<author>shiny</author>
			<description><![CDATA[<ol>
<li>
<p>找到了适合个人使用的CDN服务，按流量算钱，1G在2~6元之间。根据以前植物大战僵尸论坛的流量表现看，一个月也就两三G(日700ip，较高PV，多图)。示例，www.asia-home.com.cn 这个站用了该CDN Service Provider的服务。杭州电信的ping在6ms，速度非常猛。虽然这个站前端一塌糊涂，但是依托CDN依然表现不错。</p>

<p><strike>过段时间博客先试水(等有钱之后吧)。</strike>然后普及到几个站。现在博客已经启用CDN了，过段时间贴出监控宝速度检测的情况。</p>

<p>主机放国外，然后用国内的CDN加速，这样最理想，安全性和速度得到了最大的平衡。</p></li>

<li>开始制作些垃圾站(垃圾站中的战斗鸡)来维持开销。上规模后请些朋友来帮忙。</li>

<li>pinyShop 0.3用了段时间，很稳定。反馈不错。2010春节final版将于近期释出。除非有很好的理由否则将是绝版。</li>

<li>和宝哥哥聊了人生，引以为戒。</li>

<li>决定不再以加入专业IT公司(比如淘宝UED Team或者某些IT公司的CTO岗位)为职业目标。</li>

<li>不要随随便便承诺，勇于承担自己的责任，学会做商人和团队领袖。</li>

<li>淡泊、珍惜时间、隐、如果选择的时候犹豫了就坚决放弃</li>

<li>男人都以为自己可以改变世界，女人都以为自己可以改变男人</li>

<li>发这篇日志的最大目的是向大家传递一个信息：哥还活着，哥在江湖飘</li>

<li>发言完毕，谢谢大家，凑齐十条</li>
</ol>]]></description>
			<link>http://dev.meettea.com/show-69-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2010-02-02 10:10</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-67-1.html</guid>
			<title>请允许我说点和技术无关的事情</title>
			<author>shiny</author>
			<description><![CDATA[<p>
黄炎培问毛泽东：“当共产党执政后，没有了战争的压力，也没有反对党的监督，党员思想必松懈，继尔形成惰性，当享乐成风之时，你怎么解决权力腐败，跳出这个政党存亡的周期？” 毛泽东铿锵有力地回答：“我们已经找到了解决这个问题的办法，这就是‘民主’，即人民群众的监督。只有让人民起来监督政府，政府才不敢松懈。只有人人起来负责，才不会人亡政息。”</p>
<p>。。。</p>
<p>黄大能说，这次长谈，使父亲从此扭转了他历来对中共执政的忐忑不安，他从延安、从毛泽东身上看到，中国是有出路的，这出路就在共产党那里。从此以后，他坚定不移跟着共产党走。开国之初，大半生恪守“不为官吏”信条的黄炎培终于出山，担任了第一届中央人民政府政务院副总理。</p>
<p>。。。</p>]]></description>
			<link>http://dev.meettea.com/show-67-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2010-01-09 10:35</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-66-1.html</guid>
			<title>PHP版简易动态口令卡</title>
			<author>shiny</author>
			<description><![CDATA[<p>PHP版简易动态口令卡</p>
<p>WUCHA.CC是一个尚在开发中的文学网站。考虑到初期编辑分布比较广泛、编辑的操作对网站有较大的影响，故设计了网站编辑专用的动态口令卡。<br />
同样也适用对安全性有中等要求的中小型网站、博客。</p>
<p>先上图，有图有真相。</p>
<p>[attach=56]</p>
<p>[attach=57]</p>
<p>[attach=58]</p>
<p>[attach=59]</p>
<p>[attach=60]</p>
<p>连号的感觉真好 - -<br />
设计采用PHOTOSHOP。打印选择了<a href="http://www.kuukie.com">KUUKIE.COM</a>（趣奇网）的个性卡片印刷服务。<br />
趣奇网有两种规格的个性卡片。一种是名片的一半，一种和名片一样大小。</p>
<p>&nbsp;(咳咳咳咳，这里AD下趣奇网)</p>
<p>趣奇网是一家新兴的在线打印照片服务的网站。</p>
<p>你可以把你的照片等拿去印刷，也可以做些小卡片。</p>
<p>被我拿来打印口令卡纯属意外 :)</p>
<p>在互联网政策不明朗的今天，新兴网站的生存并不容易。</p>
<p>趣奇网的存在还是令我们告慰的，希望他们能够成长壮大。 :)</p>
<p>&nbsp;</p>
<p>首先是制作正面图像、背景的网格。&nbsp;</p>
<p>[attach=53]&nbsp;[attach=54]<br />
这里要注意的是，实际上剪裁的效果看（和上面的实图对比），和趣奇网提供的PSD模板有点差距，顶部有空隙[绿色线是安全线]。<br />
[attach=55]</p>
<p>然后用这段PHP代码生成动态口令并存入数据库。</p>
<div class="codeText">
<div class="codeHead">PHP代码</div>
<ol class="dp-c">
    <li class="alt"><span><span>&lt;?php &nbsp;&nbsp;</span></span></li>
    <li><span>#</span><span class="func">error_reporting</span><span>(0); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$host</span><span>&nbsp;=&nbsp;</span><span class="string">'localhost'</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="vars">$user</span><span>&nbsp;=&nbsp;</span><span class="string">'root'</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$passwd</span><span>&nbsp;=&nbsp;</span><span class="string">''</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="vars">$db</span><span>&nbsp;=&nbsp;</span><span class="string">'dpasswd'</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>mysql_connect(</span><span class="vars">$host</span><span>,</span><span class="vars">$user</span><span>,</span><span class="vars">$passwd</span><span>); &nbsp;&nbsp;</span></li>
    <li><span>mysql_select_db(</span><span class="vars">$db</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li><span class="vars">$query</span><span>&nbsp;=&nbsp;mysql_query(</span><span class="string">'select&nbsp;count(*)&nbsp;as&nbsp;maxID&nbsp;from&nbsp;dpasswd'</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">if</span><span>(!</span><span class="vars">$query</span><span>){&nbsp;</span><span class="func">exit</span><span>(</span><span class="string">'could&nbsp;not&nbsp;get&nbsp;max&nbsp;id&nbsp;record,program&nbsp;exit;'</span><span>);} &nbsp;&nbsp;</span></li>
    <li><span class="vars">$tmpArr</span><span>&nbsp;=&nbsp;mysql_fetch_assoc(</span><span class="vars">$query</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$ID</span><span>&nbsp;=&nbsp;</span><span class="vars">$tmpArr</span><span>[</span><span class="string">'maxID'</span><span>]+1; &nbsp;&nbsp;</span></li>
    <li><span class="vars">$ID</span><span>&nbsp;=&nbsp;</span><span class="func">str_pad</span><span>(</span><span class="vars">$ID</span><span>,&nbsp;5,&nbsp;</span><span class="string">'0'</span><span>,&nbsp;STR_PAD_LEFT); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li><span class="vars">$arrRand</span><span>&nbsp;=&nbsp;</span><span class="keyword">array</span><span>(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">for</span><span>(</span><span class="vars">$i</span><span>=0;</span><span class="vars">$i</span><span>&lt;6;</span><span class="vars">$i</span><span>++){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$arrRand</span><span>[]&nbsp;=&nbsp;</span><span class="keyword">array</span><span>(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>(</span><span class="vars">$j</span><span>=0;</span><span class="vars">$j</span><span>&lt;11;</span><span class="vars">$j</span><span>++){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$arrRand</span><span>[</span><span class="vars">$i</span><span>][</span><span class="vars">$j</span><span>]&nbsp;=&nbsp;rand(0,9).rand(0,9); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li><span class="vars">$im</span><span>=imagecreatefrompng(</span><span class="string">&quot;./bg.png&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$x</span><span>&nbsp;=&nbsp;155; &nbsp;&nbsp;</span></li>
    <li><span class="vars">$y</span><span>&nbsp;=&nbsp;230; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$widthPerGrid</span><span>&nbsp;=&nbsp;74; &nbsp;&nbsp;</span></li>
    <li><span class="vars">$heightPerGrid</span><span>=&nbsp;75; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$noFontSize</span><span>&nbsp;=&nbsp;35; &nbsp;&nbsp;</span></li>
    <li><span class="vars">$numFontSize</span><span>&nbsp;=&nbsp;30; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
    <li><span class="vars">$no_start</span><span>&nbsp;=&nbsp;</span><span class="string">'A'</span><span>.</span><span class="vars">$ID</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$black</span><span>&nbsp;=&nbsp;imagecolorallocate(</span><span class="vars">$im</span><span>,0,0,0); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>#图像资源、字体大小、角度 &nbsp;&nbsp;</span></li>
    <li><span>imagettftext(</span><span class="vars">$im</span><span>,</span><span class="vars">$noFontSize</span><span>,0,200,115,</span><span class="vars">$black</span><span>,</span><span class="string">'tahoma.ttf'</span><span>,</span><span class="vars">$no_start</span><span>); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">for</span><span>(</span><span class="vars">$i</span><span>=0;</span><span class="vars">$i</span><span>&lt;6;</span><span class="vars">$i</span><span>++){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">for</span><span>(</span><span class="vars">$j</span><span>=0;</span><span class="vars">$j</span><span>&lt;11;</span><span class="vars">$j</span><span>++){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;imagettftext(</span><span class="vars">$im</span><span>,</span><span class="vars">$numFontSize</span><span>,0,</span><span class="vars">$x</span><span>,</span><span class="vars">$y</span><span>,</span><span class="vars">$black</span><span>,</span><span class="string">'tahoma.ttf'</span><span>,</span><span class="vars">$arrRand</span><span>[</span><span class="vars">$i</span><span>][</span><span class="vars">$j</span><span>]); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$x</span><span>+=</span><span class="vars">$widthPerGrid</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$x</span><span>-=(</span><span class="vars">$widthPerGrid</span><span>*11); &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$y</span><span>+=</span><span class="vars">$heightPerGrid</span><span>; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="vars">$num</span><span>&nbsp;=&nbsp;</span><span class="string">''</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">foreach</span><span>(</span><span class="vars">$arrRand</span><span>&nbsp;</span><span class="keyword">as</span><span>&nbsp;</span><span class="vars">$item</span><span>){ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$num</span><span>&nbsp;.=&nbsp;implode(</span><span class="string">''</span><span>,</span><span class="vars">$item</span><span>); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>mysql_query(</span><span class="string">&quot;INSERT&nbsp;INTO&nbsp;dpasswd&nbsp;(type,num)&nbsp;values&nbsp;('A','{$num}')&quot;</span><span>); &nbsp;&nbsp;</span></li>
    <li><span class="vars">$card_id</span><span>&nbsp;=&nbsp;mysql_insert_id(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">if</span><span>(imagepng(</span><span class="vars">$im</span><span>,</span><span class="vars">$no_start</span><span>.</span><span class="string">'.png'</span><span>)){ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="func">echo</span><span>&nbsp;</span><span class="string">'密保卡已经生成:'</span><span>,</span><span class="vars">$no_start</span><span>,</span><span class="string">'.png'</span><span>,</span><span class="string">';数据库中的ID:'</span><span>,</span><span class="vars">$card_id</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="func">echo</span><span>&nbsp;</span><span class="string">'密保卡:'</span><span>,</span><span class="vars">$no_start</span><span>,</span><span class="string">'.png'</span><span>,</span><span class="string">'生成失败'</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<div class="codeText">
<div class="codeHead">SQL代码</div>
<ol class="dp-sql">
    <li class="alt"><span><span class="keyword">DROP</span><span>&nbsp;</span><span class="keyword">TABLE</span><span>&nbsp;IF&nbsp;EXISTS&nbsp;`dpasswd`; &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">CREATE</span><span>&nbsp;</span><span class="keyword">TABLE</span><span>&nbsp;`dpasswd`&nbsp;( &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;`dpasswdID`&nbsp;</span><span class="keyword">int</span><span>(10)&nbsp;unsigned&nbsp;</span><span class="op">NOT</span><span>&nbsp;</span><span class="op">NULL</span><span>&nbsp;AUTO_INCREMENT, &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;`type`&nbsp;</span><span class="keyword">char</span><span>(2)&nbsp;</span><span class="keyword">DEFAULT</span><span>&nbsp;</span><span class="op">NULL</span><span>, &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;`num`&nbsp;</span><span class="keyword">char</span><span>(132)&nbsp;</span><span class="keyword">CHARACTER</span><span>&nbsp;</span><span class="keyword">SET</span><span>&nbsp;ascii&nbsp;</span><span class="op">NOT</span><span>&nbsp;</span><span class="op">NULL</span><span>, &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">PRIMARY</span><span>&nbsp;</span><span class="keyword">KEY</span><span>&nbsp;(`dpasswdID`) &nbsp;&nbsp;</span></li>
    <li class="alt"><span>)&nbsp;ENGINE=MyISAM&nbsp;AUTO_INCREMENT=51&nbsp;</span><span class="keyword">DEFAULT</span><span>&nbsp;CHARSET=utf8;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>每次刷新都会使编号+1并生成一张动态口令卡。<br />
随机数的产生并没有用到种子等概念。<br />
产生完毕后数据库、本地文件各存一份。</p>
<p>趣奇网提供了批量上传图片的功能，很快就上传完毕。需要注意的是为了方便，文字面打印正面图片，正面则放生成的口令卡图片。</p>
<p>最后，感谢CCTV感谢MTV感谢支持我的fans们，WUCHA is coming soon。。。。&nbsp;</p>]]></description>
			<link>http://dev.meettea.com/show-66-1.html</link>
			<category domain="http://dev.meettea.com/category-5-1.html">PHP</category>
			<pubDate>2010-01-04 14:09</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-62-1.html</guid>
			<title>从linux kernel coding style看php代码规范</title>
			<author>shiny</author>
			<description><![CDATA[<p>从linux kernel coding style看php代码规范</p>
<p>linux内核的编码是一种极端情况。</p>
<p>需要清晰明朗以供全世界的开发者学习、修改，对代码的质量要求较高。</p>
<p>相信linus大神在长期接触各种各式代码后脾气会变得更暴躁，就比如前段时间在某论坛痛斥C++。。。</p>
<p>节选，去除不适合PHP程序员阅读的部分。</p>
<p>如果你开发PHP程序的核心代码，比如框架，尤其建议好好思考。</p>
<p>虽然，它和一些权威的代码规范比如discuz和zend的有所冲突，但是依然能从中受益。</p>
<p>linux kernel coding style (针对PHPer作了节选)</p>
<p>linux kernel coding style的中文译者:</p>
<p>中文版维护者： 张乐 Zhang Le</p>
<p>中文版翻译者： 张乐 Zhang Le</p>
<p>中文版校译者： 王聪 Wang Cong</p>
<p>wheelz</p>
<p>管旭东 Xudong Guan</p>
<p>Li Zefan</p>
<p>Wang Chen</p>
<p>&nbsp;</p>
<p><strong>第一章：缩进</strong></p>
<p>制表符是8个字符，所以缩进也是8个字符。有些异端运动试图将缩进变为4（乃至2）个字符</p>
<p>深，这几乎相当于尝试将圆周率的值定义为3。</p>
<p>理由：缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的屏幕</p>
<p>连续看了20小时之后，你将会发现大一点的缩进会使你更容易分辨缩进。</p>
<p>现在，有些人会抱怨8个字符的缩进会使代码向右边移动的太远，在80个字符的终端屏幕上</p>
<p>就很难读这样的代码。这个问题的答案是，如果你需要3级以上的缩进，不管用何种方式你</p>
<p>的代码已经有问题了，应该修正你的程序。</p>
<p>在switch语句中消除多级缩进的首选的方式是让&ldquo;switch&rdquo;和从属于它的&ldquo;case&rdquo;标签对齐于同</p>
<p>一列，而不要&ldquo;两次缩进&rdquo;&ldquo;case&rdquo;标签。比如：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">switch</span><span>&nbsp;(suffix)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">case</span><span>&nbsp;</span><span class="string">'G'</span><span>: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">case</span><span>&nbsp;</span><span class="string">'g'</span><span>: &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem&nbsp;&lt;&lt;=&nbsp;30; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">case</span><span>&nbsp;</span><span class="string">'M'</span><span>: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">case</span><span>&nbsp;</span><span class="string">'m'</span><span>: &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem&nbsp;&lt;&lt;=&nbsp;20; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">case</span><span>&nbsp;</span><span class="string">'K'</span><span>: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">case</span><span>&nbsp;</span><span class="string">'k'</span><span>: &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mem&nbsp;&lt;&lt;=&nbsp;10; &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="comment">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*&nbsp;fall&nbsp;through&nbsp;*/</span><span>&nbsp;&nbsp;</span></li>
    <li><span class="keyword">default</span><span>: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</span><span>; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>不要把多个语句放在一行里，除非你有什么东西要隐藏：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(condition)&nbsp;do_this; &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp; do_something_everytime;&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读的表</p>
<p>达式。</p>
<p>除了注释、文档和Kconfig之外，不要使用空格来缩进，前面的例子是例外，是有意为之。</p>
<p>选用一个好的编辑器，不要在行尾留空格。</p>
<p>&nbsp;</p>
<p><strong>第二章：把长的行和字符串打散</strong></p>
<p>代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。</p>
<p>每一行的长度的限制是80列，我们强烈建议您遵守这个惯例。</p>
<p>长于80列的语句要打散成有意义的片段。每个片段要明显短于原来的语句，而且放置的位置</p>
<p>也明显的靠右。同样的规则也适用于有很长参数列表的函数头。长字符串也要打散成较短的</p>
<p>字符串。唯一的例外是超过80列可以大幅度提高可读性并且不会隐藏信息的情况。</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">void</span><span>&nbsp;fun(</span><span class="datatypes">int</span><span>&nbsp;a,&nbsp;</span><span class="datatypes">int</span><span>&nbsp;b,&nbsp;</span><span class="datatypes">int</span><span>&nbsp;c) &nbsp;&nbsp;</span></span></li>
    <li><span>{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if</span><span>&nbsp;(condition) &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_WARNING&nbsp;</span><span class="string">&quot;Warning&nbsp;this&nbsp;is&nbsp;a&nbsp;long&nbsp;&quot;</span></li>
    <li class="alt"><span class="string">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;3&nbsp;parameters&nbsp;a:&nbsp;%u&nbsp;b:&nbsp;%u&nbsp;&quot;</span><span>&nbsp;&nbsp;</span></li>
    <li><span class="string">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;c:&nbsp;%u&nbsp;\n&quot;</span><span>,&nbsp;a,&nbsp;b,&nbsp;c); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else</span><span>&nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; next_statement; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;</p>
<p><strong>第三章：大括号和空格的放置</strong></p>
<p>C语言风格中另外一个常见问题是大括号的放置。和缩进大小不同，选择或弃用某种放置策</p>
<p>略并没有多少技术上的原因，不过首选的方式，就像Kernighan和Ritchie展示给我们的，是</p>
<p>把起始大括号放在行尾，而把结束大括号放在行首，所以：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(x&nbsp;is&nbsp;</span><span class="keyword">true</span><span>)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; we&nbsp;</span><span class="keyword">do</span><span>&nbsp;y &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;这适用于所有的非函数语句块（if、switch、for、while、do）。比如：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">switch</span><span>&nbsp;(action)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span class="keyword">case</span><span>&nbsp;KOBJ_ADD: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return</span><span>&nbsp;</span><span class="string">&quot;add&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">case</span><span>&nbsp;KOBJ_REMOVE: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return</span><span>&nbsp;</span><span class="string">&quot;remove&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">case</span><span>&nbsp;KOBJ_CHANGE: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return</span><span>&nbsp;</span><span class="string">&quot;change&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li><span class="keyword">default</span><span>: &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="keyword">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return</span><span>&nbsp;NULL; &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>不过，有一个例外，那就是函数：函数的起始大括号放置于下一行的开头，所以：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="datatypes">int</span><span>&nbsp;function(</span><span class="datatypes">int</span><span>&nbsp;x) &nbsp;&nbsp;</span></span></li>
    <li><span>{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body&nbsp;of&nbsp;function &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;全世界的异端可能会抱怨这个不一致性是&hellip;&hellip;呃&hellip;&hellip;不一致的，不过所有思维健全的人都知道（</p>
<p>a）K&amp;R是_正确的_，并且（b）K&amp;R是正确的。此外，不管怎样函数都是特殊的（在C语言中</p>
<p>，函数是不能嵌套的）。</p>
<p>注意结束大括号独自占据一行，除非它后面跟着同一个语句的剩余部分，也就是do语句中的</p>
<p>&ldquo;while&rdquo;或者if语句中的&ldquo;else&rdquo;，像这样：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">do</span><span>&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; body&nbsp;of&nbsp;</span><span class="keyword">do</span><span>-loop &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;</span><span class="keyword">while</span><span>&nbsp;(condition); &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;和</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(x&nbsp;==&nbsp;y)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .. &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;</span><span class="keyword">else</span><span>&nbsp;</span><span class="keyword">if</span><span>&nbsp;(x&nbsp;&gt;&nbsp;y)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ... &nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>.... &nbsp;&nbsp;</span></li>
    <li class="alt"><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;理由：K&amp;R。</p>
<p>&nbsp;也请注意这种大括号的放置方式也能使空（或者差不多空的）行的数量最小化，同时不失可</p>
<p>读性。因此，由于你的屏幕上的新行是不可再生资源（想想25行的终端屏幕），你将会有更</p>
<p>多的空行来放置注释。</p>
<p>&nbsp;当只有一个单独的语句的时候，不用加不必要的大括号。</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(condition) &nbsp;&nbsp;</span></span></li>
    <li><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>action();&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;这点不适用于本身为某个条件语句的一个分支的单独语句。这时需要在两个分支里都使用大</p>
<p>括号。</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(condition)&nbsp;{ &nbsp;&nbsp;</span></span></li>
    <li><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>do_this(); &nbsp;&nbsp;</span></li>
    <li class="alt"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>do_that(); &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>otherwise(); &nbsp;&nbsp;</span></li>
    <li><span>} &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;3.1：空格</p>
<p>Linux内核的空格使用方式（主要）取决于它是用于函数还是关键字。（大多数）关键字后</p>
<p>要加一个空格。值得注意的例外是sizeof、typeof、alignof和__attribute__，这些关键字</p>
<p>某些程度上看起来更像函数（它们在Linux里也常常伴随小括号而使用，尽管在C语言里这样</p>
<p>的小括号不是必需的，就像&ldquo;struct fileinfo info&rdquo;声明过后的&ldquo;sizeof info&rdquo;）。</p>
<p>&nbsp;所以在这些关键字之后放一个空格：</p>
<p>if, switch, case, for, do, while</p>
<p>但是不要在sizeof、typeof、alignof或者__attribute__这些关键字之后放空格。例如，</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>s&nbsp;=&nbsp;</span><span class="keyword">sizeof</span><span>(</span><span class="keyword">struct</span><span>&nbsp;file);&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>不要在小括号里的表达式两侧加空格。这是一个反例：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>s&nbsp;=&nbsp;</span><span class="keyword">sizeof</span><span>(&nbsp;</span><span class="keyword">struct</span><span>&nbsp;file&nbsp;);&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>&nbsp;当声明指针类型或者返回指针类型的函数时，&ldquo;*&rdquo;的首选使用方式是使之靠近变量名或者函</p>
<p>数名，而不是靠近类型名。例子：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="datatypes">char</span><span>&nbsp;*linux_banner; &nbsp;&nbsp;</span></span></li>
    <li><span>unsigned&nbsp;</span><span class="datatypes">long</span><span>&nbsp;</span><span class="datatypes">long</span><span>&nbsp;memparse(</span><span class="datatypes">char</span><span>&nbsp;*ptr,&nbsp;</span><span class="datatypes">char</span><span>&nbsp;**retptr); &nbsp;&nbsp;</span></li>
    <li class="alt"><span class="datatypes">char</span><span>&nbsp;*match_strdup(substring_t&nbsp;*s); &nbsp;&nbsp;</span></li>
</ol>
</div>
<p>&nbsp;在大多数二元和三元操作符两侧使用一个空格，例如下面所有这些操作符：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>=&nbsp;+&nbsp;-&nbsp;&lt;&nbsp;&gt;&nbsp;*&nbsp;/&nbsp;%&nbsp;|&nbsp;&amp;&nbsp;^&nbsp;&lt;=&nbsp;&gt;=&nbsp;==&nbsp;!=&nbsp;?&nbsp;:&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>&nbsp;但是一元操作符后不要加空格：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span>&amp;&nbsp;*&nbsp;+&nbsp;-&nbsp;~&nbsp;!&nbsp;</span><span class="keyword">sizeof</span><span>&nbsp;typeof&nbsp;alignof&nbsp;__attribute__&nbsp;defined&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>&nbsp;后缀自加和自减一元操作符前不加空格：</p>
<p>++ --</p>
<p>&nbsp;前缀自加和自减一元操作符后不加空格：</p>
<p>++ --</p>
<p>&nbsp;&ldquo;.&rdquo;和&ldquo;-&gt;&rdquo;结构体成员操作符前后不加空格。</p>
<p>&nbsp;不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白，然后你</p>
<p>就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码，有些编辑器就不</p>
<p>会移除已经加入的空白，就像你故意留下一个只有空白的行。包含行尾空白的行就这样产</p>
<p>生了。</p>
<p>当git发现补丁包含了行尾空白的时候会警告你，并且可以应你的要求去掉行尾空白；不过</p>
<p>如果你是正在打一系列补丁，这样做会导致后面的补丁失败，因为你改变了补丁的上下文。</p>
<p>&nbsp;</p>
<p><strong>第四章：命名</strong></p>
<p>&nbsp;C是一个简朴的语言，你的命名也应该这样。和Modula-2和Pascal程序员不同，C程序员不使</p>
<p>用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C程序员会称那个变量为&ldquo;tmp&rdquo;</p>
<p>，这样写起来会更容易，而且至少不会令其难于理解。</p>
<p>&nbsp;不过，虽然混用大小写的名字是不提倡使用的，但是全局变量还是需要一个具描述性的名字</p>
<p>。称一个全局函数为&ldquo;foo&rdquo;是一个难以饶恕的错误。</p>
<p>&nbsp;全局变量（只有当你真正需要它们的时候再用它）需要有一个具描述性的名字，就像全局函</p>
<p>数。如果你有一个可以计算活动用户数量的函数，你应该叫它&ldquo;count_active_users()&rdquo;或者</p>
<p>类似的名字，你不应该叫它&ldquo;cntuser()&rdquo;。</p>
<p>&nbsp;在函数名中包含函数类型（所谓的匈牙利命名法）是脑子出了问题&mdash;&mdash;编译器知道那些类型而</p>
<p>且能够检查那些类型，这样做只能把程序员弄糊涂了。难怪微软总是制造出有问题的程序。</p>
<p>&nbsp;本地变量名应该简短，而且能够表达相关的含义。如果你有一些随机的整数型的循环计数器</p>
<p>，它应该被称为&ldquo;i&rdquo;。叫它&ldquo;loop_counter&rdquo;并无益处，如果它没有被误解的可能的话。类似</p>
<p>的，&ldquo;tmp&rdquo;可以用来称呼任意类型的临时变量。</p>
<p>&nbsp;如果你怕混淆了你的本地变量名，你就遇到另一个问题了，叫做函数增长荷尔蒙失衡综合症</p>
<p>。请看第六章（函数）。</p>
<p><strong>第六章：函数</strong></p>
<p>&nbsp;函数应该简短而漂亮，并且只完成一件事情。函数应该可以一屏或者两屏显示完（我们都知</p>
<p>道ISO/ANSI屏幕大小是80x24），只做一件事情，而且把它做好。</p>
<p>&nbsp;一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以，如果你有一个理论上</p>
<p>很简单的只有一个很长（但是简单）的case语句的函数，而且你需要在每个case里做很多很</p>
<p>小的事情，这样的函数尽管很长，但也是可以的。</p>
<p>&nbsp;不过，如果你有一个复杂的函数，而且你怀疑一个天分不是很高的高中一年级学生可能甚至</p>
<p>搞不清楚这个函数的目的，你应该严格的遵守前面提到的长度限制。使用辅助函数，并为之</p>
<p>取个具描述性的名字。</p>
<p>&nbsp;函数的另外一个衡量标准是本地变量的数量。此数量不应超过5－10个，否则你的函数就有</p>
<p>问题了。重新考虑一下你的函数，把它分拆成更小的函数。人的大脑一般可以轻松的同时跟</p>
<p>踪7个不同的事物，如果再增多的话，就会糊涂了。即便你聪颖过人，你也可能会记不清你2</p>
<p>个星期前做过的事情。</p>
<p>&nbsp;在源文件里，使用空行隔开不同的函数。</p>
<p><strong>第八章：注释</strong></p>
<p>&nbsp;注释是好的，不过有过度注释的危险。永远不要在注释里解释你的代码是如何运作的：更好</p>
<p>的做法是让别人一看你的代码就可以明白，解释写的很差的代码是浪费时间。</p>
<p>&nbsp;一般的，你想要你的注释告诉别人你的代码做了什么，而不是怎么做的。也请你不要把注释</p>
<p>放在一个函数体内部：如果函数复杂到你需要独立的注释其中的一部分，你很可能需要回到</p>
<p>第六章看一看。你可以做一些小注释来注明或警告某些很聪明（或者槽糕）的做法，但不要</p>
<p>加太多。你应该做的，是把注释放在函数的头部，告诉人们它做了什么，也可以加上它做这</p>
<p>些事情的原因。</p>
<p>&nbsp;当注释内核API函数时，请使用kernel-doc格式。请看</p>
<p>Documentation/kernel-doc-nano-HOWTO.txt 和 scripts/kernel-doc 以获得详细信息。</p>
<p>&nbsp;Linux的注释风格是C89&ldquo;/* ... */&rdquo;风格。不要使用C99风格&ldquo;// ...&rdquo;注释。</p>
<p>&nbsp;长（多行）的首选注释风格是：</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="comment">/* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;This&nbsp;is&nbsp;the&nbsp;preferred&nbsp;style&nbsp;for&nbsp;multi-line </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;*&nbsp;comments&nbsp;in&nbsp;the&nbsp;Linux&nbsp;kernel&nbsp;source&nbsp;code. </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;Please&nbsp;use&nbsp;it&nbsp;consistently. </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;* </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*&nbsp;Description:&nbsp;A&nbsp;column&nbsp;of&nbsp;asterisks&nbsp;on&nbsp;the&nbsp;left&nbsp;side, </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;*&nbsp;with&nbsp;beginning&nbsp;and&nbsp;ending&nbsp;almost-blank&nbsp;lines. </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>&nbsp;注释数据也是很重要的，不管是基本类型还是衍生类型。为了方便实现这一点，每一行应只</p>
<p>声明一个数据（不要使用逗号来一次声明多个数据）。这样你就有空间来为每个数据写一段</p>
<p>小注释来解释它们的用途了。</p>
<p>对于PHPER来讲，最好遵循PHPDOC风格的注释。</p>
<p>&nbsp;<strong>第九章：你已经把事情弄糟了</strong></p>
<p>&nbsp;这没什么，我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你&ldquo;GNU emacs&rdquo;能</p>
<p>自动帮你格式化C源代码，而且你也注意到了，确实是这样，不过它所使用的默认值和我们</p>
<p>想要的相去甚远（实际上，甚至比随机打的还要差&mdash;&mdash;无数个猴子在GNU emacs里打字永远不</p>
<p>会创造出一个好程序）（译注：请参考Infinite Monkey Theorem）(对于PHPer，可能就是zend studio、eclipse之类的自动格式化工具)</p>
<p>&nbsp;所以你要么放弃GNU emacs，要么改变它让它使用更合理的设定。</p>
<p>&nbsp;<strong>第十二章：宏，枚举和RTL</strong></p>
<p>&nbsp;用于定义常量的宏的名字及枚举里的标签需要大写。</p>
<div class="codeText">
<div class="codeHead">C++代码</div>
<ol class="dp-cpp">
    <li class="alt"><span><span class="preprocessor">#define&nbsp;CONSTANT&nbsp;0x12345</span><span>&nbsp;&nbsp;</span></span></li>
</ol>
</div>
<p>&nbsp;宏的名字请用大写字母，不过形如函数的宏的名字可以用小写字母。</p>
<p>。。。</p>
<p>&nbsp;</p>
<p><strong>第十三章：打印内核消息</strong></p>
<p>&nbsp;内核开发者应该是受过良好教育的。请一定注意内核信息的拼写，以给人以好的印象。不要</p>
<p>用不规范的单词比如&ldquo;dont&rdquo;，而要用&ldquo;do not&rdquo;或者&ldquo;don't&rdquo;。保证这些信息简单、明了、无</p>
<p>歧义。</p>
<p>&nbsp;内核信息不必以句号（译注：英文句号，即点）结束。</p>
<p>&nbsp;写出好的调试信息可以是一个很大的挑战；<strong>当你写出来之后，这些信息在远程除错的时候</strong>当DEBUG符号没有被定义的时候，这些信息不应该被编译进内核里</p>
<p>就会成为极大的帮助。</p>
<p>（也就是说，默认地，它们不应该被包含在内）。(对于PHPer也是同样)</p>
<p>&nbsp;</p>
<p><strong>第十八章：编辑器模式行和其他需要罗嗦的事情</strong></p>
<p>&nbsp;有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如，emacs</p>
<p>能够解释被标记成这样的行：</p>
<p>&nbsp;-*- mode: c -*-</p>
<p>或者这样的：</p>
<p>&nbsp;/*</p>
<p>Local Variables:</p>
<p>compile-command: &quot;gcc -DMAGIC_DEBUG_FLAG foo.c&quot;</p>
<p>End:</p>
<p>*/</p>
<p>&nbsp;Vim能够解释这样的标记：</p>
<p>&nbsp;/* vim:set sw=8 noet */</p>
<p>&nbsp;这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模</p>
<p>式，或者使用其他可以产生正确的缩进的巧妙方法。</p>
<p>&nbsp;</p>
<p>不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置，你的源文件不应</p>
<p>该覆盖别人的配置。</p>
<p>&nbsp;</p>
<p>简而言之，8个字符的缩进可以让代码更容易阅读，还有一个好处是当你的函数嵌套太深的</p>
<p>时候可以给你警告。留心这个警告。</p>]]></description>
			<link>http://dev.meettea.com/show-62-1.html</link>
			<category domain="http://dev.meettea.com/category-4-1.html">微风笔记</category>
			<pubDate>2010-01-03 20:40</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-61-1.html</guid>
			<title>help</title>
			<author>shiny</author>
			<description><![CDATA[<a href="http://help-yifan.org/">help-yifan.org</a>]]></description>
			<link>http://dev.meettea.com/show-61-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2010-01-02 13:44</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-60-1.html</guid>
			<title>pinyShop v0.3.0元旦内测版</title>
			<author>shiny</author>
			<description><![CDATA[<p>pinyShop v0.3.0元旦内测版释出</p>
<p>主要更新功能</p>
<ul>
    <li>新增的win窗口，只有200k不到</li>
    <li>仍旧保持纯绿色、bat双击使用、可自由更改、绝大多数功能由bat实现</li>
    <li>仍旧保持新建文件夹既是新建虚拟主机</li>
    <li>DIY更简单，自动识别mysql、php、nginx(一个目录内不能放两个php开头的文件夹)</li>
    <li>增加调试模式/演示模式两种概念，分别使用不同的php.ini和nginx.conf，还是用bat实现</li>
    <li>调试模式下增加目录浏览功能</li>
    <li>除nginx，默认绑定127.0.0.1，更安全</li>
    <li>PHP更新到5.3.1,nginx更新到0.8.31</li>
    <li>解决每次都需要更新xdebug的路径的问题</li>
    <li>抛弃process.exe，杀毒软件不再报可疑的程序</li>
    <li>更多等待你的发现</li>
</ul>
<p>下载地址:<a href="http://nginx.tcisv.cn/pinyShop0.3.exe">电信下载点</a> <a href="http://pinyshop.nginxhome.com/pinyShopv0.3alpha.exe">美国下载点</a></p>
<p>感谢一直为我们提供建议的网友们，是你们让这个软件更完善。我们仍旧需要在不同环境下的测试。目前仅测试windows7。</p>
<p>反馈渠道依然畅通:QQ:1004020666 gtalk:ice.shiny@gmail.com Mail:pinyshop@meettea.com</p>
<p>[attach=26]</p>
<p>[attach=27]</p>
<p>感谢橙C 的意见和建议，感谢PHPCHINA的朋友们的支持，现在感觉vb基本是没法来写小巧的绿色软件；而PHPCHINA上的情况看，nginx+php+mysql+memcache的套装也开始涌现。pinyShop0.3将会是最后一版(将OPEN SOURCE)，这类工作，总有人乐意去做的。</p>]]></description>
			<link>http://dev.meettea.com/show-60-1.html</link>
			<category domain="http://dev.meettea.com/category-6-1.html">发布与下载</category>
			<pubDate>2010-01-01 23:35</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-59-1.html</guid>
			<title>godaddy已经支持支付宝</title>
			<author>shiny</author>
			<description><![CDATA[<p>godaddy已经支持支付宝。</p>
<p>根据建行实时汇率对人民币转换为美元。</p>
<p>今晨汇率6.8，比绝大多数代购都要便宜。</p>
<p>今天买个了.us域名</p>
]]></description>
			<link>http://dev.meettea.com/show-59-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2010-01-01 12:04</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-58-1.html</guid>
			<title>PHP 5.2.12 发布</title>
			<author>shiny</author>
			<description><![CDATA[<p>PHP 5.2.12 发布</p>
<p>PHP开发小组宣布PHP5.2.12已经可以获取。这次发布主要在于提升php5.2.x系列的稳定性，修复了超过60个BUG,一些与安全相关。建议所有php5.2的用户升级到这个版本。</p>
<p>PHP5.2.12中安全的改善与修复:</p>
<p>tempnam()绕过safe_mode (CVE-2009-3557, Rasmus)</p>
<p>open_basedir被posix_mkfifo()绕过</p>
<p>增加max_file_uploads的INI设置，默认限制为每个请求只能上传20个文件，用于阻止临时文件夹溢出的DOS攻击。(注:php5.3.1中同样增加了这个功能)</p>
<p>增加了对SESSION的保护、改进了对session.save_path的检查</p>
<p>修复BUG#49785 (htmlspecialchars()对传入的字符验证不充分)</p>
<p>更多修复详情见发布公告</p>
<p></p>
<p>PHP5.2.12是最新的、适合部署到生产环境的、能兼容主流PHP应用的PHP版本，建议大家在生产环境中应用该版本(开发环境建议使用PHP5.3.1)。</p>]]></description>
			<link>http://dev.meettea.com/show-58-1.html</link>
			<category domain="http://dev.meettea.com/category-5-1.html">PHP</category>
			<pubDate>2009-12-25 22:07</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-57-1.html</guid>
			<title>D2论坛归来</title>
			<author>shiny</author>
			<description><![CDATA[<p>首先是上图,有图有真相</p>
<p>[attach=20]</p>
<p>[attach=21]</p>
<p>[attach=22]</p>
<p>[attach=23]</p>
<p>[attach=24]</p>
<p>关于D2，不想多说，总结几点</p>
<ul>
    <li>关注过金大为的LITE模板引擎，的确有所启发；这次提及的为前端建模的确很新颖，不过性能和安全成了比较受人关注的问题(安全问题的关注起源于金先生说数据模型在前台后台是一致的)</li>
    <li>YUI的性能问题，克军似乎没能说服在场的观众，看来YUI的性能问题依旧是众矢之的；虽然作为JQUERY教众表示影响不大，但是YUI3组件化的思想还是很有借鉴价值的。</li>
    <li>午餐，味道一般般</li>
    <li>slqq，连当事人都觉得很冷。。。的确，现场多是关注JS、关注AS的。做SL的还太少，面对观众的质疑，当事人说：选择SL很简单，总之一句话：老大说：要用SL。。。不过腾讯产品的影响力确实大，大家对腾讯的产品很感兴趣。</li>
    <li>作为一个三年前的《黑防》忠实读者，XSS只能说是炒冷饭，毫无新意，虽然我已经三年没看《黑防》了。</li>
    <li>前端性能优化与自动化，这个以前确实没有想过，的确，也一直为开发环境消耗了不少时间。pinyShop完全是为了提高效率而搞的一个东西，简单却有效。此外CDN下网站的部署，被科普了。</li>
    <li>最后的抽奖，有个人名字叫&ldquo;田异常&rdquo;，全场哗然，哈哈。</li>
</ul>
<p>D2带给我最大的启发是重新思考前端重构的方式；之前只针对后端进行不断重构。</p>
<p>D2，其实主要还是develop,design基本没涉及。整个会议就像对developer进行科普。</p>
<p>最后还见到了网上常常和人掐架的hax。</p>
<p>最后，其实我一直想在台上说<strong>感谢CCTV</strong>感谢MTV，可惜没抽到奖，没机会。</p>]]></description>
			<link>http://dev.meettea.com/show-57-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2009-12-19 23:17</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-56-1.html</guid>
			<title>SMARTY的意义</title>
			<author>shiny</author>
			<description><![CDATA[<p>个人认为smarty被移出php.net的项目，最大原因是smarty不再被上升到模板引擎的高度。</p>
<p>作为一个模板引擎，smarty并不是最佳选择。国内discuz的高效、原生的blitz引擎都会是比smarty更好的选择。</p>
<p>所以smarty受到大家的冷落。</p>
<p>&nbsp;</p>
<p>从前端开发者的角度或者整个程序的架构上讲，smarty的作用却是目前一些简单的模板引擎所不具备的。</p>
<p>SMARTY对于我而言最大的作用是把前端和后端比较彻底地分离了。</p>
<p>对于模板的重用、模板和程序的分离达到了较好的效果。</p>
<p>下面这个例子是<strong>模板与程序</strong>的深度分离</p>
<p>举例:{$topic.groupName|truncate:14:&quot;...&quot;} 语法简洁，不用再去了解mb_substr和substr的区别。字符串要多长，难道不是前端的事情吗?&nbsp;（就这点，马宝学长如果知道有这种方式，肯定会很高兴的 :) <font size="2">注:马宝是一设计师，连CSS都不全会）</font></p>
<p><strong>实际上就是对截取字符串这个函数进行了封装，达到高度的可重用性。smarty在这里起到的作用就是给前端引用后端资源进行了封装和组织。</strong></p>
<p>下面这个例子是<strong>模板和模板</strong>的分离&nbsp;</p>
<p>此外，在group模块，模板里需要使用用户模块里的东西，如果用户未登录就显示用户未登录，用户已经登录则显示欢迎词。如何才能达到两个模块最大程度的分离呢?</p>
<p>除了模板和模板的分离还需要程序的介入，但是程序之间也需要分离。</p>
<p>我是这样处理的:{include file=&quot;view:users/users/userInfo&quot;} view资源是自己定义的，对以一种简单优雅的方式引入模板，进行了组织和进一步处理。</p>
<p>区块、修改器、模板资源等组织形式，对于一个比较复杂的网站完全够用。</p>
<p>在越来越多的人关注div+css重用的今天，实用性比较大。如果blitz能完全实现smarty模板引擎的语法，我很乐意去使用。</p>]]></description>
			<link>http://dev.meettea.com/show-56-1.html</link>
			<category domain="http://dev.meettea.com/category-4-1.html">微风笔记</category>
			<pubDate>2009-12-16 11:22</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-54-1.html</guid>
			<title>PHP5.3.1发布，修复大量BUG</title>
			<author>shiny</author>
			<description><![CDATA[<p>PHP5.3.1发布，修复大量BUG，包括前段时间pinyShop用户反馈的mysql_close() <br />
php即崩溃的BUG。<br />
Windows版本的下载http://windows.php.net/download/<br />
pinyShop v0.3将主推php5.3.1的版本，如果有用户需要，考虑临时推出pinyShop v0.2 for php5.3.1的版本。<br />
<br />
<strong>php5.3.1官方介绍</strong><br />
<br />
PHP 5.3.1中安全的增强与修复: <br />
<br />
■增加 &quot;max_file_uploads&quot; INI 指令,能够用于限制每次上传的文件数，默认限制为20个，用于阻止可能的通过临时文件耗尽的DOS攻击。<br />
■增加没有实现的exif处理中的合理检查<br />
■修复 tempnam() 中绕过safe_mode<br />
■修复posix_mkfifo() 中绕过 open_basedir bypass<br />
■修复编号为#50063的BUG (safe_mode_include_dir 失效).<br />
■修复编号为#44683的BUG (无效的MODE值传入popen后奔溃).<br />
<br />
关键BUG修复，含:<br />
<br />
■修复无效的typelib传入com_print_typeinfo后崩溃<br />
■用Reflection调用SQLiteDatabase::ArrayQuery() 和 SQLiteDatabase::SingleQuery()崩溃.<br />
■通过Reflection使用PDORow and PDOStatement崩溃<br />
■修复BUG编号为#49910 (不支持 ././@LongLink 长文件名).<br />
■修复BUG编号为#49908 ( interface未定义时通过__autoload加载则抛出异常)<br />
■其他近100个BUG的修复</p>
<p>2009/12/14 update:注意,mysql_connect如果连接localhost，如果开启了php对ipv6的支持则将连接超时。</p>
<p>解决方法一:HOSTS文件里把#::1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; localhost 的#去掉</p>
<p>解决方法二:使用127.0.0.1代替localhost</p>]]></description>
			<link>http://dev.meettea.com/show-54-1.html</link>
			<category domain="http://dev.meettea.com/category-5-1.html">PHP</category>
			<pubDate>2009-11-25 13:15</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-53-1.html</guid>
			<title>Google OAuth 简单入门与使用</title>
			<author>shiny</author>
			<description><![CDATA[<p><font color="#333333" size="2">MeetTea需要能够通过Google API来获取用户的用户名和头像，效果就像google.org.cn的排队系统。</font></p>
<p><font color="#333333" size="2">那么如何实现呢? 通过几天的学习、研究，下载google的源码，最后了解了原理并制作了一个简单的DEMO。</font></p>
<p><font color="#333333" size="2">效果见附件，只有一个简单的test.php，需要自己去申请CONSUMER_KEY和CONSUMER_SECRET，不过申请步骤简单。</font></p>
<p><font color="#333333" size="2">申请地址:here</font><a href="https://www.google.com/accounts/ManageDomains"><font color="#333333" size="2">https://www.google.com/accounts/ManageDomains</font></a><font color="#333333" size="2">&nbsp; </font></p>
<p><font color="#333333" size="2">目前仅使用HMAC-SHA1算法。此外可以参考这个</font><a href="http://googlecodesamples.com/oauth_playground/"><font color="#333333" size="2">http://googlecodesamples.com/oauth_playground/</font></a><font color="#333333" size="2">&nbsp;有源码，是PHP的。 </font></p>
<p><font color="#333333" size="2">详细的技术文档在这里 </font><a href="http://code.google.com/apis/accounts/docs/OAuth_ref.html"><font color="#333333" size="2">http://code.google.com/apis/accounts/docs/OAuth_ref.html</font></a></p>
<p><font size="2"><font color="#333333">OAuth验证第一步:<strong>Get a Request Token</strong></font></font></p>
<p><font color="#333333" size="2">这个Request Token是请求一个令牌，来允许程序接入google的服务。</font></p>
<p><font color="#333333" size="2">具体做法是发送一个HTTP GET请求到https://www.google.com/accounts/OAuthGetRequestToken</font></p>
<p><font size="2"><font color="#333333">并且在HTTP头里有一个Authorization<font face="Helvetica">字段，字段里的内容是OAuth开头，加一个空格，然后是每个参数join一个&ldquo;,&rdquo;和空格。</font></font></font></p>
<p><font color="#333333" size="2" face="Helvetica">此外google的OAuth还有一个SCOPE参数，这个不是标准OAuth里的。</font></p>
<p><font color="#333333" size="2">最后注意端口是443，不然会收到一个302;如果程序有问题会收到一个400。</font></p>
<p><font color="#333333" size="2">如果是200，则在返回的HTTP BODY里取得$oauth_token,$oauth_token_secret </font></p>
<p><font color="#333333" size="2">保存好这两个值，下两步要用到。</font></p>
<p>&nbsp;</p>
<p><font color="#333333" size="2">第二步是用户操作部分，需要用户授权应用访问GOOGLE相关服务。也就是redirect到 www.google.com/accounts/OAuthAuthorizeToken?oauth_token=刚才的KEY </font></p>
<p><font color="#333333" size="2">&nbsp;获取用户的头像、用户名的scope是http://www-opensocial.googleusercontent.com/api/people/@me</font></p>
<p><font color="#333333" size="2">用户允许Access后就会跳转回刚才的页面，并且在URL参数里多了一个参数。</font></p>
<p>&nbsp;</p>
<p><font color="#333333" size="2">第三步是凭刚才URL里验证的参数发送一个GET请求到https://www.google.com/accounts/OAuthGetAccessToken</font></p>
<p><font size="2"><font color="#333333">获取接入GOOGLE服务的权限，HEADER里仍旧要包含Authorization<font face="Helvetica">字段。</font></font></font></p>
<p><font face="Helvetica"><font size="2"><font color="#333333">得到KEY和SECRET后替换刚才一开始的KEY和SECRET，发送GET请求到<font face="Tahoma">&nbsp;获取用户的头像、用户名的scope，就可以保存下来，用户也无需注册了。</font></font></font></font></p>
<p>&nbsp;</p>
<p><font color="#333333" size="2">当然，GOOGLE庞大的API还可以帮助你得到用户朋友的EMAIL地址之类的，就看网站的需要了，潜力无限。</font></p>
<p><font color="#333333" size="2">豆瓣用的也是OAuth。</font></p>
<p><font color="#333333" size="2">==============2009/11/25 update=====================</font></p>
<p><font color="#333333" size="2">豆瓣的算法和google的略有不同，主要是在http header里的数据不用rawurlencode</font></p>
<p><font color="#333333" size="2">请搜索test.php里 </font></p>
<div class="codeText">
<div class="codeHead">PHP代码</div>
<ol class="dp-c">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">function</span><span>&nbsp;to_header(</span><span class="vars">$realm</span><span>=</span><span class="string">''</span><span>)&nbsp;{</span><span class="comment">/*{{{*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li><span>&nbsp;&nbsp;</span><span class="vars">$out</span><span>&nbsp;=</span><span class="string">'Authorization:&nbsp;OAuth&nbsp;realm=&quot;'</span><span>&nbsp;.&nbsp;</span><span class="vars">$realm</span><span>&nbsp;.&nbsp;</span><span class="string">'&quot;'</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="vars">$total</span><span>&nbsp;=&nbsp;</span><span class="keyword">array</span><span>(); &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span><span class="comment">/* </span>&nbsp;</li>
    <li><span><span class="comment">&nbsp;&nbsp;$sig&nbsp;=&nbsp;$this-&gt;parameters['oauth_signature'];&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;unset($this-&gt;parameters['oauth_signature']);&nbsp; </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;uksort($this-&gt;parameters,&nbsp;'strnatcmp');&nbsp;&nbsp; </span>&nbsp;</span></li>
    <li class="alt"><span><span class="comment">&nbsp;&nbsp;$this-&gt;parameters['oauth_signature']&nbsp;=&nbsp;$sig; </span>&nbsp;</span></li>
    <li><span><span class="comment">&nbsp;&nbsp;*/</span><span>&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span><span class="keyword">foreach</span><span>&nbsp;(</span><span class="vars">$this</span><span>-&gt;parameters&nbsp;</span><span class="keyword">as</span><span>&nbsp;</span><span class="vars">$k</span><span>&nbsp;=&gt;&nbsp;</span><span class="vars">$v</span><span>)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(</span><span class="func">substr</span><span>(</span><span class="vars">$k</span><span>,&nbsp;0,&nbsp;5)&nbsp;!=&nbsp;</span><span class="string">&quot;oauth&quot;</span><span>)&nbsp;</span><span class="keyword">continue</span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="comment">//$out&nbsp;.=&nbsp;OAuthUtil::urlencodeRFC3986($k)&nbsp;.&nbsp;'=&quot;'&nbsp;.&nbsp;OAuthUtil::urlencodeRFC3986($v)&nbsp;.&nbsp;'&quot;,&nbsp;'; </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;</span><span class="vars">$out</span><span>&nbsp;.=&nbsp;</span><span class="string">','</span><span>&nbsp;.&nbsp;</span><span class="vars">$k</span><span>&nbsp;.&nbsp;</span><span class="string">'=&quot;'</span><span>&nbsp;.&nbsp;</span><span class="vars">$v</span><span>&nbsp;.&nbsp;</span><span class="string">'&quot;'</span><span>; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$str</span><span>&nbsp;=&nbsp;</span><span class="vars">$k</span><span>&nbsp;.&nbsp;</span><span class="string">'='</span><span>&nbsp;.&nbsp;</span><span class="vars">$v</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">if</span><span>&nbsp;(</span><span class="vars">$this</span><span>-&gt;string&nbsp;==&nbsp;null)&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$this</span><span>-&gt;string&nbsp;=&nbsp;</span><span class="vars">$str</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span class="keyword">else</span><span>&nbsp;{ &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="vars">$this</span><span>-&gt;string&nbsp;.=&nbsp;</span><span class="string">'&amp;'</span><span>&nbsp;.&nbsp;</span><span class="vars">$str</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p><font color="#333333" size="2">此外把params数组里的scope清理掉，豆瓣不需要。详细可以参考</font><a href="http://www.douban.com/service/apidoc/auth"><font color="#333333" size="2">http://www.douban.com/service/apidoc/auth</font></a></p>
<p><font color="#333333" size="2">其他基本是大同小异。豆瓣有PHP版的OAuth示例，可惜是做成ZEND FRAMEWORK的。我需要的是单个文件以便拆解到我的框架中。</font></p>
<p><font color="#333333" size="2">接下来研究windows live的API和renren.com的API。</font></p>]]></description>
			<link>http://dev.meettea.com/show-53-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2009-11-24 18:29</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-52-1.html</guid>
			<title>免费SSL证书 STARTSSL 介绍与申请攻略</title>
			<author>shiny</author>
			<description><![CDATA[<p>startssl在9月微软补丁更新中被支持，使得startssl证书得到承认。</p>
<p>申请流程如下 startssl.com</p>
<p>我的环境是windows 7</p>
<p>请不要使用chrome和IE8，否则将无法生成KEY而无法申请成功。建议使用firefox。</p>
<p>此外我还遇上了点意外，我使用的移动的网络被误判为澳大利亚的IP并收到邮件要求解释。</p>
<p>我将APNIC的查询地址和查询结果发送给对方后帐户才申请成功。</p>
<p>control panel / sign-up 注意填写正确资料。收到邮件后复制验证码。然后可以生成一个证书，注意，startssl.com不是以用户名、密码来验证用户的，是用证书来验证用户的。</p>
<p>所以生成证书后(火狐会导入证书)，注意备份证书。丢失证书后只能重新注册。</p>
<p>登录后还要验证域名才能为该域名生成SSL证书，可以选择在whois里的邮箱、hostmaster@domain、postmaster@domain或者webmaster@domain</p>
<p>然后就可以在Certificates wizard里就可以申请SSL证书了。</p>
<p>有效期一年。</p>
<p>======2009/11/26 update===========</p>
<p>Toolbox</p>
<p>把你申请时的private key拿去Decrypt private key，然后把生成的key保存起来。</p>
<p>然后在Retieve certificate里选择你申请的域名，就可以得到cer文件，保存起来，放到nginx的conf目录。</p>
<p>在nginx里这样配置</p>
<div class="codeText">
<div class="codeHead">PHP代码</div>
<ol class="dp-c">
    <li class="alt"><span><span>server &nbsp;&nbsp;</span></span></li>
    <li><span>{ &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;server_name&nbsp;security.meettea.com; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;listen&nbsp;&nbsp;443; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;index&nbsp;index.html&nbsp;index.htm&nbsp;index.php; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;root&nbsp;&nbsp;/data0/htdocs/security.meettea.com; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;ssl&nbsp;on; &nbsp;&nbsp;</span></li>
    <li><span>&nbsp;&nbsp;&nbsp;ssl_certificate&nbsp;security.cer; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;ssl_certificate_key&nbsp;security.key; &nbsp;&nbsp;</span></li>
    <li><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p>nginx -s reload下如果没有任何提示，就说明配置成功了。</p>
<p>效果<a href="https://security.meettea.com/">https://security.meettea.com/</a></p>
<p>可惜firefox3.5测试，不信任class 1的证书。</p>
<p>&nbsp;==============2009/11/26 update===================</p>
<p>在startssl forum看到官方人员说firefox3.5不支持是因为没有配置好。经过配置解决了firefox 3.5不信任该证书的问题，ubuntu studio下测试通过。</p>
<p>步骤是:获取https://www.startssl.com/certs/ca.pem</p>
<p>获取https://www.startssl.com/certs/sub.class1.server.ca.pem</p>
<p>cat ca.pem sub.class1.server.ca.pem &gt;&gt; ca-certs.crt</p>
<p>cat ca-certs.crt &gt;&gt; security.cer</p>
<p>这是因为需要把startssl的根证书和sub class1的证书附上，因为是他们把证书颁发给你，firefox需要这张证书才认识你的证书。 :)</p>
<p>此外opera测试没通过，这点，连startssl.com自己都没有被opera通过。</p>]]></description>
			<link>http://dev.meettea.com/show-52-1.html</link>
			<category domain="http://dev.meettea.com/category-4-1.html">微风笔记</category>
			<pubDate>2009-11-21 17:27</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-51-1.html</guid>
			<title>考古新发现</title>
			<author>shiny</author>
			<description><![CDATA[<p>考古新发现:从床底挖出07年底512M SD卡一张，距今两年；</p>
<p>上次考古发现是04年底64MB U盘一个，距今5年。</p>
<p>该考古发现的重要意义是验证了本人几年前的技术水平。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>其实，人最难认识自己。</p>
<p>过去的水平和过去的自信心显然不成正比。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>那么现在的呢?</p>
<p>&nbsp;</p>
<p>扯淡完毕。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>PS:我觉得每年都应该把自己觉得最好的作品封存起来，供来年批判用。</p>]]></description>
			<link>http://dev.meettea.com/show-51-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2009-11-14 13:39</pubDate>
		</item>
		<item>
			<guid>http://dev.meettea.com/show-50-1.html</guid>
			<title>newStyle on the way</title>
			<author>shiny</author>
			<description><![CDATA[<p>是骡子是马拿出来遛遛就知道了</p>
<p>[attach=17]</p>
<p>[attach=18]</p>]]></description>
			<link>http://dev.meettea.com/show-50-1.html</link>
			<category domain="http://dev.meettea.com/category-1-1.html">微风日志</category>
			<pubDate>2009-11-12 17:45</pubDate>
		</item>
	</channel>
</rss>
