'init' 动作挂钩上的 $wp_rewrite->flush_rules() 有多糟糕?
How bad is $wp_rewrite->flush_rules() on 'init' action hook?
根据the Codex:
[...] This function can be extremely costly in terms of performance. It should be used as sparingly as possible - such as during activation or deactivation of plugins or themes. Every attempt should be made to avoid using it in hooks that execute on each page load, such as init.
好的,所以,我知道它不应该在每个页面加载中使用,我也不是,但我仍然需要在这个项目上有一个非常有条件的重写规则。
我有这 2 个 url 结构:
- example.com/products/tables/fancy-computer-table //This is a product url, here I expect the normal behavior from wp.
- example.com/products/tables/office //This should be some kind of a filter, where the site gets all the tables related to the office department. Note how both URL structure matches.
为了让它发挥作用,我使用一些正则表达式将其缩小到这些非常具体的 URL。如果匹配,我将 运行 2 个查询来验证我所在的 url 是否适用于我希望应用该规则的过滤器,或者它是否是产品 url。在后者中,我希望 wordpress 正常运行。但是我必须以任何一种方式刷新规则,无论是产品还是类别和过滤器,以便两个页面都能正常和动态地工作。
我做这一切是为了尽可能减少此功能的使用范围,但 Codex 并没有真正告诉我它对性能的影响有多严重,或者为什么。
顺便说一句,我将该函数的参数作为 false 传递,因此它不会重写我的 htaccess 文件,但我不确定 rewrite 规则在哪里option 已存储,如果它在某处的内存中或在数据库中,希望他们能对此提供一些说明。
提前感谢您阅读这个问题。在这里感谢任何指点,即使你想指出我做这件事的其他方式。 :)
编辑:在这里发布一些代码,这样你们就可以真正理解我的意思,如果这可能是不好的做法,请告诉我...也许是关于如何做的建议做得更好。
<?php function custom_rewrite_products()
{
// regex to match either "products/tables/fancy-computer-table" or "products/tables/office"
preg_match('#products\/([^\/]+)\/([^\/]+)\/?#', $_SERVER['REQUEST_URI'], $url_matches);
if(is_array($url_matches)) {
$query_category = new WP_Query('category_name='.$url_matches[1]);
$query_category->get_posts();
$args = array(
'post_type' => 'filters',
'name' => $url_matches[2]
);
$query_post = new WP_Query($args);
$query_post->get_posts();
if($query_category->have_posts() && $query_post->have_posts()) {
$category_ID = '';
$filter = '';
$category_ID = '' . $query_category->query_vars['cat'] . '';
$filter = '' . $query_post->query_vars['name'] . '';
$string = "index.php?cat={$category_ID}&filter={$filter}";
add_rewrite_rule('products/([^/]+)/([^/]+)/?$', $string, 'top');
}
global $wp_rewrite;
//Call flush_rules() as a method of the $wp_rewrite object
$wp_rewrite->flush_rules(false);
}
}
add_action('init', 'custom_rewrite_products');
我仍然不明白为什么,但是这里需要刷新,所以 $category_ID
和 $filter
变量实际上被传递给了重写规则。如果我把它拿出来,重写只会转到索引页,值应该为空的地方。
如果你想知道,我在自定义 post 类型上创建了过滤器,它们通过使用自定义字段与每个 post 相关,因为它们有四个或五个并且存在在这个项目的每个类别上。如您所见,我已经有了一个 category/subcategory 结构,但我发现在每个主要类别中再次手动创建这些过滤器并不明智。
'wp_options' table 中有一条 'rewrite_rules' 记录,其中包含所有重写规则。调用 flush_rules() 时,WordPress 将清除此记录并重新生成所有新规则,包括您未更改的规则。
根据the Codex:
[...] This function can be extremely costly in terms of performance. It should be used as sparingly as possible - such as during activation or deactivation of plugins or themes. Every attempt should be made to avoid using it in hooks that execute on each page load, such as init.
好的,所以,我知道它不应该在每个页面加载中使用,我也不是,但我仍然需要在这个项目上有一个非常有条件的重写规则。 我有这 2 个 url 结构:
- example.com/products/tables/fancy-computer-table //This is a product url, here I expect the normal behavior from wp.
- example.com/products/tables/office //This should be some kind of a filter, where the site gets all the tables related to the office department. Note how both URL structure matches.
为了让它发挥作用,我使用一些正则表达式将其缩小到这些非常具体的 URL。如果匹配,我将 运行 2 个查询来验证我所在的 url 是否适用于我希望应用该规则的过滤器,或者它是否是产品 url。在后者中,我希望 wordpress 正常运行。但是我必须以任何一种方式刷新规则,无论是产品还是类别和过滤器,以便两个页面都能正常和动态地工作。
我做这一切是为了尽可能减少此功能的使用范围,但 Codex 并没有真正告诉我它对性能的影响有多严重,或者为什么。 顺便说一句,我将该函数的参数作为 false 传递,因此它不会重写我的 htaccess 文件,但我不确定 rewrite 规则在哪里option 已存储,如果它在某处的内存中或在数据库中,希望他们能对此提供一些说明。
提前感谢您阅读这个问题。在这里感谢任何指点,即使你想指出我做这件事的其他方式。 :)
编辑:在这里发布一些代码,这样你们就可以真正理解我的意思,如果这可能是不好的做法,请告诉我...也许是关于如何做的建议做得更好。
<?php function custom_rewrite_products()
{
// regex to match either "products/tables/fancy-computer-table" or "products/tables/office"
preg_match('#products\/([^\/]+)\/([^\/]+)\/?#', $_SERVER['REQUEST_URI'], $url_matches);
if(is_array($url_matches)) {
$query_category = new WP_Query('category_name='.$url_matches[1]);
$query_category->get_posts();
$args = array(
'post_type' => 'filters',
'name' => $url_matches[2]
);
$query_post = new WP_Query($args);
$query_post->get_posts();
if($query_category->have_posts() && $query_post->have_posts()) {
$category_ID = '';
$filter = '';
$category_ID = '' . $query_category->query_vars['cat'] . '';
$filter = '' . $query_post->query_vars['name'] . '';
$string = "index.php?cat={$category_ID}&filter={$filter}";
add_rewrite_rule('products/([^/]+)/([^/]+)/?$', $string, 'top');
}
global $wp_rewrite;
//Call flush_rules() as a method of the $wp_rewrite object
$wp_rewrite->flush_rules(false);
}
}
add_action('init', 'custom_rewrite_products');
我仍然不明白为什么,但是这里需要刷新,所以 $category_ID
和 $filter
变量实际上被传递给了重写规则。如果我把它拿出来,重写只会转到索引页,值应该为空的地方。
如果你想知道,我在自定义 post 类型上创建了过滤器,它们通过使用自定义字段与每个 post 相关,因为它们有四个或五个并且存在在这个项目的每个类别上。如您所见,我已经有了一个 category/subcategory 结构,但我发现在每个主要类别中再次手动创建这些过滤器并不明智。
'wp_options' table 中有一条 'rewrite_rules' 记录,其中包含所有重写规则。调用 flush_rules() 时,WordPress 将清除此记录并重新生成所有新规则,包括您未更改的规则。