【问题标题】:Adding Mod Rewrite Rules Programmatically in WordPress Plugin在 WordPress 插件中以编程方式添加 Mod 重写规则
【发布时间】:2012-10-01 05:15:11
【问题描述】:

当用户更改永久链接设置时,以下示例插件将自定义 mod 重写规则添加到 .htaccess

/* Plugin Name: Sample Mod Rewrite  */

add_action('generate_rewrite_rules', array(new custom_mod_rewrite, "generate_rewrite_rules"));

class custom_mod_rewrite {
    function __construct() {
        $this->wp_rewrite = & $GLOBALS["wp_rewrite"];
    }
    function generate_rewrite_rules() {

        $non_wp_rules = array(
            'simple-redirect/?$plugin_name' => 'http://google.com',
            'one-more-redirect/?$plugin_name' => 'http://yahoo.com'
        );

        $this->wp_rewrite->non_wp_rules = $non_wp_rules + $this->wp_rewrite->non_wp_rules;
        add_filter('mod_rewrite_rules', array(&$this, "mod_rewrite_rules"));
    }
    function mod_rewrite_rules($rules) {
        return preg_replace('#^(RewriteRule \^.*/)\?\$plugin_name .*(http://.*) \[QSA,L\]#mi', '$1 $2 [R=301,L]', $rules);
    }
}

我发现这有两个问题。

  1. 如果设置为默认永久链接,则不会添加规则。
  2. 更重要的是,除非用户更改永久链接设置,否则不会添加规则。(可以在插件激活时执行$wp_rewrite->flush_rules() 解决)

对于#2,我想知道是否有一种以编程方式添加规则的好方法。

IIS(常见于 Windows 服务器)不支持 mod_rewrite。

来源:http://codex.wordpress.org/Using_Permalinks#Permalinks_without_mod_rewrite

听起来并非所有系统都使用.htaccess。所以直接编辑.htaccess文件可能不是分布式插件的最佳选择。我不知道。可能我必须检查服务器是否使用 Apache,如果是,我需要检查 .htacess 是否可写并且现有规则没有添加规则,最后我可以将规则附加到它。此外,当用户停用插件时,必须删除规则。所以有点麻烦。

如果 WordPress 可以使用内置 API 或其他东西处理它,我想把它留给 WordPress。但是上面的例子是我到目前为止所能找到的。所以我很感激你的信息。

更新

按照 pfefferle 的建议,我可以使用 $wp_rewrite->flush_rules()。但是,问题 #1 仍然存在;使用默认永久链接设置时,它不会生效。有什么想法吗?

/* Plugin Name: Sample Mod Rewrite  */

$custom_mod_rewrite = new custom_mod_rewrite;
register_activation_hook( __FILE__, array($custom_mod_rewrite, 'flush_rewrite_rules'));
register_deactivation_hook( __FILE__, array($custom_mod_rewrite, 'flush_rewrite_rules'));
add_action('generate_rewrite_rules', array($custom_mod_rewrite, "generate_rewrite_rules"));

class custom_mod_rewrite {
    function __construct() {
        $this->wp_rewrite = & $GLOBALS["wp_rewrite"];
    }
    function flush_rewrite_rules() {
        $this->wp_rewrite->flush_rules();
    }
    function generate_rewrite_rules() {

        $non_wp_rules = array(
            'simple-redirect/?$plugin_name' => 'http://google.com',
            'one-more-redirect/?$plugin_name' => 'http://yahoo.com'
        );

        $this->wp_rewrite->non_wp_rules = $non_wp_rules + $this->wp_rewrite->non_wp_rules;
        add_filter('mod_rewrite_rules', array(&$this, "mod_rewrite_rules"));
    }
    function mod_rewrite_rules($rules) {
        return preg_replace('#^(RewriteRule \^.*/)\?\$plugin_name .*(http://.*) \[QSA,L\]#mi', '$1 $2 [R=301,L]', $rules);
    }
}

此外,停用插件时,它不会变回以前的规则。我只是按照 codex 示例并将其设置为在停用插件时刷新规则。所以应该有一些代码来删除添加的规则。

作为旁注,根据the codex

刷新重写规则是一项昂贵的操作,......你应该在插件的激活钩子上刷新重写规则,或者当你知道需要更改重写规则时

剩余问题:

  1. 如果设置为默认永久链接,则不会添加规则。
  2. 停用插件时,它不会变回以前的规则。

【问题讨论】:

  • 请参阅一个当前活跃的、非常相似的问题:How can I rewrite a wordpress URL to use the first sub directory as a querystring? - 也许你们可以互相帮助或至少交换意见。
  • @hakre 似乎我无法理解那里提出的问题。我无法通过尝试发布的代码来重现 OP 的问题。什么都没发生。所以我宁愿不通过询问重现问题的方法来打扰 OP。
  • mini-answer:如果您使用默认的 (?p=) 永久链接,则 WordPress 无需任何 mod_rewrite URL 重写即可运行。这就是为什么当您切换到默认永久链接时这不起作用的原因。

标签: php mod-rewrite wordpress


【解决方案1】:

很遗憾,目前似乎没有有效的解决方案。

【讨论】:

    【解决方案2】:

    您可以使用 symfony 的路由系统,如下所述:http://pookey.co.uk/wordpress/archives/80-playing-with-symfony-routing-without-symfony

    您可以编写一个简单的插件来实现这个想法。

    编辑:已经有一个可以编辑 .htaccess 的插件。 http://plugins.svn.wordpress.org/wp-htaccess-editor/trunk/以它为例。

    注意:直接编辑 .htaccess 意味着 apache 用户对该文件具有写入权限,这可能很危险。但我想你已经知道了。 ;)

    【讨论】:

    • 有趣。该示例使用.htaccess,所以我想它需要编辑它。问题是我们如何在插件中编辑它。感谢您的意见。
    • 我在回复中添加了帮助链接。
    • 通过查看您介绍的插件WP Htaccess Editor,它可以让用户输入他们的规则。我宁愿希望有一种以编程方式而不是手动完成的方法。所以一个简化的代码示例会很好,它检查用户是否使用 Apache 和访问权限并将规则添加到 .htaccess 并在插件停用时删除规则。
    【解决方案3】:

    添加一些更改后,您必须“刷新”重写规则:http://codex.wordpress.org/Function_Reference/flush_rewrite_rules

    【讨论】:

    • 谢谢,我更新了问题。问题 #1 仍然存在。
    • 您必须在添加更改后刷新它。你现在要做的是 on_activation 和 on_deactivation 这意味着:你刷新规则,wordpress 重新生成它们,然后你改变它们。
    • 试试这个add_action('generate_rewrite_rules', array(&$custom_mod_rewrite, 'flush_rewrite_rules'));
    • 我注释掉了激活和停用钩子的行并在add_action('generate_rewrite_rules', array($custom_mod_rewrite, "generate_rewrite_rules"));之后插入了行现在它产生了错误,Fatal error: Maximum function nesting level of '100' reached, aborting!
    猜你喜欢
    • 2016-03-13
    • 2019-03-13
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 2010-11-13
    • 2012-05-13
    • 1970-01-01
    相关资源
    最近更新 更多