WordPress Rewrite SEO 之404方式折腾笔记

2011-07-17
4分钟阅读时长
1629字
阅读
Featured Image

WordPress 是多么强大的Blog(甚至可以说CMS)系统就不用多说了。说到底我把WP只看做一个开发起步的框架而已,更多的性能及功能的挖掘和利用还是需要自己去完成。
最近折腾 HTML5探索 的SEO时,想起来我的博客依旧还没做过SEO,遂就开始了下面记录中的折腾回忆录。
空间是虚拟主机(还是WIN + IIS)、无Rewrite、无子域名等等,在诸多的不利因素下,对于强大的WordPress来说,依旧能找到较好的优化方式: 404 Rewrite
so, 就开始大面积的调整程序 + hack 终于算完成了现在的Rewrite,真是累死我也。(做了一大堆复杂的兼容工作,历史原因害死人呀!)
经过亲身体验,需要提醒下使用 404 Rewrite 前要明确站点是否为新建站点,若是,一切很easy,若不是,就有了我下面的那么多兼容工作要做,悲催!!
正常的对于新建站点(404支持设置为php页面前提),因为站点较新搜索引擎还未开始收录,对外分享也几乎为0。所以需要做的就相对很少,编写好404.php的处理代码,后台做好配置即可。
而有时候(其实就是我现在啦- -), 站点运行很长时间(几年了),期间经历过无数的配置调整(还有数据丢失,我擦!),对于各种URL已经产生了很多种版本,所以需要做的工作就非常多了。
由于已经过了2天了,具体顺序都不清楚了,这里仅做下回忆录式笔记,以防以后不备之需(身在天朝,谁知哪天又天灾人祸呀!):

涉及文件修改列表:

/404.php     /index.php     /blog/index.php

修改回忆录:

  1. /blog/index.php -> /blog/index.php.bak 说白了就是备份
  2. 新建 /blog/index.php, 编写一些兼容处理代码:
<?php
// zfkun.com to www.zfkun.com
if ( $_SERVER["HTTP_HOST"] === "zfkun.com") {
doRedirect("http://www.");
} else {

// 对所有原有效URL规则做301永久重定向,从而兼容原旧历史路径
$_qu = str_replace('/blog/index.php', '', $_SERVER['REQUEST_URI']);
$_SERVER["REQUEST_URI"] = (empty($_qu) || $_qu == "") ? '/' : $_qu;
doRedirect();
}

function doRedirect($prefix = "http://") {
header( "HTTP/1.1 301 Moved Permanently" );
header("Location: " . $prefix . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] );
}
?>
  1. cp /blog/index.php.bak /index.php, 然后增加兼容处理:
<?php
    // zfkun.com to www.zfkun.com
    if ( $_SERVER["HTTP_HOST"] === "zfkun.com" ) {
    header( "HTTP/1.1 301 Moved Permanently" );
    header("Location: " . "http://www." . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"] );
    exit;
} else {

	/**
	 * 对 /index.php/archives/* 形式URL做下过滤(历史原因)
	 *    增加对一些特殊路径的兼容纠错,如:
	 *        http://www.zfkun.com/index.php/archives/category/code/javascript
	 *        http://www.zfkun.com/index.php/archives/tag/javascript
	 *        http://www.zfkun.com/index.php/archives/205.html
	 */
	if (strpos($_SERVER['REQUEST_URI'], '/index.php') === 0) {
		$_qu = str_replace( '/archives', '', str_replace('/index.php', '', $_SERVER['REQUEST_URI']) );
		if (!empty($_qu)) {
                    // 修正对 /index.php/archives/239 此类地址解析时忘记补充 .html 造成的BUG
		    if (strpos($_qu, '.html') === false) {
		        // '/205' => '/205.html'
		         $_qu = preg_replace('/^\/(\d+)/', '$0.html', $_qu);
		    }
		    $_SERVER['PATH_INFO'] = $_SERVER["REQUEST_URI"] = $_qu;
		}
	}
}

// 解决 WordPress的中文路径在WIN + IIS 下的解析错误问题
$_SERVER['PATH_INFO'] = mb_convert_encoding($_SERVER['PATH_INFO'],"UTF-8","GBK");
$_SERVER['REQUEST_URI'] = mb_convert_encoding($_SERVER['REQUEST_URI'], "UTF-8", "GBK");
.....
?>
  1. 新建 /404.php 并设置虚拟主机404错误跳转至它,代码摘要:
<?php
/**
 * 重置 $_SERVER['REQUEST_URI'] 为期望访问的值
 * 如:
 *    当前访问  http://www.zfkun.com/date/2010/01 ,
 *    则 404 跳转来的 $_SERVER['QUERY_STRING'] === '404;http://www.zfkun.com:80/date/2010/01'
 */
$_SERVER['REQUEST_URI'] = substr($_SERVER['QUERY_STRING'], strpos($_SERVER['QUERY_STRING'], ':80') + 3);

// blog rule 标志位
$isBlogRule = false;

if (strpos($_SERVER['REQUEST_URI'], '/blog') === 0) {
    $_SERVER['REQUEST_URI'] = substr($_SERVER['REQUEST_URI'], 5);
    $isBlogRule = true;
}

if ($isBlogRule) {
    $_SERVER['REQUEST_URI'] = str_replace('/index.php', '', $_SERVER['REQUEST_URI']);

   /**
    *    /blog/archives/205
    *    /blog/archives/tag/php
    *    /blog/tag/php
    *    /blog/archives/category/code/php
    *    /blog/category/code/php
    */
   if (strpos($_SERVER['REQUEST_URI'], '/archives/') === 0) {
       $_SERVER['REQUEST_URI'] = str_replace('/archives/', '/', $_SERVER['REQUEST_URI']);
   }

    /**
     *  对非静态化后缀的形式进行过滤检测:
     *     可能为: '/blog/205'
     */
    if (strpos($_SERVER['REQUEST_URI'], '.html') === false) {
        // '/205' => '/205.html'
        $_SERVER['REQUEST_URI'] = preg_replace('/^\/(\d+)/', '$0.html', $_SERVER['REQUEST_URI']);
    }

   /**
    * 检测 queryString 和 hash, 非空需特殊处理
    */
    if (strpos($_SERVER['REQUEST_URI'], '?') === 0 || strpos($_SERVER['REQUEST_URI'], '#') === 0) {
        $_SERVER['REQUEST_URI'] = '/index.php' . $_SERVER['REQUEST_URI'];
        $_SERVER['PATH_INFO'] = '';
    } else {
        $_SERVER['PATH_INFO'] = $_SERVER['REQUEST_URI'];
    }

    /**
     * 修正因 404 带来的 wordpress内置分页算法的链接错误问题
     * 比如:
     *   访问 http://www.zfkun.com/date/2010/01 时,上一页本来期望是http://www.zfkun.com/date/2010/01/page/2
     *   而实际,因为使用的404 rewrite技术,上一页链接却成了http://www.zfkun.com:80;/date/2010/01/page/3
     *   这是因为wp内置的分页算法直接使用了 $_SERVER['QUERY_STRING'] 和 $_SERVER["SCRIPT_NAME"] 来生成链接地址,
     *   当前因为是404状态下,所以 $_SERVER['QUERY_STRING'] = '404;http://www.zfkun.com:80/date/2010/01';
     * 注意:
     *   仅修改 $_SERVER['QUERY_STRING'] = '' 的话,并解决不了问题,因为当前执行脚本文件为/404.php 从而会导致
     *   生成的链接到  http://www.zfkun.com/404.php/date/2010/01 上去
     *   所以,必须还要重置 $_SERVER['SCRIPT_NAME'] = '/index.php' 从而让WP内置处理逻辑运行正常
     */
    $_SERVER['QUERY_STRING'] = '';
    $_SERVER["SCRIPT_NAME"] = '/index.php';

    // 启动博客主程序
...
} else {
// 真正的 404 处理
...
}
?>
  1. 必须地,后台->固定链接->自定义结构 更新值为 /%post_id%.html
    这里又发现一个让我很郁闷的问题,若自定义结构使用的形如 /archives/%post_id%.html 或之前的 /index.php/archives/%post_id%
    则, 分类 和 标签的 路由默认也会增加这个前缀 /archives/tag/* /archives/category/* 擦,之前历史遗留的2种兼容结构,就是因为这个问题导致的,无奈。

  2. 其余的乱七八糟的兼容,模糊了,回头想起来补记下

其实,做的工作远比现在记录的要多,只是让我印象深刻(那是好听的,其实我想说恶心的)的是这些。回头有时间继续更新好了。今天就先到这。

Avatar
zfkun 喜欢游戏、热爱技术、追求艺术、崇尚自由、渴望精彩、最爱唠叨