探究 WordPress `WP_Rewrite` 类源码:URL 重写规则的存储与管理。

哈喽,各位代码界的弄潮儿们!今天咱们来扒一扒 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 规则:

  1. '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] 分别代表正则表达式中第一个和第二个括号捕获的内容。
  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 内容类型。

生成规则的过程主要分为以下几个步骤:

  1. 确定 Permalink 结构: WP_Rewrite 类首先会根据 $permalink_structure 属性确定 Permalink 的基本结构。这个属性的值可以在 WordPress 后台的“设置” -> “固定链接” 页面进行配置。
  2. 构建正则表达式: WP_Rewrite 类会根据 Permalink 结构和各种参数(比如文章类型、分类法)构建正则表达式。这些正则表达式用于匹配各种类型的 URL。
  3. 生成替换字符串: WP_Rewrite 类会根据正则表达式和查询变量生成替换字符串。替换字符串用于将匹配到的 URL 转换成对应的查询字符串。
  4. 添加到 $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() 函数的执行过程如下:

  1. 删除现有的 rewrite 规则: flush_rewrite_rules() 函数会首先删除 .htaccess 文件中现有的 rewrite 规则。
  2. 重新生成 rewrite 规则: flush_rewrite_rules() 函数会重新调用 WP_Rewrite 类的 wp_rewrite_rules() 方法,生成新的 rewrite 规则。
  3. 写入 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 的其他奥秘。 编码快乐!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注