将动态网页链接rewriting成静态链接是最保险和稳定的面向搜索引擎优化方式。如果网 站想更好地被搜索引擎收录,网站设计除了面向用户友好(User Friendly)外,搜索引擎友好 (Search Engine Friendly)的设计也是非常重要的。进入搜索引擎的页面内容越多,则被用户用不同的关键词找到的几率越大。在Google的算法调查一文中提到一个 站点被Google索引页面的数量其实对PageRank也是有一定影响的。由于Google突出的是整个网络中相对静态的部分(动态网页索引量比较 小),链接地址相对固定的静态网页比较适合被Google索引(怪不得很多大网站的邮件列表归档和BLOG按日期归档的文档很容被搜的到),因此很多关于 面向搜索引擎URL设计优化(URI Pretty)的文章中提到了很多利用一定机制将动态网页参数变成像静态网页的形式:
比如可以将:
http://www.domain.com/index.php?product=mp3&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,文件内容如下:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /test/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test/index.php [L]
</IfModule>
当然,如果站点目录就是根目录,则.htaccess文件内容如下:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
上述重写规则表示:启用URL重写功能,对于以”RewriteBase”开始的URL,如果没有找到直接的文件,则将其重写为 /index.php 。
假定我们有如下的目录结构(注:站点根目录为c:/www/htdocs/test/)
c:/www/htdocs/test/
|- .htaccess
|- index.php
|
|- info (这是一个目录)
| |- .htaccess
| /- index.php
|
/- info2
|- test.html
/- info.php
其中,c:/www/htdocs/test/.htaccess的文件内容为:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /test/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /test/index.php [L]
</IfModule>
而 c:/www/htdocs/test/info/.htaccess的内容为:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /test/info/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /info/index.php [L]
</IfModule>
那么会有如下重写结果:
尝试访问: http://www.domain.com/test/aaa/bbb/ccc.html
实际访问: /test/index.php
得到参数: /test/aaa/bbb/ccc.html
尝试访问: http://www.domain.com/test/info/bbb/ccc.html
实际访问: /test/info/index.php
得到参数: /test/info/bbb/ccc.html
尝试访问: http://www.domain.com/test/info2/test.html
实际访问: /test/info2/test.html
得到参数: N/A
尝试访问: http://www.domain.com/test/info2/abcd.html
实际访问: /test/index.php
得到参数: /test/info2/abcd.html
上面的内容中,”实际访问”就是$_SERVER[’PHP_SELF’],而”得到参数” 其实就是$_SERVER[’REQUEST_URI’]。这样,我们可以在PHP脚本中根据一定的规则将参数分离出来。比如说对于 http://www.domain.com/test/a/AA/b/BB.html:
…
$urlpath = PHP_SELF反向查找’/'字符,然后抛弃后面的文件名; (得到: /test/)
$param = REQUEST_URI - $urlpath; (得到: a/AA/b/BB.html)
$param = $param - ‘.html’; (得到: a/AA/b/BB)
$params = 用’/'将$param分割; (得到一个数组)
用循环合成需要的参数,得到 $a = ‘AA’; $b = ‘BB’;
使用这些参数
…
当然,也可以设计其他的参数规则,例如某个页面有固定的参数形式,则可以:
http://www.domain.com/test/AA/BB.html
我们要求第一个参数一定是$a,第二个参数一定是$b,效果一样。但是这样的规则设计不可以写成:
http://www.domain.com/test/BB/AA.html
那样就乱套了。