<?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>Keep on Fighting! &#187; $_SERVER</title>
	<atom:link href="http://yihui.name/cn/tag/_server/feed/" rel="self" type="application/rss+xml" />
	<link>http://yihui.name/cn</link>
	<description>谢益辉</description>
	<lastBuildDate>Mon, 06 Sep 2010 07:59:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>PHP的301重定向（从Bo-Blog搬家到WordPress的后续工作）</title>
		<link>http://yihui.name/cn/2009/05/php-301-redirect-from-bo-blog-to-wordpress/</link>
		<comments>http://yihui.name/cn/2009/05/php-301-redirect-from-bo-blog-to-wordpress/#comments</comments>
		<pubDate>Sun, 24 May 2009 09:18:39 +0000</pubDate>
		<dc:creator>谢益辉</dc:creator>
				<category><![CDATA[网站和网页]]></category>
		<category><![CDATA[$_SERVER]]></category>
		<category><![CDATA[301重定向]]></category>
		<category><![CDATA[404错误]]></category>
		<category><![CDATA[Bo-Blog]]></category>
		<category><![CDATA[header()]]></category>
		<category><![CDATA[mail()]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[str_replace()]]></category>
		<category><![CDATA[urlencode()]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[搬家]]></category>

		<guid isPermaLink="false">http://yihui.name/cn/?p=963</guid>
		<description><![CDATA[客搬家之后不可避免会产生一大堆404错误，绝大部分原链接都失效了，不过好在动态网站系统的网址都是有规律的，因此把原来的网址重新定向也很容易，这里简单记录从Bo-Blog搬家到Wordpress的一些301重定向工作。PHP代码写得非常拙劣，各位看官见笑了，写出来为了将来要用到PHP的时候能找找自己以前写的例子。 1、RSS Feed：feed.php 对现代网民来说，RSS阅读器已经是看网页的必备工具，因此RSS种子的地址几乎是众多网址中最重要的一个。 Bo-Blog的feed.php文件在不带参数的时候是博客正文的RSS，带参数go的时候可能是评论，也可能是分类目录的RSS，因此需要在WP根目录下建一个feed.php文件，里面对参数作简单的判断，把原来的RSS重定向到WP的RSS中。以下代码只是本博客的转向，具体怎么写要根据具体搬家结果分析。 &#60;?php header("HTTP/1.1 301 Moved Permanently"); if(!isset($_REQUEST["go"])){ header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=rss2"); } else { $tmp = $_REQUEST["go"]; if ($tmp == 'comment') { header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=comments-rss2"); } else if (stripos($tmp, '_')) { $tmp = end(explode('_', $tmp)); if ($tmp == '2') { header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=rss2"); } else { header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=rss2&#38;cat=".$tmp); } } } ?&#62; 2、博客阅读页面：read.php 由于在Bo-Blog系统中我使用了链接地址优化（Rewrite），而搜索引擎收录的既有优化地址，也有动态地址，因此要判断一下地址究竟是哪种类型，然后把参数提取出来，传给WP。含有htm的地址是优化的地址，从中提取.htm之前的数字传给WP的p参数就可以到新的页面地址了。 &#60;?php [...]]]></description>
			<content:encoded><![CDATA[<a href="http://yihui.name/cn/2009/05/php-301-redirect-from-bo-blog-to-wordpress/"><span class="dropcap">博</span></a>客搬家之后不可避免会产生一大堆404错误，绝大部分原链接都失效了，不过好在动态网站系统的网址都是有规律的，因此把原来的网址重新定向也很容易，这里简单记录从Bo-Blog搬家到Wordpress的一些301重定向工作。PHP代码写得非常拙劣，各位看官见笑了，写出来为了将来要用到PHP的时候能找找自己以前写的例子。</p>
<h1>1、RSS Feed：<code>feed.php</code></h1>
<p>对现代网民来说，RSS阅读器已经是看网页的必备工具，因此RSS种子的地址几乎是众多网址中最重要的一个。</p>
<p><span class="attention">插播不重要的通知：<br />
1、本站的RSS地址已经更改为：<em><a title="谢益辉中文博客RSS地址" href="http://yihui.name/cn/feed/">http://yihui.name/cn/feed/</a></em>，评论RSS为：<em><a title="谢益辉中文博客评论RSS地址" href="http://yihui.name/cn/comments/feed/">http://yihui.name/cn/comments/feed/</a></em>，请Google Reader中的读者即时更换。英文博客也类似，把cn改成en就可以了。<br />
2、如果你懒得换也行，反正我已经重定向了。 <img src='http://yihui.name/cn/wp-content/plugins/tango-smilies/tango/face-smile-big.png' alt=':grin:' class='wp-smiley' /><br />
</span>
<p>Bo-Blog的<code>feed.php</code>文件在不带参数的时候是博客正文的RSS，带参数<code>go</code>的时候可能是评论，也可能是分类目录的RSS，因此需要在WP根目录下建一个<code>feed.php</code>文件，里面对参数作简单的判断，把原来的RSS重定向到WP的RSS中。以下代码只是本博客的转向，具体怎么写要根据具体搬家结果分析。</p>
<span class="notice">我的博客搬家过程中，分类数字2不知为何被搬家程序略过了，因此当分类数字为2的时候特殊处理，否则从原来的<code>go</code>参数中提取分类数字，传给WP的<code>cat</code>参数。</span>
<pre>&lt;?php
header("HTTP/1.1 301 Moved Permanently");

if(!isset($_REQUEST["go"])){
	header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=rss2");
} else {
	$tmp = $_REQUEST["go"];
	if ($tmp == 'comment') {
		header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=comments-rss2");
	} else if (stripos($tmp, '_')) {
		$tmp = end(explode('_', $tmp));
		if ($tmp == '2') {
			header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=rss2");
		} else {
			header("Location: http://$_SERVER[HTTP_HOST]/cn/?feed=rss2&amp;cat=".$tmp);
		}
	}
}
?&gt;</pre>
<p><span id="more-963"></span></p>
<h1>2、博客阅读页面：<code>read.php</code></h1>
<p>由于在Bo-Blog系统中我使用了链接地址优化（Rewrite），而搜索引擎收录的既有优化地址，也有动态地址，因此要判断一下地址究竟是哪种类型，然后把参数提取出来，传给WP。含有htm的地址是优化的地址，从中提取<code>.htm</code>之前的数字传给WP的<code>p</code>参数就可以到新的页面地址了。</p>
<span class="notice">英文博客搬家过程中，日志的数字ID和新系统对不上，那些ID&gt;2的日志都被<code>+=1</code>了，所以中间对英文日志ID作了特殊处理。变量<code>$prefix</code>用来判断是中文还是英文站。</span>
<pre>&lt;?php
header("HTTP/1.1 301 Moved Permanently");

$info = ($_SERVER["REQUEST_URI"]) ? $_SERVER["REQUEST_URI"] : $_ENV["REQUEST_URI"];
$prefix = substr($info, 1, 2);
$entry = array_keys($_REQUEST);

if(strpos($info, 'htm')) {
	$tmp = pathinfo($info, PATHINFO_FILENAME);
	if ($prefix == 'en') {
		if ($tmp &gt; 2) {
			$tmp += 1;
		}
	}
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?p=".$tmp);
} else {
	if(count($entry) &gt; 0) {
		$tmp = $entry[0];
		if (stripos($tmp, '_')) {
			$tmp = end(explode('_', $tmp));
		}
		if ($prefix == 'en') {
			if ($tmp &gt; 2) {
				$tmp += 1;
			}
		}
		header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?p=".$tmp);
	} else {
		header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
	}
}
?&gt;</pre>
<h1>3、标签页面：<code>tag.php</code></h1>
<p>我觉得如果没有标签的话，这世上的网页会减少一半。用<code>site:</code>命令在Google中一看就知道，一个小破站，却有几千个页面被搜索引擎收录，而真正的日志不过上百篇而已，那多出来的页面几乎都是各种导航页面，其中就包括标签导航。鉴于标签这么重要，原来的<code>tag.php</code>自然要加上、改写一下了。</p>
<span class="notice">在我原来的系统中，由于标签是空格分隔，导致我只好以下划线_把一些英文字句连起来，现在WP中是以逗号分隔，而且标签有别名（空格被替换为-），因此原来的标签中，下划线要被替换为-，所以用到了<code>str_replace()</code>函数。在重定向之前要严重注意<code>tag</code>参数已经被解码了，因此需要重新编码！（即：<code>urlencode()</code>）</span>
<pre>&lt;?php
header("HTTP/1.1 301 Moved Permanently");

if(!isset($_REQUEST["tag"])){
	header("Location: http://$_SERVER[HTTP_HOST]/cn/");
} else {
	header("Location: http://$_SERVER[HTTP_HOST]/cn/?tag=" .
		urlencode(str_replace('_','-',$_REQUEST["tag"])));
}
?&gt;</pre>
<h1>4、其它页面的重定向</h1>
<p>我喜欢WP系统的一个重要原因就是它的各个文件分工非常明确，模板系统也是如此，所有的模板系统中都可以用一个<code>404.php</code>来出来404错误。除了上面三个重定向之外，大约还剩下70%的页面重定向没有完成（不要惊愕于这个工作的复杂性），如：按日期的归档、精华文章、评论页面、分类显示、附件下载和登录页面等等。由于这些页面一般都是被搜索引擎以静态地址收录的，所以不能像前面那样写PHP文件完成重定向，只能根据网址来逐个判断，把原地址转向新地址。其中有无数的细节要注意，如原来的星标日志对应新系统中的featured分类文章、两个系统的分类ID的对应关系等。综上，这个<code>404.php</code>便极度冗长。</p>
<span class="notice">怎么知道你的网站是否有404错误呢？在WP中，只需要在<code>404.php</code>文件中用<code>mail()</code>函数往你的邮箱发报告就可以了。我将不能成功重定向的页面都发到<code>404@yihui.name</code>了，看看<code>$_SERVER</code>变量，大概就知道是哪一页出错了，以及是活人点的链接还是搜索引擎的蜘蛛人在看我的页面。</span>
<pre>&lt;?php
$info = $_SERVER['REQUEST_URI'];
$prefix = substr($info, 1, 2);

if (strpos($info, '/index')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
} else if (strpos($info, '/post/')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = current(explode('_', pathinfo($info, PATHINFO_FILENAME)));
	if ($prefix == 'en') {
		if ($tmp &gt; 2) {
			$tmp += 1;
		}
	}
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?p=".$tmp);
} else if (strpos($info, '/star')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = $prefix=='cn' ? 618 : 150;
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?cat=".$tmp);
} else if (strpos($info, '/view')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?feed=comments-rss2");
} else if (strpos($info, '/category')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = explode('_', pathinfo($info, PATHINFO_FILENAME));
	if ($prefix == 'cn') {
		if (count($tmp) &gt; 1) {
			if ($tmp[1] == '2') {
				header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
			} else {
				header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?cat=" .
				    $tmp[1]);
			}
		} else {
			header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
		}
	} else {
		$catmap = array('7' =&gt; 6, '8' =&gt; 7, '9' =&gt; 9, '0' =&gt; 117, '1' =&gt; 11, '2' =&gt; 147,
                                          '6' =&gt; 12, '10' =&gt; 148, '3' =&gt; 4, '4' =&gt; 8, '5' =&gt; 10);
		if (count($tmp) &gt; 1) {
			if (array_search($tmp[1], array_keys($catmap)) !== false) {
				header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?cat=" .
				    $catmap[$tmp[1]]);
			} else {
				header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
			}
		} else {
			header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
		}
	}
} else if (strpos($info, '/archive')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = explode('_', pathinfo($info, PATHINFO_FILENAME));
	if (count($tmp) &gt; 2) {
		if (strlen($tmp[1]) == 1) {
			$tmp[1] = '0'.$tmp[1];
		}
		if ($tmp[2] &lt; 2007 || $tmp[2] &gt; 2009) {
			header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
		} else {
			header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?m=".$tmp[2].$tmp[1]);
		}
	} else {
		header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
	}
} else if (strpos($info, '/showday')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = explode('_', pathinfo($info, PATHINFO_FILENAME));
	if (count($tmp) &gt; 3) {
		if (strlen($tmp[2]) == 1) {
			$tmp[2] = '0'.$tmp[2];
		}
		if (strlen($tmp[3]) == 1) {
			$tmp[3] = '0'.$tmp[3];
		}
		if ($tmp[2] &lt; 2007 || $tmp[2] &gt; 2009) {
			header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
		} else {
			header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?m=".$tmp[1] .
				$tmp[2].$tmp[3]);
		}
	} else {
		header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
	}
} else if (strpos($info, '/attachment')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = pathinfo(urldecode($info), PATHINFO_BASENAME);
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/wp-content/uploads/".$tmp);
} else if (strpos($info, '?tag=')) {
	header("HTTP/1.1 301 Moved Permanently");
	$tmp = '';
	if (isset($_REQUEST["tag"])) {
		$tmp = $_REQUEST["tag"];
	}
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?tag=".$tmp);
} else if ($info == '/'.$prefix.'/tag/') {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
} else if (strpos($info, 'read.php')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/?p=" .
		pathinfo($info, PATHINFO_FILENAME));
} else if (strpos($info, 'links.php')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
} else if (strpos($info, 'cv_yihui')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/cv/cv_yihui_".$prefix.".htm");
} else if (strpos($info, 'visit.php')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
} else if (strpos($info, 'securitycode.php')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
} else if (strpos($info, 'login.php')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/wp-login.php");
}

else {

//if(array_search($ext, array('gif', 'js', 'png', 'jpg', 'jpeg', 'css')) !== false) {
if (strpos($info, '/images/js') || strpos($info, '/images/lightbox')
		|| strpos($info, '/images/arrows') || strpos($info, '/template/fighting/')
		|| strpos($info, '/emot/thumbnail/') || strpos($info, '/editor/ubb/')
		|| strpos($info, '/images/r.css') || strpos($info, '/images/others')
		|| strpos($info, '/images/weather') || strpos($info, '/images/weather')
		|| strpos($info, 'jslang.js')) {
	header("HTTP/1.1 301 Moved Permanently");
	header("Location: http://$_SERVER[HTTP_HOST]/".$prefix."/");
} else {
	mail('404@yihui.name',
			"Invalid link: " . urldecode($info),
			'Request page: http://yihui.name' . $info . PHP_EOL .
			 'Referer: ' . $_SERVER['HTTP_REFERER']. PHP_EOL .
			  print_r($_SERVER, true),
			"From: Yihui Xie &lt;xie@yihui.name&gt;");
}

?&gt;

&lt;?php get_header(); ?&gt;

&lt;div id="wrapper"&gt;

	&lt;div id="home_content"&gt;

		&lt;div class="post"&gt;
		  &lt;p&gt;Sorry, I'm changing my blog system now; if the page you are looking for
		  doesn't exist, please visit
		  &lt;a href="http://yihui.name/&lt;?php echo $prefix; ?&gt;/"&gt;http://yihui.name/
		  &lt;?php echo $prefix; ?&gt;/&lt;/a&gt;.
		  I'll fix the original links soon. Thanks!&lt;/p&gt;
		  &lt;p&gt;&lt;img src="&lt;?php bloginfo('template_directory'); ?&gt;/images/mal.jpg"
		  alt="a questioning duck" class="errorduck" /&gt;
	          &lt;/p&gt;
		&lt;/div&gt;

		&lt;div class="main_meta"&gt;
			&lt;ul&gt;
				&lt;li&gt;Mal the Error Duck says, "Uh oh! 404! That means the page you are
				looking for doesn't exist, at least not anymore."&lt;/li&gt;
			&lt;/ul&gt;
    &lt;h2&gt;Latest &lt;?php print(isset($getOptions["num_posts"])?$getOptions["num_posts"]:"10"); ?&gt;
        articles&lt;/h2&gt;
	&lt;ul&gt;
			&lt;?php get_archives('postbypost',
				isset($getOptions["num_posts"]) ? $getOptions["num_posts"]:10,
				'', '&lt;li&gt;', '&lt;/li&gt;'); ?&gt;
	&lt;/ul&gt;
		&lt;/div&gt;

    &lt;/div&gt;

&lt;/div&gt;

&lt;?php get_footer(); ?&gt;

&lt;?php } ?&gt;</pre>
<p>然后就每天看看邮件报告，有没有出现新的404错误，能解决的话就在上面的代码中加上一条<code>if</code>语句。</p>
<p>看看，搬个家容易嘛我。</p>
<h2  class="related_post_title">爷还想看：</h2><ul class="related_post"><li>2009/05/10 -- <a href="http://yihui.name/cn/2009/05/turning-to-wordpress/" title="我也想转WP啊……">我也想转WP啊……</a> (19)</li><li>2010/04/24 -- <a href="http://yihui.name/cn/2010/04/conditional-captcha-stops-spam-comments/" title="Conditional CAPTCHA：进一步阻拦垃圾评论">Conditional CAPTCHA：进一步阻拦垃圾评论</a> (15)</li><li>2010/02/02 -- <a href="http://yihui.name/cn/2010/02/a-big-thank-you-to-linlin-yan/" title="特别致谢颜林林对COS的贡献">特别致谢颜林林对COS的贡献</a> (6)</li><li>2009/06/10 -- <a href="http://yihui.name/cn/2009/06/creating-tag-cloud-using-r-and-flash-javascript/" title="用R语言和Flash以及JavaScript生成标签云">用R语言和Flash以及JavaScript生成标签云</a> (7)</li><li>2009/05/30 -- <a href="http://yihui.name/cn/2009/05/visualize-simple-data-with-google-chart-api/" title="用Google Chart API展示简单的数据以及WordPress示例">用Google Chart API展示简单的数据以及WordPress示例</a> (5)</li></ul>]]></content:encoded>
			<wfw:commentRss>http://yihui.name/cn/2009/05/php-301-redirect-from-bo-blog-to-wordpress/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
