各位观众,大家好!今天咱们来聊聊 WordPress 里面一个挺神秘,但又非常重要的家伙—— WP_Rewrite
类。说它神秘,是因为很多人用了 WordPress 很久,都没直接跟它打过交道。说它重要,是因为它负责管理 WordPress 的 URL 重写规则,也就是让你的网站链接看起来更漂亮、更 SEO 友好。
一、WP_Rewrite
类:URL 重写的幕后英雄
想象一下,没有 WP_Rewrite
,你的文章链接可能长这样:/?p=123
。这玩意儿机器能看懂,但人看着就觉得…嗯…不够优雅。有了 WP_Rewrite
,你可以把链接变成这样:/my-awesome-article/
,是不是瞬间高大上了?
WP_Rewrite
类的主要作用就是:
- 定义重写规则: 它存储了一系列规则,告诉 WordPress 如何把丑陋的内部 URL 转换成漂亮的外部 URL。
- 解析 URL: 当用户访问一个漂亮的 URL 时,它会解析这个 URL,找到对应的 WordPress 内容。
- 生成 URL: 在 WordPress 生成链接时,它会根据规则生成对应的漂亮 URL。
二、WP_Rewrite
的核心属性:规则在哪里?
WP_Rewrite
类有很多属性,但最核心的几个是:
$rewritecode
:这是一个数组,存储了用于替换的标签。比如%postname%
,%category%
等。$rewritereplace
:这是一个数组,存储了与$rewritecode
对应的替换值。$rules
:这是一个关键数组,存储了最终的重写规则。每个规则都是一个键值对,键是正则表达式(用于匹配 URL),值是查询字符串(告诉 WordPress 要加载什么内容)。$permalink_structure
:存储了永久链接的结构。比如/blog/%postname%/
。$endpoints
:存储了额外的 URL 终结点,比如feed
,trackback
,comments
等。
这些属性都是 protected
级别的,意味着你不能直接从类的外部访问它们。你需要通过类提供的方法来操作这些属性。
三、WP_Rewrite
的核心方法:规则如何生效?
接下来,咱们来看看 WP_Rewrite
类的一些核心方法:
-
__construct()
: 构造函数,负责初始化各种属性,并加载现有的重写规则。public function __construct() { // 初始化 $this->rewritecode = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%postname%', '%post_id%', '%category%', '%tag%', '%author%', '%pagename%', '%search%', '%feed%', '%comment_feed%', '%trackback%', '%author_name%', '%category_name%', '%tag_id%', '%category_nicename%', '%tag_slug%', '%year%/%monthnum%', '%postname%/', '%post_id%/', '%page%'); $this->rewritereplace = array('([0-9]{4})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([0-9]{1,2})', '([^/]+)', '([0-9]+)', '([^/]+)', '([^/]+)', '([^/]+)', '([^/]+)', '(.+)', '(feed|rdf|rss|rss2|atom)', '(feed|rdf|rss|rss2|atom)', '(trackback)', '([^/]+)', '([^/]+)', '([0-9]+)', '([^/]+)', '([^/]+)', '([0-9]{4})/([0-9]{1,2})', '([^/]+)/', '([0-9]+)/', '([0-9]+)'); // 加载已有的重写规则 $this->rules = (array) get_option('rewrite_rules'); // 其他初始化代码... }
-
wp_rewrite_rules()
: 这个方法是 WordPress 加载重写规则的关键。它会调用WP_Rewrite
实例的wp_rewrite_rules()
方法,从而将规则添加到 WordPress 的 URL 解析过程中。function wp_rewrite_rules() { global $wp_rewrite; if ( ! isset( $wp_rewrite ) ) { $wp_rewrite = new WP_Rewrite(); } return $wp_rewrite->wp_rewrite_rules(); }
-
wp_rewrite_rules()
(WP_Rewrite 类中的版本): 这个方法才是真正干活的。它会根据当前的永久链接结构和其它设置,生成一系列重写规则,并将它们存储到$rules
属性中。public function wp_rewrite_rules() { // 省略大量代码... // 这里会根据permalink_structure, category_base, tag_base等生成规则 // 例如: // 'blog/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/?$' => 'index.php?year=$1&monthnum=$2&day=$3&name=$4' // 省略大量代码... return $this->rules; }
-
generate_rewrite_rules()
: 这个方法根据给定的参数(比如文章的链接结构、分类的链接结构等),生成相应的重写规则。public function generate_rewrite_rules( $permalink_structure, $ep_mask, $paged = true, $feed = true, $forcomments = false, $walk_dirs = true, $endpoints = true ) { // 省略大量代码... // 根据传入的参数,生成各种重写规则 // 省略大量代码... return $rewrite_rules; }
-
rewrite_rules()
: 这个方法返回$rules
属性,也就是存储重写规则的数组。public function rewrite_rules() { return $this->rules; }
-
flush_rules()
: 这个方法用于刷新重写规则。当你修改了永久链接结构或者其它与 URL 重写相关的设置时,你需要调用这个方法来更新重写规则。它会先删除旧的规则,然后重新生成新的规则,并将它们保存到数据库中。这个函数非常重要,因为如果你不刷新规则,你的新链接结构可能无法正常工作。public function flush_rules( $hard = true ) { global $wpdb; if ( ! is_network_admin() && ! is_super_admin() && current_filter() !== 'wp_loaded' ) { /** This action is documented in wp-includes/rewrite.php */ do_action( 'flush_rewrite_rules', $hard ); return; } /** This action is documented in wp-includes/rewrite.php */ do_action( 'flush_rewrite_rules', $hard ); if ( $hard ) { $this->init(); // Remove rules. delete_option( 'rewrite_rules' ); $this->wp_rewrite_rules(); $this->add_rewrite_rules(); $this->rewrite_rules_filter(); // Update rules. update_option( 'rewrite_rules', $this->rules ); // Update the .htaccess file. $this->mod_rewrite_rules(); // Flush rules is sometimes called from plugins/themes // during admin screens. Prevent redirect loops. if ( ! is_admin() ) { redirect_guess_404_permalink(); } } else { $this->add_rewrite_rules(); $this->rewrite_rules_filter(); update_option( 'rewrite_rules', $this->rules ); } }
-
add_rule()
: 这个方法用于添加自定义的重写规则。你可以使用它来创建自己的 URL 结构。public function add_rule( $regex, $redirect, $after = 'bottom' ) { if ( 'bottom' === $after ) { $this->rules[ $regex ] = $redirect; } else { $new_rules = array( $regex => $redirect ); $this->rules = $new_rules + $this->rules; } }
四、WP_Rewrite
的工作流程:从 URL 到内容
当用户访问你的 WordPress 网站时,WP_Rewrite
类会参与到 URL 解析的过程中。具体流程如下:
- 用户访问 URL: 用户在浏览器中输入一个 URL,比如
/my-awesome-article/
。 - WordPress 接收请求: WordPress 接收到用户的请求。
WP_Rewrite
解析 URL:WP_Rewrite
类会遍历$rules
数组中的正则表达式,尝试匹配用户访问的 URL。- 找到匹配的规则: 如果找到了匹配的规则,
WP_Rewrite
类会提取出正则表达式中的参数。 - 生成查询字符串:
WP_Rewrite
类会根据匹配的规则和提取出的参数,生成一个查询字符串,比如index.php?name=my-awesome-article
。 - WordPress 加载内容: WordPress 会根据查询字符串,加载对应的内容(比如文章、页面等)。
- 返回响应: WordPress 将加载的内容返回给用户。
五、WP_Rewrite
的实际应用:修改永久链接结构
最常见的 WP_Rewrite
应用场景就是修改 WordPress 的永久链接结构。你可以在 WordPress 后台的“设置”->“固定链接”页面中选择不同的永久链接结构。
当你选择了一个新的永久链接结构后,WordPress 会自动调用 WP_Rewrite
类的 flush_rules()
方法来刷新重写规则。
六、WP_Rewrite
的高级用法:自定义重写规则
除了修改永久链接结构,你还可以使用 WP_Rewrite
类来创建自己的重写规则。这可以让你实现一些更高级的 URL 结构。
比如,你可以创建一个规则,将 /products/iphone/
转换成 index.php?product=iphone
。
add_action( 'init', 'my_custom_rewrite_rules' );
function my_custom_rewrite_rules() {
global $wp_rewrite;
// 添加重写规则
$wp_rewrite->add_rule(
'products/([^/]+)/?',
'index.php?product=$matches[1]',
'top'
);
// 刷新重写规则 (注意: 仅在第一次添加规则时需要)
$wp_rewrite->flush_rules();
}
add_filter( 'query_vars', 'my_custom_query_vars' );
function my_custom_query_vars( $query_vars ) {
// 添加 query variable
$query_vars[] = 'product';
return $query_vars;
}
这段代码做了以下几件事:
add_action( 'init', 'my_custom_rewrite_rules' )
: 在 WordPress 初始化时,执行my_custom_rewrite_rules()
函数。my_custom_rewrite_rules()
: 这个函数负责添加自定义的重写规则。$wp_rewrite->add_rule( 'products/([^/]+)/?', 'index.php?product=$matches[1]', 'top' )
: 添加一个重写规则,将products/iphone/
转换成index.php?product=iphone
。$wp_rewrite->flush_rules()
: 刷新重写规则。注意: 刷新重写规则是一个耗时的操作,所以只需要在第一次添加规则时执行一次。
add_filter( 'query_vars', 'my_custom_query_vars' )
: 在 WordPress 查询变量被过滤时,执行my_custom_query_vars()
函数。my_custom_query_vars()
: 这个函数负责添加自定义的查询变量。$query_vars[] = 'product'
: 添加一个名为product
的查询变量。
七、WP_Rewrite
的注意事项:坑在哪里?
在使用 WP_Rewrite
类时,需要注意以下几点:
- 刷新重写规则: 当你修改了永久链接结构或者添加了自定义的重写规则后,一定要刷新重写规则。否则,你的修改可能不会生效。
- 正则表达式: 重写规则中的正则表达式需要写正确。否则,你的规则可能无法匹配到正确的 URL。
- 查询变量: 如果你在重写规则中使用了自定义的查询变量,你需要将这些变量添加到 WordPress 的查询变量列表中。
- 性能: 过多的重写规则会影响网站的性能。所以,尽量只添加必要的规则。
八、WP_Rewrite
的调试技巧:如何排查问题?
当你的重写规则没有生效时,你可以使用以下技巧来调试问题:
- 检查
.htaccess
文件: 如果你的服务器支持.htaccess
文件,你可以检查这个文件是否包含了正确的重写规则。 - 使用
var_dump()
或print_r()
: 你可以使用var_dump()
或print_r()
函数来输出$wp_rewrite->rules
数组,查看是否包含了你添加的规则。 - 使用插件: 有一些 WordPress 插件可以帮助你调试重写规则。
九、总结:WP_Rewrite
的价值
WP_Rewrite
类是 WordPress 中一个非常重要的组件。它负责管理 URL 重写规则,让你的网站链接更漂亮、更 SEO 友好。通过理解 WP_Rewrite
类的工作原理,你可以更好地控制 WordPress 的 URL 结构,从而提升网站的用户体验和搜索引擎排名。
特性 | 描述 |
---|---|
URL 美化 | 将丑陋的 URL (例如 /?p=123 ) 转换为更具可读性和 SEO 友好的 URL (例如 /my-awesome-article/ )。 |
规则存储 | 使用 $rules 数组存储重写规则,其中键是正则表达式,值是查询字符串。 |
规则生成 | 使用 generate_rewrite_rules() 方法根据永久链接结构和其他设置生成规则。 |
规则刷新 | 使用 flush_rules() 方法刷新重写规则,这在修改永久链接结构或添加自定义规则后是必要的。 |
自定义规则 | 使用 add_rule() 方法添加自定义重写规则,允许创建符合特定需求的 URL 结构。 |
URL 解析 | 当用户访问一个 URL 时,WP_Rewrite 会解析该 URL,并将其转换为 WordPress 可以理解的查询字符串。 |
性能考虑 | 过多的重写规则会影响网站性能,因此应谨慎添加规则。 |
调试技巧 | 可以检查 .htaccess 文件、输出 $wp_rewrite->rules 数组或使用插件来调试重写规则。 |
核心方法 | __construct() , wp_rewrite_rules() , generate_rewrite_rules() , rewrite_rules() , flush_rules() , add_rule() 等。 |
核心属性 | $rewritecode , $rewritereplace , $rules , $permalink_structure , $endpoints 等。 |
希望今天的讲座对大家有所帮助!如果大家有什么问题,欢迎提问。下次再见!