WordPress+WP-SuperCache之中文tag的Permalink问题全解析

Linux, PHP, 技术心得 Add comments

  WordPress的中文支持有问题,特别是在使用Permalink的时候,这个大家都知道。本文将分析其中的原因和网上流传的多种解决方案,并给出一个具体的解决结论。
  这个问题主要表现为,在默认情况下,Wordpress对于形如这样的链接(链接1):
  

www.example.com/tag/中文

  不能正常访问,会产生404或500错误,或者其他的错误。
  而对于这样的链接(链接2):
  

www.example.com/?tag=中文

  WordPress就能够正确解析。

  原因:参见这篇文章和这篇文章,这是URL编码问题造成的。对于上面的链接1,这是一个PathInfo,对于链接2,这是一个QueryString。事实证明,对于UTF-8的页面,IE和FF都会正确发送PathInfo和QueryString(而不像有些文章中说的,他们在不同的设置下会有错误的反应),但服务器端,IIS会将PathInfo转换成GBK编码从而造成错误,于是Windows下的此类问题只需要转回来就行了;但是Linux下,Apache不支持中文PathInfo,要么通过这篇文章中的方法来对Apache进行改造,要么只能像我一样,Linux主机无法使用中文permalink。于是,我们只能寻找绕路的方法。

  解决方案分析:
  一、转换编码(参见这篇文章
  原理是,IIS会将PathInfo中的UTF-8转换成GBK,而QueryString中就不会转换,故而为了使用Permalink,采用以下方法:
  打开wp-includesclasses.php文件,找到第44行和第50行:

if ( isset($_SERVER['PATH_INFO']) )
  $pathinfo = $_SERVER['PATH_INFO'];
else
  $pathinfo = '';
$pathinfo_array = explode('?', $pathinfo);
$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
$req_uri = $_SERVER['REQUEST_URI'];

改为

if ( isset($_SERVER['PATH_INFO']) )
  $pathinfo = mb_convert_encoding($_SERVER['PATH_INFO'], "UTF-8", "GBK");
else
  $pathinfo = '';
$pathinfo_array = explode('?', $pathinfo);
$pathinfo = str_replace("%", "%25", $pathinfo_array[0]);
$req_uri = mb_convert_encoding($_SERVER['REQUEST_URI'], "UTF-8", "GBK");

  局限:只对Windows主机、且必须是Windows下的IIS主机有效。

  二、修改rewrite.php(参见这篇文章
  这是网上最常见的方法,原理是,让WordPress在对其他内容使用Permalink的时候,对tag不使用,而使用链接2的QueryString模式发送中文编码:

1
2
3
4
5
6
7
8
function get_tag_permastruct() {
if (isset($this->tag_structure)) {
return $this->tag_structure;
}
if (empty($this->permalink_structure)) { //-----this line need change------
$this->tag_structure = ”;
return false;
}

把第4行改为

if (!empty($this->permalink_structure)) {

  局限:没有起到Permalink的“漂亮”作用,如果不能自己修改WP的文件就没办法了。

  三、修改tag base(参见这篇文章,经过我研究改造)
  原理同上,只要让WordPress在打开了Permalink功能后继续对tag不理不问就行了。那么,欺骗WordPress,让它用链接2的格式来显示Permalink,可行么?可行,因为WordPress可以自定义Permalink的形式:
  在WordPress的 Settings - Permalinks - Tag base 中填上
  

/?tag=

  注意”"不能少,引用原文中的写法不对。另外要注意每次输入”",WP都会再次转义为”\”,所以每次点提交都会把”"翻一倍,点两次就是”\\”,所以不要多点,一次就对了。
  这个方法的结果是使得链接变成这个样子
  

www.example.com/?tag=/中文/

  多出来的斜杠对于服务器丝毫没有影响,还是被视为QueryString,效果同上。
  局限是链接变得更加不好看了,更为致命的是插件生成的Sitemap中,tag链接会变成错误的形式,如果你很在乎Sitemap,请不要使用这个方法,除非你真的无法修改自己的rewrite.php文件。

  但是当你使用WP-SuperCache或者类似的缓存插件时,它会加入自己的rewrite规则,所有请求先由自己判断,不在缓存中或者不符合缓存规则才交由WordPress处理。但问题在于,它不支持中文URL的解析,哪怕是QueryString也不行。于是我们必须绕过它。
  这是WP-SuperCache在.htaccess文件里所添加的rewrite规则

RewriteEngine On
RewriteBase /
 
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{QUERY_STRING} !.*wp-subscription-manager=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html.gz [L]
 
RewriteCond %{REQUEST_METHOD} !=POST
RewriteCond %{QUERY_STRING} !.*s=.*
RewriteCond %{QUERY_STRING} !.*p=.*
RewriteCond %{QUERY_STRING} !.*wp-subscription-manager=.*
RewriteCond %{QUERY_STRING} !.*attachment_id=.*
RewriteCond %{HTTP_COOKIE} !^.*(comment_author_|wordpress|wp-postpass_).*$
RewriteCond %{DOCUMENT_ROOT}/wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html -f
RewriteRule ^(.*) /wp-content/cache/supercache/%{HTTP_HOST}/$1/index.html [L]

  我们要做的就是不让它去判断中文tag链接,在两个 RewriteCond %{REQUEST_METHOD} !=POST 后面分别加入这样一句:

RewriteCond %{QUERY_STRING} !.*tag=.*

  含义是如果QueryString中含有tag字样,请不要解析(交给下一条规则,一般来说就是WordPress的index.php了)。

  结论:
  Windows+IIS主机下,通过方案一可以完美解决中文tag问题
  Linux+Apache主机下,不能使用中文Permalink,除非修改Apache,否则只有用方案二和方案三绕行。
  方案二是较为推荐的方法,但是搭配WP-SuperCache使用的时候,需要自己在.htaccess文件中加入一条不处理tag链接的规则。

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="">


LilyStudio & WordPress & N.Design Studio
Entries RSS Comments RSS Log in