哈喽,各位代码界的弄潮儿们!今天咱们来扒一扒 WordPress 里面那个神秘又强大的家伙——WP_Rewrite
。它就像一个幕后大佬,默默地操纵着 WordPress 的 URL,让你的链接看起来更漂亮、更SEO友好。
咱们今天的目标是:深入了解 WP_Rewrite
类,搞清楚它是如何存储和管理 URL 重写规则的。准备好了吗?Let’s dive in!
第一幕:WP_Rewrite
是个啥?
简单来说,WP_Rewrite
的核心作用就是将 WordPress 内部的 URL(通常是 ?p=123
这种形式)转换成更友好的形式(比如 /2023/10/27/hello-world/
)。这种转换的过程就叫做 URL 重写。
想象一下,你是一个网站访客,更喜欢看到哪个链接?
https://example.com/?p=123
https://example.com/hello-world/
答案显而易见。漂亮的 URL 不仅更容易记忆,还能提高用户体验,对搜索引擎也更友好。
第二幕:WP_Rewrite
类的结构剖析
WP_Rewrite
类位于 wp-includes/class-wp-rewrite.php
文件中。咱们先来看看它的主要属性:
属性名称 | 作用 |
---|---|
$wp_rewrite |
WP_Rewrite 类的全局实例。 |
$permalink_structure |
Permalink 结构,就是你后台设置的 URL 格式,比如 /blog/%postname%/ 。 |
$use_verbose_rules |
是否使用详细的 rewrite 规则。启用后,会生成更易读(但可能更慢)的规则。 |
$rules |
存储 rewrite 规则的关联数组。键是正则表达式,值是替换字符串。 |
$rewritecode |
用于匹配查询变量的正则表达式代码。 |
$queryreplace |
用于替换查询变量的字符串。 |
$feeds |
内置的 feed 规则,比如 RSS、Atom。 |
$feed_permalink_structure |
Feed 的 Permalink 结构。 |
$search_base |
搜索页面的 URL 基础,默认为 /search/ 。 |
$comments_pagination_base |
评论分页的 URL 基础。 |
$maintags |
主标签,用于构建 URL。 |
$commentsmaintag |
评论的标签。 |
$paged_base |
分页的 URL 基础。 |
$author_base |
作者页面的 URL 基础。 |
$date_format |
日期格式,用于构建日期归档的 URL。 |
这些属性是 WP_Rewrite
类的核心组成部分,它们共同决定了 URL 重写的行为。
第三幕:Rewrite 规则的存储方式
WP_Rewrite
类使用 $rules
属性来存储 rewrite 规则。 $rules
是一个关联数组,它的键是正则表达式,值是替换字符串。
例如:
$this->rules = array(
'author/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?author_name=$matches[1]&paged=$matches[2]',
'author/([^/]+)/?$' => 'index.php?author_name=$matches[1]'
);
这个例子定义了两个 rewrite 规则:
-
'author/([^/]+)/page/?([0-9]{1,})/?$' => 'index.php?author_name=$matches[1]&paged=$matches[2]'
- 正则表达式:
'author/([^/]+)/page/?([0-9]{1,})/?$'
匹配类似/author/john/page/2/
这样的 URL。 - 替换字符串:
'index.php?author_name=$matches[1]&paged=$matches[2]'
将匹配到的 URL 转换成index.php?author_name=john&paged=2
这样的查询字符串。$matches[1]
和$matches[2]
分别代表正则表达式中第一个和第二个括号捕获的内容。
- 正则表达式:
-
'author/([^/]+)/?$' => 'index.php?author_name=$matches[1]'
- 正则表达式:
'author/([^/]+)/?$'
匹配类似/author/john/
这样的 URL。 - 替换字符串:
'index.php?author_name=$matches[1]'
将匹配到的 URL 转换成index.php?author_name=john
这样的查询字符串。
- 正则表达式:
这些规则会被添加到 .htaccess
文件(或者其他 web 服务器的配置文件)中,当用户访问匹配这些规则的 URL 时,web 服务器会根据规则将 URL 重写成对应的查询字符串,然后 WordPress 就可以根据查询字符串来显示正确的内容。
第四幕:Rewrite 规则的生成过程
WP_Rewrite
类在初始化时会生成一系列默认的 rewrite 规则,这些规则涵盖了文章、页面、分类、标签、作者、日期归档等常见的 WordPress 内容类型。
生成规则的过程主要分为以下几个步骤:
- 确定 Permalink 结构:
WP_Rewrite
类首先会根据$permalink_structure
属性确定 Permalink 的基本结构。这个属性的值可以在 WordPress 后台的“设置” -> “固定链接” 页面进行配置。 - 构建正则表达式:
WP_Rewrite
类会根据 Permalink 结构和各种参数(比如文章类型、分类法)构建正则表达式。这些正则表达式用于匹配各种类型的 URL。 - 生成替换字符串:
WP_Rewrite
类会根据正则表达式和查询变量生成替换字符串。替换字符串用于将匹配到的 URL 转换成对应的查询字符串。 - 添加到
$rules
数组:WP_Rewrite
类将生成的正则表达式和替换字符串添加到$rules
数组中。
咱们来看一个例子,了解如何生成文章的 rewrite 规则。假设 $permalink_structure
的值为 /%postname%/
:
// 假设文章的 post_name 为 'hello-world'
$post_name = 'hello-world';
// 构建正则表达式
$regex = '^' . preg_quote( $post_name, '^' ) . '/?$';
// 生成替换字符串
$replace = 'index.php?name=' . $post_name;
// 添加到 $rules 数组
$this->rules[$regex] = $replace;
这段代码会生成如下 rewrite 规则:
array(
'^hello-world/?$' => 'index.php?name=hello-world'
);
这个规则会将 /hello-world/
转换成 index.php?name=hello-world
。
第五幕:添加自定义 Rewrite 规则
WordPress 提供了 add_rewrite_rule()
函数,允许开发者添加自定义的 rewrite 规则。这个函数接受三个参数:
$regex
:正则表达式,用于匹配 URL。$redirect
:替换字符串,用于将匹配到的 URL 转换成对应的查询字符串。$priority
:规则的优先级,可选参数,默认为 ‘bottom’。
例如,假设你想添加一个规则,将 /books/([0-9]+)/
转换成 index.php?book_id=$matches[1]
:
function my_add_rewrite_rules() {
add_rewrite_rule(
'books/([0-9]+)/?',
'index.php?book_id=$matches[1]',
'top'
);
}
add_action( 'init', 'my_add_rewrite_rules' );
这段代码会在 WordPress 初始化时添加一个新的 rewrite 规则。注意,在添加或修改 rewrite 规则后,你需要刷新 Permalink,才能使新的规则生效。可以通过访问 WordPress 后台的“设置” -> “固定链接” 页面,然后点击“保存更改”按钮来刷新 Permalink。或者,你也可以使用 flush_rewrite_rules()
函数来刷新 Permalink。
function my_flush_rewrite_rules() {
flush_rewrite_rules();
}
add_action( 'after_switch_theme', 'my_flush_rewrite_rules' ); // 主题切换后刷新
add_action( 'admin_init', 'my_flush_rewrite_rules' ); // 后台初始化时刷新
第六幕:查询变量(Query Variables)
在 rewrite 规则中,我们经常需要使用查询变量来传递参数。查询变量是 URL 中 ?
后面的键值对,比如 ?p=123
中的 p
就是一个查询变量。
WordPress 使用 $wp_query->query_vars
属性来存储查询变量。你可以使用 get_query_var()
函数来获取查询变量的值,使用 set_query_var()
函数来设置查询变量的值。
在添加自定义 rewrite 规则时,你需要告诉 WordPress 你使用的查询变量,否则 WordPress 可能无法识别这些变量。可以使用 add_filter()
函数来添加自定义查询变量:
function my_add_query_vars( $vars ) {
$vars[] = 'book_id';
return $vars;
}
add_filter( 'query_vars', 'my_add_query_vars' );
这段代码会将 book_id
添加到 WordPress 的查询变量列表中。
第七幕:flush_rewrite_rules()
的作用
flush_rewrite_rules()
函数的作用是刷新 Permalink。它会重新生成 rewrite 规则,并将这些规则写入到 .htaccess
文件(或者其他 web 服务器的配置文件)中。
这个函数非常重要,因为当你添加、修改或删除 rewrite 规则后,你需要调用这个函数才能使新的规则生效。
flush_rewrite_rules()
函数的执行过程如下:
- 删除现有的 rewrite 规则:
flush_rewrite_rules()
函数会首先删除.htaccess
文件中现有的 rewrite 规则。 - 重新生成 rewrite 规则:
flush_rewrite_rules()
函数会重新调用WP_Rewrite
类的wp_rewrite_rules()
方法,生成新的 rewrite 规则。 - 写入 rewrite 规则到
.htaccess
文件:flush_rewrite_rules()
函数会将新的 rewrite 规则写入到.htaccess
文件中。
第八幕:.htaccess
文件
.htaccess
文件是 Apache Web 服务器的一个配置文件,它可以控制目录级别的配置。WordPress 使用 .htaccess
文件来存储 rewrite 规则。
.htaccess
文件位于 WordPress 的根目录下。你可以使用文本编辑器打开它,查看其中的内容。
一个典型的 .htaccess
文件可能包含以下内容:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# BEGIN WordPress
和 # END WordPress
之间的内容是 WordPress 管理的 rewrite 规则。不要手动修改这些内容,因为 WordPress 会自动更新它们。
第九幕:Rewrite 规则的优先级
当多个 rewrite 规则匹配同一个 URL 时,WordPress 会按照规则的优先级来选择执行哪个规则。规则的优先级由 add_rewrite_rule()
函数的 $priority
参数控制。
$priority
参数可以取两个值:
'top'
:规则的优先级最高,会优先执行。'bottom'
:规则的优先级最低,会最后执行。
默认情况下,add_rewrite_rule()
函数的 $priority
参数的值为 'bottom'
。
第十幕:一些注意事项
- 性能: 过多的 rewrite 规则会影响网站的性能,因为 web 服务器需要花费更多的时间来匹配 URL。因此,应该尽量减少 rewrite 规则的数量。
- 冲突: 自定义的 rewrite 规则可能会与 WordPress 的默认规则或其他插件的规则发生冲突。因此,在添加自定义规则时,应该仔细测试,确保没有冲突。
- 服务器配置: rewrite 功能需要 web 服务器的支持。如果你的 web 服务器没有启用 rewrite 模块,你需要手动启用它。
- 缓存: 一些缓存插件可能会缓存 rewrite 规则,导致新的规则无法生效。因此,在添加或修改 rewrite 规则后,应该清除缓存。
总结
WP_Rewrite
类是 WordPress URL 重写的核心。它负责生成、存储和管理 rewrite 规则,让你的 URL 看起来更漂亮、更 SEO 友好。掌握 WP_Rewrite
类的使用方法,可以让你更好地控制 WordPress 的 URL 结构,提升用户体验和搜索引擎排名。
希望今天的讲解对你有所帮助!下次有机会,咱们再一起探索 WordPress 的其他奥秘。 编码快乐!