<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Apex[有所思,有所志]</title>
	<atom:link href="http://apex.ncksoft.com/feed" rel="self" type="application/rss+xml" />
	<link>http://apex.ncksoft.com</link>
	<description>日有所思，夜有所志</description>
	<lastBuildDate>Sat, 06 Feb 2010 18:12:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>当遇到C4995警告时该怎么办？</title>
		<link>http://apex.ncksoft.com/archives/293</link>
		<comments>http://apex.ncksoft.com/archives/293#comments</comments>
		<pubDate>Sat, 06 Feb 2010 18:12:04 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[代码人生]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[VC]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=293</guid>
		<description><![CDATA[使用Visual Studio 2008写代码时，编译时遇到警告：
1&#62;d:\program\msvs2008\vc\include\cstdio(49) : warning C4995: 'gets': name was marked as #pragma deprecated
1&#62;d:\program\msvs2008\vc\include\cstdio(53) : warning C4995: 'sprintf': name was marked as #pragma deprecated
1&#62;d:\program\msvs2008\vc\include\cstdio(56) : warning C4995: 'vsprintf': name was marked as #pragma deprecated
1&#62;d:\program\msvs2008\vc\include\cstring(22) : warning C4995: 'strcat': name was marked as #pragma deprecated
1&#62;d:\program\msvs2008\vc\include\cstring(23) : warning C4995: 'strcpy': name was marked as #pragma deprecated
1&#62;d:\program\msvs2008\vc\include\cwchar(36) : warning [...]]]></description>
			<content:encoded><![CDATA[<p>使用Visual Studio 2008写代码时，编译时遇到警告：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline">1&gt;d:\program\msvs2008\vc\include\cstdio(49) : warning C4995: 'gets': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cstdio(53) : warning C4995: 'sprintf': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cstdio(56) : warning C4995: 'vsprintf': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cstring(22) : warning C4995: 'strcat': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cstring(23) : warning C4995: 'strcpy': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cwchar(36) : warning C4995: 'swprintf': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cwchar(37) : warning C4995: 'vswprintf': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cwchar(39) : warning C4995: 'wcscat': name was marked as #pragma deprecated</li>
<li>1&gt;d:\program\msvs2008\vc\include\cwchar(41) : warning C4995: 'wcscpy': name was marked as #pragma deprecated</li></ol></div>
<p>意思是说，某个函数已经被标记为过时了，最好不要用，在将来的版本中，该函数可能就没有了，不存在了。</p>
<p>奇怪的是，代码里面并没有使用这些函数啊。但是先不考虑这个了，还是看看如何解决吧。对于编译器警告，当然可以用 #pragma warning(disable: xxxx ) 的语法将其禁止掉，这样编译时编译器就不会在那里唧唧歪歪了。在网上查找此类问题，基本上都是这样说的。</p>
<p>然后仔细想想，关闭这个警告并不正常，因为这样一来，所有过时的函数都不会再警告了，而我们可能是需要这个警告的，像是对于strcpy这种超常用的函数，考虑到安全性（应对缓冲区溢出攻击），我们的确应该使用其安全版本，例如strcpy就有对应的StringCchCopy/StringCbCopy这样的函数，如果关闭了此警告，我们就可能在代码中不小心写下strcpy，而不是其对应的安全版本（当然，strcpy等函数是特例，关闭C4995警告后，仍然会有其他警告，下面有说明）。</p>
<p>所以，考察上述几个函数，我们知道其函数声明所在的头文件，这些头文件中的函数应该都不会用到，所以可以用另一种方式来避免引入这些头文件：</p>
<p>在你的工程的预编译头文件（一般来说，就是stdafx.h）中，在 #pragma once 一行后面加上下列三行：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-prepro">#define</span><span class="hl-code"> </span><span class="hl-identifier">_CSTDIO_</span><span class="hl-prepro"></span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-prepro">#define</span><span class="hl-code"> </span><span class="hl-identifier">_CSTRING_</span><span class="hl-prepro"></span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-prepro">#define</span><span class="hl-code"> </span><span class="hl-identifier">_CWCHAR_</span></li></ol></div>
<p>这样，编译器就不会再加载 cstdio / cstring / cwchar 这几个头文件了。</p>
<p><strong>P.S.</strong><br />
使用 #pragma warning(disable: xxxx) 这种方式关闭警告后，如果代码里面用到了 strcpy 这样的函数，编译器会报另一个警告：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline">1&gt;e:\work\ncksoft\test\main.cpp(126) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.</li>
<li>1&gt;&nbsp; &nbsp; &nbsp; &nbsp; d:\program\msvs2008\vc\include\string.h(74) : see declaration of 'strcpy'</li></ol></div>
<p>所以我们仍然可以得到想要的警告信息。</p>
<p><strong>再 P.S.</strong><br />
如果在代码中使用 #pragma deprecated( name_of_deprecated ) ，就会在编译时报 C4995 警告，而使用下面的方法，则会报 C4996 警告：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-identifier">__declspec</span><span class="hl-brackets">(</span><span class="hl-identifier">deprecated</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-types">void</span><span class="hl-code"> </span><span class="hl-identifier">foo</span><span class="hl-brackets">(</span><span class="hl-types">int</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;&nbsp; </span><span class="hl-comment">// ...</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span></li></ol></div>
<p><strong>再 再 P.S.</strong><br />
我很讨厌那些将警告信息视作无物的程序员，一点美感都没有！</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/293/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP网站提速</title>
		<link>http://apex.ncksoft.com/archives/279</link>
		<comments>http://apex.ncksoft.com/archives/279#comments</comments>
		<pubDate>Fri, 11 Dec 2009 18:44:59 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[代码人生]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[网站优化]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=279</guid>
		<description><![CDATA[最近在研究网站提速、搜索引擎优化等技术，打算将一些技巧逐步分享，这里先说说提速。
对于基于PHP构建的网站，一个可行的方法是将网络上传输的内容减少。一是压缩，二是如果内容没有发生变化，则不发送内容到客户端，而是让客户端使用缓存的数据。虽然说现在网络速度已经比较快了，但是考虑到网页大部分都是文本内容，压缩率还是相当可观的，一般来说，构成网页的文本内容如HTML/CSS/JS等，使用gzip压缩可以达到60%以上的压缩率。这样，一个简单的网站页面每次访问也可减少60KB以上的网络传输量。而压缩操作速度是很快的，一个100KB的页面文本，压缩耗时在3毫秒以下，基本可以忽略。
我打算先从css/javascript文件入手。下面来看一段代码：

&#19979;&#36733;: index.php&#60;?php
&#160;
// Created by Apex
// http://apex.ncksoft.com/archives/279
&#160;
define('FILE_TYPE_UNKNOWN', 0);
define('FILE_TYPE_CSS', 1);
define('FILE_TYPE_JS', 2);
&#160;
// 这个PHP文件将会放到与css和js文件同一个目录下，方便文件定位
$this_path = dirname( realpath(__FILE__) ).DIRECTORY_SEPARATOR;
&#160;
// 根据URL请求来决定后续发生什么样的header到客户端
$type = FILE_TYPE_UNKNOWN;
$fname = '';
if(isset($_REQUEST['css']))
{
&#160; &#160; $type = FILE_TYPE_CSS;
&#160; &#160; $fname = $_REQUEST['css'];
}
else if(isset($_REQUEST['js']))
{
&#160; &#160; $type = FILE_TYPE_JS;
&#160; &#160; $fname = $_REQUEST['js'];
}
else
{
&#160; &#160; exit();
}
&#160;
// 对参数进行判断
if(empty($fname))
{
&#160; &#160; exit();
}
&#160;
// 指定的文件应该存在，否则什么都不输出
$fname = $this_path . $fname;
if(!is_file($fname))
{
&#160; &#160; exit();
}
&#160;
// 得到文件内容，并获取文件最后修改时间
$output = file_get_contents($fname);
$fmtime = filemtime($fname);
&#160;
// 如果该客户端不是第一次希望获取此文件，则会有如下变量
if(isset($_SERVER[&#34;HTTP_IF_MODIFIED_SINCE&#34;]))
{
&#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>最近在研究网站提速、搜索引擎优化等技术，打算将一些技巧逐步分享，这里先说说提速。</p>
<p>对于基于PHP构建的网站，一个可行的方法是将网络上传输的内容减少。一是压缩，二是如果内容没有发生变化，则不发送内容到客户端，而是让客户端使用缓存的数据。虽然说现在网络速度已经比较快了，但是考虑到网页大部分都是文本内容，压缩率还是相当可观的，一般来说，构成网页的文本内容如HTML/CSS/JS等，使用gzip压缩可以达到60%以上的压缩率。这样，一个简单的网站页面每次访问也可减少60KB以上的网络传输量。而压缩操作速度是很快的，一个100KB的页面文本，压缩耗时在3毫秒以下，基本可以忽略。</p>
<p>我打算先从css/javascript文件入手。下面来看一段代码：<br />
<span id="more-279"></span></p>
<div class="hl-title">&#19979;&#36733;: <a href="http://apex.ncksoft.com/wp-content/plugins/coolcode/coolcode.php?p=279&amp;download=index.php">index.php</a></div><div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-inlinetags">&lt;?php</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// Created by Apex</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-comment">// </span><span class="hl-url">http://apex.ncksoft.com/archives/279</span><span class="hl-comment"></span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-reserved">define</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">FILE_TYPE_UNKNOWN</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-number">0</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-reserved">define</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">FILE_TYPE_CSS</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-number">1</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-reserved">define</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">FILE_TYPE_JS</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-number">2</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 这个PHP文件将会放到与css和js文件同一个目录下，方便文件定位</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-var">$this_path</span><span class="hl-code"> = </span><span class="hl-identifier">dirname</span><span class="hl-brackets">(</span><span class="hl-code"> </span><span class="hl-identifier">realpath</span><span class="hl-brackets">(</span><span class="hl-reserved">__FILE__</span><span class="hl-brackets">)</span><span class="hl-code"> </span><span class="hl-brackets">)</span><span class="hl-code">.</span><span class="hl-reserved">DIRECTORY_SEPARATOR</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 根据URL请求来决定后续发生什么样的header到客户端</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-var">$type</span><span class="hl-code"> = </span><span class="hl-identifier">FILE_TYPE_UNKNOWN</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-var">$fname</span><span class="hl-code"> = </span><span class="hl-quotes">''</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-reserved">isset</span><span class="hl-brackets">(</span><span class="hl-var">$_REQUEST</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">css</span><span class="hl-quotes">'</span><span class="hl-brackets">]))</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$type</span><span class="hl-code"> = </span><span class="hl-identifier">FILE_TYPE_CSS</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$fname</span><span class="hl-code"> = </span><span class="hl-var">$_REQUEST</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">css</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-reserved">isset</span><span class="hl-brackets">(</span><span class="hl-var">$_REQUEST</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">js</span><span class="hl-quotes">'</span><span class="hl-brackets">]))</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$type</span><span class="hl-code"> = </span><span class="hl-identifier">FILE_TYPE_JS</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$fname</span><span class="hl-code"> = </span><span class="hl-var">$_REQUEST</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">js</span><span class="hl-quotes">'</span><span class="hl-brackets">]</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">else</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-reserved">exit</span><span class="hl-brackets">()</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 对参数进行判断</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-reserved">empty</span><span class="hl-brackets">(</span><span class="hl-var">$fname</span><span class="hl-brackets">))</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-reserved">exit</span><span class="hl-brackets">()</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 指定的文件应该存在，否则什么都不输出</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-var">$fname</span><span class="hl-code"> = </span><span class="hl-var">$this_path</span><span class="hl-code"> . </span><span class="hl-var">$fname</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-code">!</span><span class="hl-identifier">is_file</span><span class="hl-brackets">(</span><span class="hl-var">$fname</span><span class="hl-brackets">))</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-reserved">exit</span><span class="hl-brackets">()</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 得到文件内容，并获取文件最后修改时间</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-var">$output</span><span class="hl-code"> = </span><span class="hl-identifier">file_get_contents</span><span class="hl-brackets">(</span><span class="hl-var">$fname</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-var">$fmtime</span><span class="hl-code"> = </span><span class="hl-identifier">filemtime</span><span class="hl-brackets">(</span><span class="hl-var">$fname</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 如果该客户端不是第一次希望获取此文件，则会有如下变量</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-reserved">isset</span><span class="hl-brackets">(</span><span class="hl-var">$_SERVER</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">HTTP_IF_MODIFIED_SINCE</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]))</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-comment">// 这个变量里面放着客户端所缓存的这个文件的最后修改时间</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$checktime</span><span class="hl-code"> = </span><span class="hl-var">$_SERVER</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">HTTP_IF_MODIFIED_SINCE</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$checktime</span><span class="hl-code"> = </span><span class="hl-identifier">strtotime</span><span class="hl-brackets">(</span><span class="hl-var">$checktime</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-comment">// 比较一下时间，如果文件没有改动过，则无需发送文件内容（通过发送304响应码来完成）</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-var">$fmtime</span><span class="hl-code"> &lt;= </span><span class="hl-var">$checktime</span><span class="hl-brackets">)</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-identifier">header</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">HTTP/1.1 304 Not Modified</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; &nbsp; &nbsp; </span><span class="hl-reserved">exit</span><span class="hl-brackets">()</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 一个额外处理，将css文件中的注释全部去掉。如何去掉js的注释，还没有做。 :)</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-identifier">FILE_TYPE_CSS</span><span class="hl-code"> == </span><span class="hl-var">$type</span><span class="hl-brackets">)</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$output</span><span class="hl-code"> = </span><span class="hl-identifier">preg_replace</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">!/\*[^*]*\*+([^/][^*]*\*+)*/!</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-quotes">''</span><span class="hl-code">, </span><span class="hl-var">$output</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 重要：只有服务端的PHP加载了zlib模块，且客户端支持获取gzip压缩数据的情况下，我们才进行压缩</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; !</span><span class="hl-identifier">headers_sent</span><span class="hl-brackets">()</span><span class="hl-code"> &amp;&amp;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">extension_loaded</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">zlib</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code"> &amp;&amp;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">strstr</span><span class="hl-brackets">(</span><span class="hl-var">$_SERVER</span><span class="hl-brackets">[</span><span class="hl-quotes">&quot;</span><span class="hl-string">HTTP_ACCEPT_ENCODING</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">]</span><span class="hl-code">,</span><span class="hl-quotes">&quot;</span><span class="hl-string">gzip</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">)</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-comment">// 9 代表最强压缩</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-var">$output</span><span class="hl-code"> = </span><span class="hl-identifier">gzencode</span><span class="hl-brackets">(</span><span class="hl-var">$output</span><span class="hl-code">, </span><span class="hl-number">9</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-comment">// 告诉客户端我们发送的数据是压缩过的</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">header</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Content-Encoding: gzip</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-comment">// 下面这个header不太清楚其含义，貌似用于通知缓存服务器或者代理服务器（如果有的话）做某些操作吧，请达人告诉我</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">header</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Vary: Accept-Encoding</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-comment">// 告诉客户端压缩后的数据长度，因为压缩后的数据是二进制的，客户端需要这个数据来决定接收多少数据后可以结束</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">header</span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">Content-Length: </span><span class="hl-quotes">&quot;</span><span class="hl-code">.</span><span class="hl-identifier">strlen</span><span class="hl-brackets">(</span><span class="hl-var">$output</span><span class="hl-brackets">))</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 告诉客户端我们本次发送的数据是什么内容，注意编码格式，如果你的不是utf-8编码，要进行修改</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-identifier">FILE_TYPE_CSS</span><span class="hl-code"> == </span><span class="hl-var">$type</span><span class="hl-brackets">)</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">header</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">content-type: text/css; charset: utf-8</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">else</span><span class="hl-code"> </span><span class="hl-reserved">if</span><span class="hl-brackets">(</span><span class="hl-identifier">FILE_TYPE_JS</span><span class="hl-code"> == </span><span class="hl-var">$type</span><span class="hl-brackets">)</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-brackets">{</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp; &nbsp; </span><span class="hl-identifier">header</span><span class="hl-code"> </span><span class="hl-brackets">(</span><span class="hl-quotes">&quot;</span><span class="hl-string">content-type: text/javascript; charset: utf-8</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-brackets">}</span><span class="hl-code"></span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 重要：告诉客户端这个文件的最后修改时间，这样客户端下次访问此文件时，才会将这个时间再发回服务器，以便服务器进行判断</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-identifier">header</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Last-Modified: </span><span class="hl-quotes">'</span><span class="hl-code"> . </span><span class="hl-identifier">gmdate</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">D, d M Y H:i:s</span><span class="hl-quotes">'</span><span class="hl-code">, </span><span class="hl-var">$fmtime</span><span class="hl-brackets">)</span><span class="hl-code"> . </span><span class="hl-quotes">'</span><span class="hl-string"> GMT</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-identifier">header</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Etag: &quot;</span><span class="hl-quotes">'</span><span class="hl-code"> . </span><span class="hl-identifier">md5</span><span class="hl-brackets">(</span><span class="hl-var">$_SERVER</span><span class="hl-brackets">[</span><span class="hl-quotes">'</span><span class="hl-string">REQUEST_URI</span><span class="hl-quotes">'</span><span class="hl-brackets">])</span><span class="hl-code">.</span><span class="hl-quotes">'</span><span class="hl-string">&quot;</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-code">;</span></li>
<li><span class="hl-code">&nbsp;</span></li>
<li><span class="hl-code"></span><span class="hl-comment">// 将压缩后的数据发回客户端</span><span class="hl-code"></span></li>
<li><span class="hl-code"></span><span class="hl-reserved">echo</span><span class="hl-code"> </span><span class="hl-var">$output</span><span class="hl-code">;</span></li>
<li><span class="hl-code"></span><span class="hl-inlinetags">?&gt;</span></li></ol></div>
<p>我已经尽量在代码中使用注释来说明其工作了。</p>
<p>将这个文件放到保存CSS/Javascript文件的目录下，然后在需要使用原来的css/javascript文件的地方如下调用：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-brackets">&lt;</span><span class="hl-reserved">link</span><span class="hl-code"> </span><span class="hl-var">rel</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">stylesheet</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-var">href</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">http://your.domain.com/css/index.php?css=style.css</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-var">type</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">text/css</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">&gt;</span></li></ol></div>
<p>或者这样：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-brackets">&lt;</span><span class="hl-reserved">script</span><span class="hl-code"> </span><span class="hl-var">src</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">http://your.domain.com/css/index.php?js=common.css</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-var">type</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">text/javascript</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">&gt;</span></li></ol></div>
<p>就可以了。</p>
<p>可能你会问，为什么要这么做？为什么不直接使用Apache的mod_deflate模块来做输出时的压缩呢？原因有三个。</p>
<ol>
<li>缺省安装Apache是不会安装mod_deflate模块的，如果你的代码跑在一台你不能触及Apache设置的主机上，你将不得不用这里的办法；</li>
<li>这样可以让我们在编写代码时，尽量加入注释，以便使得代码自我解释，方便多人（或者自己在将来的某个时刻）进行维护，而注释在输出的时候，可以用PHP字符串处理功能干掉；</li>
<li>更重要的是，我们可以将多个css文件或者多个js文件一次性输出到客户端；</li>
</ol>
<p>太晚了，第三点的详细解释随后补上，睡觉去了~~~zz~~ZZZ</p>
<p><strong>[2009-12-12 继续补充]</strong></p>
<p>我们知道，HTTP通讯协议其实是一个很“昂贵”的协议，每次访问服务器上的单个资源，都需要重新经过一次协议握手，其中客户端向服务端发送的请求数据，还包括cookies的内容，以及很多附加的有用数据。而一个页面一般是由多个资源构成的，例如页面文件本身、css文件、js文件、图片文件等等。我们应该尽量减少资源的数量和体积，来减少客户端与服务端的交互。</p>
<p>考虑到现今的网页，一般都会使用多个css文件来控制页面布局及外观。其实，完全可以将其合并为一个文件，这样客户端也就只需要发送一次请求即可。我们可以采用下面的方法：</p>
<div class="hl-surround"><ol class="hl-main ln-show" title="Double click to hide line number." ondblclick = "linenumber(this)"><li class="hl-firstline"><span class="hl-brackets">&lt;</span><span class="hl-reserved">link</span><span class="hl-code"> </span><span class="hl-var">rel</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">stylesheet</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-var">href</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">http://your.domain.com/css/index.php?css=layout.css,style.css,color.css</span><span class="hl-quotes">&quot;</span><span class="hl-code"> </span><span class="hl-var">type</span><span class="hl-code">=</span><span class="hl-quotes">&quot;</span><span class="hl-string">text/css</span><span class="hl-quotes">&quot;</span><span class="hl-brackets">&gt;</span></li></ol></div>
<p>这样，我们一次性将服务器上的三个css文件发送给客户端了（当然，代码要略作调整，需要内部分解参数，然后读取三个文件到一个buffer中，再压缩输出，还要考虑最后更新时间采用哪个文件的，等等，不过这都是小问题）。</p>
<p>js文件也可如此处理。</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/279/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>谈谈网银和USB Key (五)</title>
		<link>http://apex.ncksoft.com/archives/273</link>
		<comments>http://apex.ncksoft.com/archives/273#comments</comments>
		<pubDate>Sat, 27 Jun 2009 18:56:04 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[PKI]]></category>
		<category><![CDATA[网银]]></category>
		<category><![CDATA[USB Key]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=273</guid>
		<description><![CDATA[好久没有写日志了，倒不是这段时间没有所思，而是思得太多，做的也更多，也就没有时间写了。好了，言归正传，下面我们接着说说《谈谈网银和USB Key (四)》中最后提到的“带确定按键的USB Key仍然不够安全”的原因。
是的，带确定按键的USB Key可以做到每次使用硬件内部的私有密钥时都是持有者明确授权的（即持有者做了按下确认键的操作），但是不要忘记，你能保证被签名的数据就一定是你想要签名的数据吗？这句话听起来有点绕口，那么我们来举一个例子：
特别注明：本文中所提到的商家、银行、地点、人物等均为举例方便而用，没有任何明确或隐含的意义。如有雷同，那一定是你踩到狗屎了~~~

假如你正在淘宝上买东西，购物车里塞满了满意的商品，终于，你决定购买了，于是开始下订单，但是发现你的淘宝账户上余额不足。这是个小问题，因为我们可以立即使用网上银行转账到淘宝账户上。OK，你来到支付宝，选择已经开通了网上银行功能的银行，然后点击“现在就转账”，终于进入了网上银行转账的页面。
&#8230;&#8230;其实，以上都是废话，因为我们不过是要提到网银转账的页面而已。不过，这可是我使用淘宝的真实流程哦&#8230;&#8230;
在网银的转账页面上，一般需要提供三个信息：你的账户、对方账户以及转账金额。其中，你的账户是你在登陆网银时就隐含提供了，对方账户则需要你填写（如果是向淘宝这样的商家转账，网上支付系统会自动填写），转账金额也要你填写（当然，如果是向一些商家转账，网上支付系统也会自动填写）。现在你小心翼翼的填好了所有的内容，并仔细的检查了三遍，一切无误，可以转账了。于是你点下“转账”按钮，网页上提示：请按USB Key的确认键以继续转账操作。当然，因为一切无误，所以你按下了确认键，然后系统提示你：转账已成功！
好了，现在回到淘宝网站，下单吧~~~ :)  等等，为什么淘宝还是提示你余额不足？！无奈之下你只好给银行客服人员打电话，在核对了你的身份之后，你终于等来了一个噩耗，客服MM用甜美的声音告诉你：对不起，我们的系统记录显示，您刚才确实有一次网上交易的操作，不过对方账号的开户行位于广州，是由一位名为“贺爱客”的先生持有的私人账号。[题外话：招商银行信用卡部的客服MM服务真的是一流，业务熟练，声音甜美，而民生银行方面就稍微逊色一些，一个小问题也要等她跟技术方面确认才能回答，希望这只是个例]
“贺爱客”？！鬼知道这是个什么人物，怎么你的钱就转给他了呢？现在你的脑袋里一片空白~~~~
&#8230;&#8230;好了，不用空白了，让我来告诉你发生了什么事吧！通过远程注入、恶意浏览器插件、函数挂钩等诸多手段，你所填写的数据在准备送给USB Key进行数字签名之前的刹那，被修改了！对方账户不再是淘宝，而是“贺爱客”。然而USB Key本身并无法得知你要给谁转账，它只能机械的等待你确认，然后对传入的数据进行签名。从电脑屏幕上来看，数据一切正常，但是到了USB Key内部，就已经大不一样了。这正是三十六计之中的“偷梁换柱”。咳~~咳咳~~~不要把老祖宗留下来的好东西拿来干坏事啊！
偷梁换柱并不是什么困难的事情，最简单的就是使用浏览器插件。尤其是对于IE这种“公共厕所”级别的浏览器，随便谁都可以过来插一脚。曾经有朋友向我抱怨电脑上网越来越慢了，我检查了一下他的系统，发现IE中加载了几十个插件：三个工具栏插件、十几个用于网上看电影的插件、两个网银用到的插件、四个下载加速插件、PDF阅读插件、金山词霸插件、还有七八个不知道是什么东西的插件。我问他为什么装这么多插件，他还一头雾水的问我，插件是虾米东东？？
难道说，在这样一个饿狼环伺，危险重重的恶劣网络环境下，我们就无法安全的使用网上银行，享受足不出户就能指点天下的便捷吗？
请听下回分解&#8230;
]]></description>
			<content:encoded><![CDATA[<p>好久没有写日志了，倒不是这段时间没有所思，而是思得太多，做的也更多，也就没有时间写了。好了，言归正传，下面我们接着说说<a href="http://apex.ncksoft.com/archives/162">《谈谈网银和USB Key (四)》</a>中最后提到的“带确定按键的USB Key仍然不够安全”的原因。</p>
<p>是的，带确定按键的USB Key可以做到每次使用硬件内部的私有密钥时都是持有者明确授权的（即持有者做了按下确认键的操作），但是不要忘记，你能保证被签名的数据就一定是你想要签名的数据吗？这句话听起来有点绕口，那么我们来举一个例子：</p>
<p><strong>特别注明：</strong>本文中所提到的商家、银行、地点、人物等均为举例方便而用，没有任何明确或隐含的意义。如有雷同，那一定是你踩到狗屎了~~~<br />
<span id="more-273"></span><br />
假如你正在淘宝上买东西，购物车里塞满了满意的商品，终于，你决定购买了，于是开始下订单，但是发现你的淘宝账户上余额不足。这是个小问题，因为我们可以立即使用网上银行转账到淘宝账户上。OK，你来到支付宝，选择已经开通了网上银行功能的银行，然后点击“现在就转账”，终于进入了网上银行转账的页面。</p>
<p>&#8230;&#8230;其实，以上都是废话，因为我们不过是要提到网银转账的页面而已。不过，这可是我使用淘宝的真实流程哦&#8230;&#8230;</p>
<p>在网银的转账页面上，一般需要提供三个信息：你的账户、对方账户以及转账金额。其中，你的账户是你在登陆网银时就隐含提供了，对方账户则需要你填写（如果是向淘宝这样的商家转账，网上支付系统会自动填写），转账金额也要你填写（当然，如果是向一些商家转账，网上支付系统也会自动填写）。现在你小心翼翼的填好了所有的内容，并仔细的检查了三遍，一切无误，可以转账了。于是你点下“转账”按钮，网页上提示：请按USB Key的确认键以继续转账操作。当然，因为一切无误，所以你按下了确认键，然后系统提示你：转账已成功！</p>
<p>好了，现在回到淘宝网站，下单吧~~~ :)  等等，为什么淘宝还是提示你余额不足？！无奈之下你只好给银行客服人员打电话，在核对了你的身份之后，你终于等来了一个噩耗，客服MM用甜美的声音告诉你：对不起，我们的系统记录显示，您刚才确实有一次网上交易的操作，不过对方账号的开户行位于广州，是由一位名为“贺爱客”的先生持有的私人账号。[题外话：招商银行信用卡部的客服MM服务真的是一流，业务熟练，声音甜美，而民生银行方面就稍微逊色一些，一个小问题也要等她跟技术方面确认才能回答，希望这只是个例]</p>
<p>“贺爱客”？！鬼知道这是个什么人物，怎么你的钱就转给他了呢？现在你的脑袋里一片空白~~~~</p>
<p>&#8230;&#8230;好了，不用空白了，让我来告诉你发生了什么事吧！通过远程注入、恶意浏览器插件、函数挂钩等诸多手段，你所填写的数据在准备送给USB Key进行数字签名之前的刹那，被修改了！对方账户不再是淘宝，而是“贺爱客”。然而USB Key本身并无法得知你要给谁转账，它只能机械的等待你确认，然后对传入的数据进行签名。从电脑屏幕上来看，数据一切正常，但是到了USB Key内部，就已经大不一样了。这正是三十六计之中的“<strong>偷梁换柱</strong>”。咳~~咳咳~~~不要把老祖宗留下来的好东西拿来干坏事啊！</p>
<p>偷梁换柱并不是什么困难的事情，最简单的就是使用浏览器插件。尤其是对于IE这种“公共厕所”级别的浏览器，随便谁都可以过来插一脚。曾经有朋友向我抱怨电脑上网越来越慢了，我检查了一下他的系统，发现IE中加载了几十个插件：三个工具栏插件、十几个用于网上看电影的插件、两个网银用到的插件、四个下载加速插件、PDF阅读插件、金山词霸插件、还有七八个不知道是什么东西的插件。我问他为什么装这么多插件，他还一头雾水的问我，插件是虾米东东？？</p>
<p>难道说，在这样一个饿狼环伺，危险重重的恶劣网络环境下，我们就无法安全的使用网上银行，享受足不出户就能指点天下的便捷吗？</p>
<p>请听下回分解&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/273/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>升级WordPress到2.8</title>
		<link>http://apex.ncksoft.com/archives/178</link>
		<comments>http://apex.ncksoft.com/archives/178#comments</comments>
		<pubDate>Mon, 15 Jun 2009 16:41:28 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[WordPress相关]]></category>
		<category><![CDATA[DeepWater]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=178</guid>
		<description><![CDATA[很久都没有更新博客了，实在是最近太忙了。这不，前两天趁着WordPress最新版本2.8正式发布，我终于抽了个时间做了一次系统升级。
没有想到的是，忙中出错，升级后系统后台管理进不去了，即使密码是正确的，登录后也只是显示一个“你没有对应的权限！”就把我打发了。没办法，只好临时备份了一下原来的数据库，然后重新创建了一个新的数据库，总算是可以登陆了。
我是从2.5直接升级到2.7的，后台变化太大了，但是感觉非常的棒。
左思右想，让我一直很喜欢的WordPress不应该出现这么低级的错误啊，升级后不应该不能用了。于是仔细检查升级过程所做的操作，果然发现问题：在修改配置文件的时候，原来的数据库没有设定所用的字符集，后台老版本缺省使用的是拉丁字符集，新版本缺省使用UTF-8字符集。屏蔽字符集设定，切换回旧的数据库，一切正常了，原来的插件都能用，自己设计的主题DeepWater也显示正常，真好。
嗯嗯，经验值涨17点~~~
过段时间有空了，写个脚本，将原来的数据库内容全部转换为UTF-8，以适应世界潮流，哇哈哈哈~~~~~
]]></description>
			<content:encoded><![CDATA[<p>很久都没有更新博客了，实在是最近太忙了。这不，前两天趁着WordPress最新版本2.8正式发布，我终于抽了个时间做了一次系统升级。</p>
<p>没有想到的是，忙中出错，升级后系统后台管理进不去了，即使密码是正确的，登录后也只是显示一个“你没有对应的权限！”就把我打发了。没办法，只好临时备份了一下原来的数据库，然后重新创建了一个新的数据库，总算是可以登陆了。</p>
<p>我是从2.5直接升级到2.7的，后台变化太大了，但是感觉非常的棒。</p>
<p>左思右想，让我一直很喜欢的WordPress不应该出现这么低级的错误啊，升级后不应该不能用了。于是仔细检查升级过程所做的操作，果然发现问题：在修改配置文件的时候，原来的数据库没有设定所用的字符集，后台老版本缺省使用的是拉丁字符集，新版本缺省使用UTF-8字符集。屏蔽字符集设定，切换回旧的数据库，一切正常了，原来的插件都能用，自己设计的主题DeepWater也显示正常，真好。</p>
<p>嗯嗯，经验值涨17点~~~</p>
<p>过段时间有空了，写个脚本，将原来的数据库内容全部转换为UTF-8，以适应世界潮流，哇哈哈哈~~~~~</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/178/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apache的SSL缓存</title>
		<link>http://apex.ncksoft.com/archives/177</link>
		<comments>http://apex.ncksoft.com/archives/177#comments</comments>
		<pubDate>Sat, 03 Jan 2009 02:29:59 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[PKI]]></category>
		<category><![CDATA[代码人生]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=177</guid>
		<description><![CDATA[自从六年前我从ASP阵营弃暗投明转向PHP阵营之后，就不时的与Apache打交道，Apache的配置也从1.3研究到2.2版。但是有一个问题一直困扰我，而且它不定时的就冒出来打击我一下，让我很是郁闷。
这个问题是这样的：把网站设置为需要进行SSL双向认证（即通过https://的方式访问网站，还需要有客户端数字证书），如果服务端是基于Apache的话，那么客户端（也就是浏览器）每次访问一个页面，对于页面上的每一份资源（一个页面通常包含很多资源，例如被html页面引用的.js/.css文件，页面中的各个图片、flash等等），都需要做一次数字签名。奇怪的是IIS服务器就没有这种情况。
每访问一个资源就做一次数字签名，这是一件恐怖的事情。一般情况下一个html页面都会包含十几个甚至几十个资源（特别是一些装饰用的小图片和一些小图标等等，每个文件也就两三KB，但是也需要进行数字签名），早期使用数字证书的时候基本上都是将数字证书保存在计算机硬盘上，数字签名也是由CPU来进行，一次数字签名也就几个毫秒，看起来影响就不大，但是随着技术的发展，后来都是以USB Key来对数字证书进行存储和运算，为了安全，数字签名就只能USB Key内部进行。试想一下，处理器速度一般就几M，高的也就几十M的USB Key处理芯片，在做数字签名的时候效率比起计算机两三个G的运算速度低了不少，即使经过特别优化，一般的USB Key做一次数字签名也需要十多二十毫秒。这种情况下，每访问一个资源就需要做一次数字签名，在打开一个网页的时候，就会发现有明显的延时，现象就是页面文字都已经显示出来了，而USB Key的指示灯还在狂闪（USB Key上通常有一个指示灯，当USB Key正在工作的时候就会闪烁，以提醒用户），然后才能够看到页面上的图片内容一个一个的显示出来。
这几年里，对于这个问题我一直都不求甚解，当初想通过修改Apache配置来解决，也试图在PHP脚本中加入Keep-alive之类的标记，但是终不得其法，渐渐的也就有了一个错误的认识，那就是Apache无法做到SSL状态的缓存，客户端访问每个SSL资源都必须重新重新经历握手、产生会话密钥等过程，所以每访问一个资源就会做一次数字签名。
这个错误的认识一直延续了好几年，在这几年中，当有人问到我这方面的问题时，我都毫不犹豫的告诉他这是Apache的问题，是出于安全性考虑才这样做的。但是另一方面，在我内心深处，还是隐约觉得事情不应该是这样的。终于，在一次封闭开发的过程中，我弄明白了事情的真相。

前几天因为一个银行的项目，需要我们做一个客户端软件来登陆银行的网银系统，而不是直接使用浏览器。我的任务就是做这个客户端软件。当然，做这样一个客户端并不是很困难的事情，大约封闭开发了四天，客户端就基本完成了。在自我测试的时候，前面所讲的这个问题又一次出现在我面前。
看着漂亮的客户端软件界面（其实就是内嵌一个WebBrowser控件的对话框），再看着登录成功后还一直狂闪的USB Key指示灯，心中越来越郁闷。Apache不会这么弱智的呀，那么弱智的应该是我了。那么再看一遍Apache的文档吧，网上有一份翻译的非常棒的Apache 2.2的文档，是金步国先生翻译的（赞一个先，感谢这样默默无私奉献的人！！！）。在mod_ssl模块的文档中，关于“SSLSessionCache 指令”一段又反复读了几遍。对于“SSLSessionCache”指令，官方解释是“这个指令指定了全局/进程间SSL会话缓存的类型。SSL会话缓存机制(可选的)可以加速对并发HTTPS请求的处理速度。对于同一个服务器进程处理的 HTTP keep-alive连接，OpenSSL自身已经在本地缓存了SSL会话信息。但是由于现代浏览器会使用多个并发连接请求页面内的图片等其他资源，服务器就不得不使用不同的进程来处理这些连接，因此能够在不同进程之间缓存SSL会话信息就有助于避免不必要的握手过程。”也就是说，Apache肯定是支持SSL缓存的。其推荐的方式是使用shm（也就是共享内存方式）来做SSL的状态缓存，再看看Windows版Apache安装后其配置文件中缺省使用的是shmcb的方式（这种方式在文档中并未提及），而我的Apache配置一直使用的是这个缺省配置。
我的天，该不会是shmcb方式是有问题的吧。把shmcb改为shm，果然，问题解决！！！
我不知道该哭还是该笑~~~ 困扰我五、六年的问题就这样改动两个字母就搞定了！
]]></description>
			<content:encoded><![CDATA[<p>自从六年前我从ASP阵营弃暗投明转向PHP阵营之后，就不时的与Apache打交道，Apache的配置也从1.3研究到2.2版。但是有一个问题一直困扰我，而且它不定时的就冒出来打击我一下，让我很是郁闷。</p>
<p>这个问题是这样的：把网站设置为需要进行SSL双向认证（即通过https://的方式访问网站，还需要有客户端数字证书），如果服务端是基于Apache的话，那么客户端（也就是浏览器）每次访问一个页面，对于页面上的每一份资源（一个页面通常包含很多资源，例如被html页面引用的.js/.css文件，页面中的各个图片、flash等等），都需要做一次数字签名。奇怪的是IIS服务器就没有这种情况。</p>
<p>每访问一个资源就做一次数字签名，这是一件恐怖的事情。一般情况下一个html页面都会包含十几个甚至几十个资源（特别是一些装饰用的小图片和一些小图标等等，每个文件也就两三KB，但是也需要进行数字签名），早期使用数字证书的时候基本上都是将数字证书保存在计算机硬盘上，数字签名也是由CPU来进行，一次数字签名也就几个毫秒，看起来影响就不大，但是随着技术的发展，后来都是以USB Key来对数字证书进行存储和运算，为了安全，数字签名就只能USB Key内部进行。试想一下，处理器速度一般就几M，高的也就几十M的USB Key处理芯片，在做数字签名的时候效率比起计算机两三个G的运算速度低了不少，即使经过特别优化，一般的USB Key做一次数字签名也需要十多二十毫秒。这种情况下，每访问一个资源就需要做一次数字签名，在打开一个网页的时候，就会发现有明显的延时，现象就是页面文字都已经显示出来了，而USB Key的指示灯还在狂闪（USB Key上通常有一个指示灯，当USB Key正在工作的时候就会闪烁，以提醒用户），然后才能够看到页面上的图片内容一个一个的显示出来。</p>
<p>这几年里，对于这个问题我一直都不求甚解，当初想通过修改Apache配置来解决，也试图在PHP脚本中加入Keep-alive之类的标记，但是终不得其法，渐渐的也就有了一个错误的认识，那就是Apache无法做到SSL状态的缓存，客户端访问每个SSL资源都必须重新重新经历握手、产生会话密钥等过程，所以每访问一个资源就会做一次数字签名。</p>
<p>这个错误的认识一直延续了好几年，在这几年中，当有人问到我这方面的问题时，我都毫不犹豫的告诉他这是Apache的问题，是出于安全性考虑才这样做的。但是另一方面，在我内心深处，还是隐约觉得事情不应该是这样的。终于，在一次封闭开发的过程中，我弄明白了事情的真相。<br />
<span id="more-177"></span></p>
<p>前几天因为一个银行的项目，需要我们做一个客户端软件来登陆银行的网银系统，而不是直接使用浏览器。我的任务就是做这个客户端软件。当然，做这样一个客户端并不是很困难的事情，大约封闭开发了四天，客户端就基本完成了。在自我测试的时候，前面所讲的这个问题又一次出现在我面前。</p>
<p>看着漂亮的客户端软件界面（其实就是内嵌一个WebBrowser控件的对话框），再看着登录成功后还一直狂闪的USB Key指示灯，心中越来越郁闷。Apache不会这么弱智的呀，那么弱智的应该是我了。那么再看一遍Apache的文档吧，网上有一份翻译的<a href="http://lamp.linux.gov.cn/Apache/ApacheMenu/index.html">非常棒的Apache 2.2的文档</a>，是金步国先生翻译的（赞一个先，感谢这样默默无私奉献的人！！！）。在mod_ssl模块的文档中，关于“SSLSessionCache 指令”一段又反复读了几遍。对于“SSLSessionCache”指令，官方解释是“这个指令指定了全局/进程间SSL会话缓存的类型。SSL会话缓存机制(可选的)可以加速对并发HTTPS请求的处理速度。对于同一个服务器进程处理的 HTTP keep-alive连接，OpenSSL自身已经在本地缓存了SSL会话信息。但是由于现代浏览器会使用多个并发连接请求页面内的图片等其他资源，服务器就不得不使用不同的进程来处理这些连接，因此能够在不同进程之间缓存SSL会话信息就有助于避免不必要的握手过程。”也就是说，Apache肯定是支持SSL缓存的。其推荐的方式是使用shm（也就是共享内存方式）来做SSL的状态缓存，再看看Windows版Apache安装后其配置文件中缺省使用的是shmcb的方式（这种方式在文档中并未提及），而我的Apache配置一直使用的是这个缺省配置。</p>
<p>我的天，该不会是shmcb方式是有问题的吧。把shmcb改为shm，果然，问题解决！！！</p>
<p>我不知道该哭还是该笑~~~ 困扰我五、六年的问题就这样改动两个字母就搞定了！</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/177/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>吉隆坡的七天（1）</title>
		<link>http://apex.ncksoft.com/archives/176</link>
		<comments>http://apex.ncksoft.com/archives/176#comments</comments>
		<pubDate>Mon, 10 Nov 2008 02:01:32 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[海外见闻]]></category>
		<category><![CDATA[马来西亚]]></category>
		<category><![CDATA[Kuala Lumpur]]></category>
		<category><![CDATA[吉隆坡]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=176</guid>
		<description><![CDATA[一周前接到通知，要我去一趟马来西亚，需要待一周时间，于是急急忙忙去办签证，嘿嘿，去马来西亚办签证非常简单。整个过程我就跟签证官说了一句话：

签证官：Passport。  （让我把护照递给他）
签证官：Eighty。  （签证费八十块人民币）
我：Thanks, bye。 (手续办完，离开)

然后隔一天就可以取到签证了。
十一月九日深夜11点半，经过六个多小时的飞行，飞机降落在马来西亚首都吉隆坡国际机场，入关之前先去兑换一点马币（他们叫令吉），1000人民币可以兑换466马币。
然后就是等待入关，等待取行李等等，接近凌晨一点才从机场出来。来之前Edward告诉我马来西亚的出租车管理比较混乱，最好在机场购买隶属于机场的出租车票，然后凭票乘坐机场出租车，这样就非常安全了。因为是十二点过，所以从机场到市区要八十多马币，比十二点以前的价格策略要多出二十块左右。
两点左右，顺利到达了市区里预定的酒店，酒店房间没有开通网络，于是查找无线接入点，果然有，P1HotZone，一个新兴的城市无线接入服务提供商，可以在线购买上网时间。我兴高采烈的开始填写个人信息，VISA信息等等，但是最终在VISA在线付费的时候失败了。想想太晚了，就洗洗睡了。
上午Edward开车过来酒店接我去他的公司，他是一个很热情的人。一路上景色很好，绿叶很绿，蓝天很蓝，白云很白，空气很空。
中午去吃肉骨茶（其实不是“茶”，而是煲汤），很重的中药香味，马上想起的是小时候母亲用当归、黄芪、党参等熬的鸡汤，这样的味道已经很久很久没有品尝到了，浓郁的香味中裹着一种怀念的情绪。小心的喝下一口烫烫的汤汁，顿觉一股暖流穿过脾胃，说不出的熨帖舒服。
下午没事，他们在准备明天的BankTech展会的事情，我就在办公室写文档。大约四点过，准备工作做好了，于是跟他们去布置展场。
展场就在著名的双子塔(KLCC)旁边，八月份的微软TechEd就在这里开的。这次BankTech的展厅很小，我看了看，估计也就二十家左右参展。
]]></description>
			<content:encoded><![CDATA[<p>一周前接到通知，要我去一趟马来西亚，需要待一周时间，于是急急忙忙去办签证，嘿嘿，去马来西亚办签证非常简单。整个过程我就跟签证官说了一句话：</p>
<ul>
<li>签证官：Passport。  （让我把护照递给他）</li>
<li>签证官：Eighty。  （签证费八十块人民币）</li>
<li>我：Thanks, bye。 (手续办完，离开)</li>
</ul>
<p>然后隔一天就可以取到签证了。</p>
<p>十一月九日深夜11点半，经过六个多小时的飞行，飞机降落在马来西亚首都吉隆坡国际机场，入关之前先去兑换一点马币（他们叫令吉），1000人民币可以兑换466马币。</p>
<p><span id="more-176"></span>然后就是等待入关，等待取行李等等，接近凌晨一点才从机场出来。来之前Edward告诉我马来西亚的出租车管理比较混乱，最好在机场购买隶属于机场的出租车票，然后凭票乘坐机场出租车，这样就非常安全了。因为是十二点过，所以从机场到市区要八十多马币，比十二点以前的价格策略要多出二十块左右。</p>
<p>两点左右，顺利到达了市区里预定的酒店，酒店房间没有开通网络，于是查找无线接入点，果然有，P1HotZone，一个新兴的城市无线接入服务提供商，可以在线购买上网时间。我兴高采烈的开始填写个人信息，VISA信息等等，但是最终在VISA在线付费的时候失败了。想想太晚了，就洗洗睡了。</p>
<p>上午Edward开车过来酒店接我去他的公司，他是一个很热情的人。一路上景色很好，绿叶很绿，蓝天很蓝，白云很白，空气很空。</p>
<p>中午去吃肉骨茶（其实不是“茶”，而是煲汤），很重的中药香味，马上想起的是小时候母亲用当归、黄芪、党参等熬的鸡汤，这样的味道已经很久很久没有品尝到了，浓郁的香味中裹着一种怀念的情绪。小心的喝下一口烫烫的汤汁，顿觉一股暖流穿过脾胃，说不出的熨帖舒服。</p>
<p>下午没事，他们在准备明天的BankTech展会的事情，我就在办公室写文档。大约四点过，准备工作做好了，于是跟他们去布置展场。</p>
<p>展场就在著名的双子塔(KLCC)旁边，八月份的微软TechEd就在这里开的。这次BankTech的展厅很小，我看了看，估计也就二十家左右参展。</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/176/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>China Tech.Ed 2008 开幕</title>
		<link>http://apex.ncksoft.com/archives/174</link>
		<comments>http://apex.ncksoft.com/archives/174#comments</comments>
		<pubDate>Fri, 07 Nov 2008 02:23:37 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[其他分类]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[TechEd]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=174</guid>
		<description><![CDATA[今天一早就来到工人体育场，真的是好早：赞助商要在八点到场做准备，而正式开幕是在九点半。哎，只好早早的告别温暖的被窝了。
停车的时候，看到旁边一哥们手里把玩着的手机真是自己渴慕已久的HTC Touch Pro，于是借过来感受了一下机子的重量、大小和手感，哎，真的是太爽了，等过几天从马来西亚回来，就去买~~~
本次Tech.Ed的规模比起以前来说，要小了不少，但是绝对数量还是比较多的，三千多人陆陆续续的到来，三三两两聚在一起。入口处安检很严格，连打火机都不许带进场，真是过分！！
趁着还没有开幕，就在会场外围逛逛。本次活动的赞助商可以在会场外围摆摆地摊，在微软推广Windows Mobile的地摊旁边，摆放了很多支持Windows Mobile的手机，这里我不单看到了HTC Touch Pro，还看到了HTC Touch HD（我更喜欢这一款），以及很多的高端智能手机，真是大饱眼福。
开幕式很有中国味，我和同事在讨论这到底是仿奥运开幕式风格，还是学《八面埋伏》的舞蹈场景，蛮有意思的。
开幕式之后就是介绍微软的新产品，其实好多“新产品”早就已经在网上看过了，现在就是更深入、直观的看到一些视频、演示等等。十点半的时候，想起还要去大使馆取签证，于是就翘课了。
下午继续展示新产品，主要是虚拟化技术、Surface、Visual Studio 2010等等。不知怎么的，感觉微软的技术发展离我们越来越远似的，已经远远超出操作系统的范畴，在各个方面都有涉及。还有云计算、高性能计算、Hyper-V等技术的涌现，难道世界上就只剩下超级大公司了？呜呼，对于500人以下的小公司，又有什么是适合用的呢~~~
P.S.: 到底选HTC Touch Pro好，还是选HTC Touch HD好呢？这真是让人矛盾啊~~~
]]></description>
			<content:encoded><![CDATA[<p>今天一早就来到工人体育场，真的是好早：赞助商要在八点到场做准备，而正式开幕是在九点半。哎，只好早早的告别温暖的被窝了。</p>
<p>停车的时候，看到旁边一哥们手里把玩着的手机真是自己渴慕已久的HTC Touch Pro，于是借过来感受了一下机子的重量、大小和手感，哎，真的是太爽了，等过几天从马来西亚回来，就去买~~~</p>
<p>本次Tech.Ed的规模比起以前来说，要小了不少，但是绝对数量还是比较多的，三千多人陆陆续续的到来，三三两两聚在一起。入口处安检很严格，连打火机都不许带进场，真是过分！！</p>
<p>趁着还没有开幕，就在会场外围逛逛。本次活动的赞助商可以在会场外围摆摆地摊，在微软推广Windows Mobile的地摊旁边，摆放了很多支持Windows Mobile的手机，这里我不单看到了HTC Touch Pro，还看到了HTC Touch HD（我更喜欢这一款），以及很多的高端智能手机，真是大饱眼福。</p>
<p>开幕式很有中国味，我和同事在讨论这到底是仿奥运开幕式风格，还是学《八面埋伏》的舞蹈场景，蛮有意思的。</p>
<p><span id="more-174"></span>开幕式之后就是介绍微软的新产品，其实好多“新产品”早就已经在网上看过了，现在就是更深入、直观的看到一些视频、演示等等。十点半的时候，想起还要去大使馆取签证，于是就翘课了。</p>
<p>下午继续展示新产品，主要是虚拟化技术、Surface、Visual Studio 2010等等。不知怎么的，感觉微软的技术发展离我们越来越远似的，已经远远超出操作系统的范畴，在各个方面都有涉及。还有云计算、高性能计算、Hyper-V等技术的涌现，难道世界上就只剩下超级大公司了？呜呼，对于500人以下的小公司，又有什么是适合用的呢~~~</p>
<p>P.S.: 到底选HTC Touch Pro好，还是选HTC Touch HD好呢？这真是让人矛盾啊~~~</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/174/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>关于Apache的mod_rewrite模块</title>
		<link>http://apex.ncksoft.com/archives/172</link>
		<comments>http://apex.ncksoft.com/archives/172#comments</comments>
		<pubDate>Mon, 27 Oct 2008 17:58:51 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[代码人生]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mod_rewrite]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=172</guid>
		<description><![CDATA[很久以前写过一篇《Apache的Rewrite模块》，但那时是Mambo内部完成的参数解析，我一直没有花时间去真正搞清楚rewrite机制是如何进行的。最近做网站需要自己来做rewrite，所以又复习了一遍。
将动态网页链接rewriting成静态链接是最保险和稳定的面向搜索引擎优化方式。如果网站想更好地被搜索引擎收录，网站设计除了面向用户友好（User Friendly）外，搜索引擎友好 （Search Engine Friendly）的设计也是非常重要的。进入搜索引擎的页面内容越多，则被用户用不同的关键词找到的几率越大。在Google的算法调查一文中提到一个站点被Google索引页面的数量其实对PageRank也是有一定影响的。由于Google突出的是整个网络中相对静态的部分（动态网页索引量比较小）,链接地址相对固定的静态网页比较适合被Google索引（怪不得很多大网站的邮件列表归档和BLOG按日期归档的文档很容被搜的到），因此很多关于面向搜索引擎URL设计优化(URI Pretty)的文章中提到了很多利用一定机制将动态网页参数变成像静态网页的形式：
比如可以将：
http://www.domain.com/index.php?product=mp3&#038;action=ls
变成：http://www.domain.com/product/mp3/action/ls.html
操作如下：

1. 确保apache的http.conf中加载了mod_rewrite模块(缺省是不加载的)。
2. 确保apache配置中站点目录允许.htaccess重载，即：
	AllowOverride All
   需要注意的是，如果站点目录是在虚拟主机设定中进行的，不要改错了位置。
3. 修改了配置文件后，需要重新启动apache。
4. 在需要进行URL重写的目录下建立.htaccess文件。例如要对整个站点进行重写，则在站点根目录下建立.htaccess文件，假定我们的站点根目录为：
   c:\www\htdocs\test\
而服务器的根目录为
   c:\www\htdocs\
那么需要在c:\www\htdocs\test\目录下建立.htaccess，文件内容如下：
&#60;IfModule mod_rewrite.c&#62;
RewriteEngine On
RewriteBase /test/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test/index.php [L]
&#60;/IfModule&#62;
当然，如果站点目录就是根目录，则.htaccess文件内容如下：
&#60;IfModule mod_rewrite.c&#62;
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&#60;/IfModule&#62;
上述重写规则表示：启用URL重写功能，对于以&#8221;RewriteBase&#8221;开始的URL，如果没有找到直接的文件，则将其重写为 /index.php 。
假定我们有如下的目录结构(注：站点根目录为c:\www\htdocs\test\)
  c:\www\htdocs\test\
    &#124;- .htaccess
    &#124;- index.php
  [...]]]></description>
			<content:encoded><![CDATA[<p>很久以前写过一篇<a href="http://apex.ncksoft.com/archives/7">《Apache的Rewrite模块》</a>，但那时是Mambo内部完成的参数解析，我一直没有花时间去真正搞清楚rewrite机制是如何进行的。最近做网站需要自己来做rewrite，所以又复习了一遍。</p>
<p>将动态网页链接rewriting成静态链接是最保险和稳定的面向搜索引擎优化方式。如果网站想更好地被搜索引擎收录，网站设计除了面向用户友好（User Friendly）外，搜索引擎友好 （Search Engine Friendly）的设计也是非常重要的。进入搜索引擎的页面内容越多，则被用户用不同的关键词找到的几率越大。在Google的算法调查一文中提到一个站点被Google索引页面的数量其实对PageRank也是有一定影响的。由于Google突出的是整个网络中相对静态的部分（动态网页索引量比较小）,链接地址相对固定的静态网页比较适合被Google索引（怪不得很多大网站的邮件列表归档和BLOG按日期归档的文档很容被搜的到），因此很多关于面向搜索引擎URL设计优化(URI Pretty)的文章中提到了很多利用一定机制将动态网页参数变成像静态网页的形式：<br />
比如可以将：<br />
http://www.domain.com/index.php?product=mp3&#038;action=ls<br />
变成：http://www.domain.com/product/mp3/action/ls.html</p>
<p>操作如下：<br />
<span id="more-172"></span><br />
1. 确保apache的http.conf中加载了mod_rewrite模块(缺省是不加载的)。<br />
2. 确保apache配置中站点目录允许.htaccess重载，即：<br />
	AllowOverride All<br />
   需要注意的是，如果站点目录是在虚拟主机设定中进行的，不要改错了位置。<br />
3. 修改了配置文件后，需要重新启动apache。<br />
4. 在需要进行URL重写的目录下建立.htaccess文件。例如要对整个站点进行重写，则在站点根目录下建立.htaccess文件，假定我们的站点根目录为：<br />
   c:\www\htdocs\test\<br />
而服务器的根目录为<br />
   c:\www\htdocs\<br />
那么需要在c:\www\htdocs\test\目录下建立.htaccess，文件内容如下：</p>
<p><code>&lt;IfModule mod_rewrite.c&gt;<br />
RewriteEngine On<br />
RewriteBase /test/<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule . /test/index.php [L]<br />
&lt;/IfModule&gt;</code></p>
<p>当然，如果站点目录就是根目录，则.htaccess文件内容如下：</p>
<p><code>&lt;IfModule mod_rewrite.c&gt;<br />
RewriteEngine On<br />
RewriteBase /<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule . /index.php [L]<br />
&lt;/IfModule&gt;</code></p>
<p>上述重写规则表示：启用URL重写功能，对于以&#8221;RewriteBase&#8221;开始的URL，如果没有找到直接的文件，则将其重写为 /index.php 。</p>
<p>假定我们有如下的目录结构(注：站点根目录为c:\www\htdocs\test\)<br />
  c:\www\htdocs\test\<br />
    |- .htaccess<br />
    |- index.php<br />
    |<br />
    |- info   (这是一个目录)<br />
    |    |-  .htaccess<br />
    |    \-  index.php<br />
    |<br />
    \- info2<br />
         |- test.html<br />
         \- info.php</p>
<p>其中，c:\www\htdocs\test\.htaccess的文件内容为：<br />
<code>&lt;IfModule mod_rewrite.c&gt;<br />
RewriteEngine On<br />
RewriteBase /test/<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule . /test/index.php [L]<br />
&lt;/IfModule&gt;</code></p>
<p>而 c:\www\htdocs\test\info\.htaccess的内容为：<br />
<code>&lt;IfModule mod_rewrite.c&gt;<br />
RewriteEngine On<br />
RewriteBase /test/info/<br />
RewriteCond %{REQUEST_FILENAME} !-f<br />
RewriteCond %{REQUEST_FILENAME} !-d<br />
RewriteRule . /info/index.php [L]<br />
&lt;/IfModule&gt;</code></p>
<p>那么会有如下重写结果：</p>
<p>尝试访问： http://www.domain.com/test/aaa/bbb/ccc.html<br />
实际访问： /test/index.php<br />
得到参数： /test/aaa/bbb/ccc.html</p>
<p>尝试访问： http://www.domain.com/test/info/bbb/ccc.html<br />
实际访问： /test/info/index.php<br />
得到参数： /test/info/bbb/ccc.html</p>
<p>尝试访问： http://www.domain.com/test/info2/test.html<br />
实际访问： /test/info2/test.html<br />
得到参数： N/A</p>
<p>尝试访问： http://www.domain.com/test/info2/abcd.html<br />
实际访问： /test/index.php<br />
得到参数： /test/info2/abcd.html</p>
<p>上面的内容中，&#8221;实际访问&#8221;就是$_SERVER['PHP_SELF']，而&#8221;得到参数&#8221;其实就是$_SERVER['REQUEST_URI']。这样，我们可以在PHP脚本中根据一定的规则将参数分离出来。比如说对于http://www.domain.com/test/a/AA/b/BB.html:<br />
  &#8230;<br />
  $urlpath = PHP_SELF反向查找&#8217;/'字符，然后抛弃后面的文件名; (得到: /test/)<br />
  $param = REQUEST_URI &#8211; $urlpath; (得到: a/AA/b/BB.html)<br />
  $param = $param &#8211; &#8216;.html&#8217;; (得到: a/AA/b/BB)<br />
  $params = 用&#8217;/'将$param分割; (得到一个数组)<br />
  用循环合成需要的参数，得到 $a = &#8216;AA&#8217;; $b = &#8216;BB&#8217;;<br />
  使用这些参数<br />
  &#8230;</p>
<p>当然，也可以设计其他的参数规则，例如某个页面有固定的参数形式，则可以：<br />
  http://www.domain.com/test/AA/BB.html<br />
我们要求第一个参数一定是$a，第二个参数一定是$b，效果一样。但是这样的规则设计不可以写成：<br />
  http://www.domain.com/test/BB/AA.html<br />
那样就乱套了。</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/172/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>工作满八年了</title>
		<link>http://apex.ncksoft.com/archives/175</link>
		<comments>http://apex.ncksoft.com/archives/175#comments</comments>
		<pubDate>Mon, 20 Oct 2008 11:39:12 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[心情随笔]]></category>
		<category><![CDATA[工作七周年志]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=175</guid>
		<description><![CDATA[今天，是我参加工作整整八年的纪念日，也是我第一份工作满八年的纪念日——我还没有跳过槽呢。
说起来，在IT界，工作这么长时间还没有跳槽还真是不多见。不过正因如此，我亲身陪伴公司从二十来人成长到二百六七十人，我也从一个小兵成长为公司的CIO，不论是公司还是我自己，都有了很多很多的收获。
但是现在还不是收获的季节，一方面是全球信贷危机（虽然目前对我们的影响并不大），一方面是公司成立十周年了，正处于一个成长与转变的矛盾期，而自己也处在从纯技术开发、管理到信息管理的转型期，一句话，革命尚未成功，同志仍需努力！！
可惜我的《工作七周年志》还没有写完，就得开始改标题为《工作八周年志》了。  :)
]]></description>
			<content:encoded><![CDATA[<p>今天，是我参加工作整整八年的纪念日，也是我第一份工作满八年的纪念日——我还没有跳过槽呢。</p>
<p>说起来，在IT界，工作这么长时间还没有跳槽还真是不多见。不过正因如此，我亲身陪伴公司从二十来人成长到二百六七十人，我也从一个小兵成长为公司的CIO，不论是公司还是我自己，都有了很多很多的收获。</p>
<p>但是现在还不是收获的季节，一方面是全球信贷危机（虽然目前对我们的影响并不大），一方面是公司成立十周年了，正处于一个成长与转变的矛盾期，而自己也处在从纯技术开发、管理到信息管理的转型期，一句话，革命尚未成功，同志仍需努力！！</p>
<p>可惜我的《工作七周年志》还没有写完，就得开始改标题为《工作八周年志》了。  :)</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/175/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>好贴心的感觉</title>
		<link>http://apex.ncksoft.com/archives/173</link>
		<comments>http://apex.ncksoft.com/archives/173#comments</comments>
		<pubDate>Sun, 07 Sep 2008 16:15:49 +0000</pubDate>
		<dc:creator>Apex</dc:creator>
				<category><![CDATA[我的宝贝]]></category>
		<category><![CDATA[宝宝]]></category>

		<guid isPermaLink="false">http://apex.ncksoft.com/?p=173</guid>
		<description><![CDATA[最近太忙，晚上回到家，吃过饭，一阵倦意涌上来，于是就倒在沙发上睡一会儿。
正迷迷糊糊时，感觉有人给我披上了被子，睁眼一看，原来是我的宝宝，她本来在看动画片，见我倒在沙发上睡着了，于是自己跑到卧室去把她的小被子抱了出来给我盖上。
呜呜呜~~~好乖巧的女儿，真是我的好宝宝~~~一阵贴心的感觉，真的好幸福啊~~~
]]></description>
			<content:encoded><![CDATA[<p>最近太忙，晚上回到家，吃过饭，一阵倦意涌上来，于是就倒在沙发上睡一会儿。</p>
<p>正迷迷糊糊时，感觉有人给我披上了被子，睁眼一看，原来是我的宝宝，她本来在看动画片，见我倒在沙发上睡着了，于是自己跑到卧室去把她的小被子抱了出来给我盖上。</p>
<p>呜呜呜~~~好乖巧的女儿，真是我的好宝宝~~~一阵贴心的感觉，真的好幸福啊~~~</p>
]]></content:encoded>
			<wfw:commentRss>http://apex.ncksoft.com/archives/173/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
