WordPress如何“在幕后”看待重写规则?

时间:2015-11-06 作者:Camron

我正在和WordPress打交道,试图很好地掌握WordPress中使用的约定背后的思想。我遇到了一个问题,我的搜索结果无法解释我想弄明白什么。我试图查看“wp include/rewrite”的代码。php”,但出于某种原因,我似乎无法追踪到底发生了什么。所以我试着黑盒测试它,现在我很困惑。

向WordPress添加自定义路由时,可以使用add_rewrite_rule. 但不同于add_action / remove_actionadd_filter / remove_filter, 没有remove_rewrite_rule. 我在网上找到的所有东西都说只要使用flush_rewrite_rules.

这种“古怪”导致了一些flush_rewrite_rules 这反过来又引发了一种担忧,即可能有一种更好的“正确的”方法可以在插件中重写URL。我将描述我所做的让自己困惑的事情。

我创建了两个插件。第一个“plugin-x”添加重写规则“^plugin-x/?$”然后打电话flush_rewrite_rules 在插件激活挂钩中。第二个“plugin-y”只调用flush_rewrite_rules 在激活挂钩中。两个电话flush_rewrite_rules 在其停用挂钩中。

我希望“plugin-y”通过刷新plugin-x创建的规则来干扰“plugin-x”,这是基于我目前所看到的。激活“plugin-x”将重写规则放置到位,激活“plugin-y”将删除“plugin-x”创建的规则。

让我困惑的是flush_rewrite_rules 似乎在做两件不同的事情。如果之后没有呼叫add_rewrite_rule 在激活挂钩中,则从未实际将路由添加到数据库中。意味着flush_rewrite_rules 正在删除和重新加载之前保存现有规则。但那是怎么回事flush_rewrite_rules 从“plugin-y”调用,删除“plugin-x”创建的规则?

我能想到的唯一其他解释是add_rewrite_rules 正在将插入数据库的操作推迟到flush_rewrite_rules 调用,并在下次调用时将其标记为删除flush_rewrite_rules. 我认为情况并非如此,但我不知道该如何解释。

既然你不应该这样添加重写规则,我想看看add_rewrite_rule 在“init”操作中调用将显示在数据库中。所以我创建了第三个插件“plugin-z”,它调用add_rewrite_rule 在“init”操作中。重写规则显示在数据库中,无需调用flush_rewrite_rules, 并且对随后的呼叫有弹性flush_rewrite_rules.

所以我有两个问题

什么是flush_rewrite_rules 真的吗add_rewrite_rule 在“init”操作中,是否会在每次加载页面时导致额外的数据库调用插件-x

<?php
/**
 * Plugin Name: plugin-x
 * Description: create a rewrite rule on activation, and remove it on deactivation.
 */

register_activation_hook(__FILE__, \'plugin_x_activation_hook\');
register_deactivation_hook(__FILE__, \'plugin_x_deactivation_hook\');

function plugin_x_activation_hook()
{
    add_rewrite_rule(\'^plugin-x/?$\', \'index.php?plugin_x_custom_rewrite_rule=1\', \'top\');
    flush_rewrite_rules();
}

function plugin_x_deactivation_hook()
{
    flush_rewrite_rules();
}

/* necessary nonsense required to point the custom route at code within this plugin. */

// add custom query vars for rewrite rule to be associated with something custom
function plugin_x_query_vars($vars)
{
    $vars[] = \'plugin_x_custom_rewrite_rule\';
    return $vars;
}
add_filter(\'query_vars\', \'plugin_x_query_vars\', 0);

// add a request parser to search for custom query var
function plugin_x_parse_request()
{
    /** @global WP $wp */
    global $wp;

    if(array_key_exists(\'plugin_x_custom_rewrite_rule\', $wp->query_vars))
    {
        wp_die(\'plugin-x route active\', \'plugin-x\', array(\'response\' => 200));
    }
}
add_action(\'parse_request\', \'plugin_x_parse_request\', 0);
?>
插件-y

<?php
/**
* Plugin Name: plugin-y
* Description: call flush_rewrite_rules on activation and deactivation
*/

register_activation_hook(__FILE__, \'plugin_y_activation_hook\');
register_deactivation_hook(__FILE__, \'plugin_y_deactivation_hook\');

function plugin_y_activation_hook()
{
    flush_rewrite_rules();
}

function plugin_y_deactivation_hook()
{
    flush_rewrite_rules();
}
?>
插件-z

<?php
/**
 * Plugin Name: plugin-z
 * Description: create a rewrite rule in the \'init\' action, and remove it on deactivation.
 */

register_activation_hook(__FILE__, \'plugin_z_activation_hook\');
register_deactivation_hook(__FILE__, \'plugin_z_deactivation_hook\');

function plugin_z_activation_hook()
{
    // no-op
}

function plugin_z_deactivation_hook()
{
    flush_rewrite_rules();
}

function plugin_z_init()
{
    add_rewrite_rule(\'^plugin-z/?$\', \'index.php?plugin_z_custom_rewrite_rule=1\', \'top\');
}
add_action(\'init\', \'plugin_z_init\');

/* necessary nonsense required to point the custom route at code within this plugin. */

// add custom query vars for rewrite rule to be associated with something custom
function plugin_z_query_vars($vars)
{
    $vars[] = \'plugin_z_custom_rewrite_rule\';
    return $vars;
}
add_filter(\'query_vars\', \'plugin_z_query_vars\', 0);

// add a request parser to search for custom query var
function plugin_z_parse_request()
{
    /** @global WP $wp */
    global $wp;

    if(array_key_exists(\'plugin_z_custom_rewrite_rule\', $wp->query_vars))
    {
        wp_die(\'plugin-z route active\', \'plugin-z\', array(\'response\' => 200));
    }
}
add_action(\'parse_request\', \'plugin_z_parse_request\', 0);
?>

1 个回复
最合适的回答,由SO网友:Milo 整理而成

刷新重写规则删除存储重写规则的选项,然后调用重新生成规则的方法并将其保存回选项中。如果此选项不为空,则将始终从该选项加载重写规则。这是因为重新生成规则可能是一项代价高昂的操作,因此只能在发生更改时执行。

在上添加规则init 不会导致额外的数据库查询,实际上这是添加重写规则的正确方法,也是确保规则始终存在的唯一方法。添加规则的代价只是一些简单的字符串和数组操作代码,这些代码将您的规则添加到在请求生命周期内存储在重写类中的数组中。如果其他内容刷新了规则,而您的规则没有添加到init上,它们将消失。如果存储规则的选项为空,则重新填充时规则将来自此数组。

相关推荐