自定义重写规则删除查询字符串

时间:2020-07-22 作者:appshine

我正在尝试(但失败)使用重写规则将更短/更漂亮的URL重定向到正确的页面,并在查询字符串中包含值。

WP安装在https://example.com, 该插件创建了一个名为“foo”的页面,该页面使用在查询字符串中传递的值“bar”从自定义数据库表生成内容。

因此,完整URL示例如下:

https://example.com/foo/?bar=XXXXXX

“bar”值始终是一个由6到8个字母数字字符组成的字符串,其中至少有1个破折号(-)。

我想使用重写规则(但我愿意接受其他建议),以便可以使用较短的URL,例如:

https://example.com/f/XXXXXX

我尝试使用add\\u rewrite\\u规则,如下所示:

function jr_rewrite_add_rewrites(){
    add_rewrite_rule(
            \'f\\/([[:ascii:]]+)\\/?$\', 
            \'/index.php?pagename=foo&bar=$matches[1]\',
            \'top\'
        );
}

add_action( \'init\', \'jr_rewrite_add_rewrites\');
而且,当我通过单击仪表板中Permalinks设置页面上的保存刷新重写规则时,该规则会很好地添加到htaccess文件中:

# BEGIN WordPress
# The directives (lines) between `BEGIN WordPress` and `END WordPress` are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\\.php$ - [L]
RewriteRule ^f\\/([[:ascii:]]+)\\/?$ /index.php?pagename=foo&bar=$matches[1] [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
但是,当我尝试访问时:

https://example.com/f/XXXXXX

页面仅重定向到:

https://example.com/foo/

缺少所需的bar=XXXXXX查询字符串,因此无法加载相关内容。

有谁能指出我的错误在哪里,或者提出一个替代方案?

2 个回复
SO网友:mozboz

该答案分为两部分:

您当前的示例出现了多个问题,其中一些问题是由于Wordpress的规则使事情变得更加复杂造成的。如果您不介意编辑您的。直接访问htaccess文件,请尝试此操作。它避免了处理一些无法让事情变得更简单的Wordpress魔术。它应该做你想做的事,或者离得足够近,你可以调整它来做你想做的事:

    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteRule ^f/(.{6-8})$ foo/?bar=$1 [NC,L]
    </IfModule>
您需要删除插件代码,删除其中的行。htaccess(虽然我想这应该会自动发生),并添加above Wordpress部分

注意,这不是重定向。浏览器中的URL不会更改,但PHP看到的“幕后”URL将被重写。

如果您有兴趣尝试使用add_rewrite_rule() 有一些事情需要解决。这里有一个更新的尝试,尽管我无法轻松测试:

    add_rewrite_rule(
            \'^f/(.{6-8})$\', 
            \'index.php?pagename=foo&bar=$matches[1]\',
            \'top\'
        );
不要转义,删除索引中的前导项。php(这可能就是为什么它作为一个规则添加到.htaccess中,而不是在Wordpress中运行,而Wordpress本身应该是这样的)
  • 删除不必要的内容/. (任何字符)。您可以这样做,例如[a-zA-Z0-9],如果您想限制这些字符,因为它们是明确的pagename=foo 是获取此URL的正确方法。我不确定这是否是索引的方式。php可以工作,所以你需要检查一下。

  • SO网友:appshine

    除了上面mozboz有用的建议之外,我还能够使用Wordpress的重写功能,通过使用add_rewrite_tag() 识别bar变量get_query_var() 访问值而不是尝试访问$_GET[\'bar\'].

    所以我最终得到的代码是:

    function foobar_rewrite_rules(){
            add_rewrite_tag(
                \'%bar%\',
                \'(.{6})\'
            );
    
            add_rewrite_rule(
                \'^f/(.{6-8})$\',
                \'index.php?pagename=foo&bar=$matches[1]\',
                \'top\'
            );
    }
    
    add_action( \'init\', \'foobar_rewrite_rules\');
    
    然后,因为页面需要使用“pretty”URL还是完整页面地址和查询字符串的“丑陋”URL,所以我只需在$\\u GET版本和GET\\u query\\u var()版本之间进行检查和选择,如下所示:

    $bar_value = (empty($_GET[\'bar\'])) ? (get_query_var(\'bar\', FALSE)) : ($_GET[\'bar\']) ;
    
    很高兴能完成这项工作,谢谢你的帮助!