使用wp_reDirect和.htaccess重新路由搜索(并传递剩余的GET变量)

时间:2013-04-26 作者:Steve Dimock

我想用wp_redirect() 将搜索重定向到我在中建立的格式.htaccess. 不幸的是,我在做这件事时遇到了一些问题。

我需要将搜索重定向到一系列文件夹,然后将剩余参数附加到URL的末尾,最终结果如下所示:

http://www.xxxxxxx.com/search/Used/MT/Billings/?s=BMW&z=59105&r=150&m=150000&pmin=1000&pmax=30000&submit=Refine
到目前为止,我已经编写了此函数:

function redirect_search() {
    $var_status = var_status();
    $var_ci = var_ci();
    $var_st = var_st();
    if (is_search() && !empty($_GET[\'s\'])) {
        wp_redirect(home_url("/search/".$var_status.\'/\'.$var_ci.\'/\'.$var_st));
        exit();
    }
}
add_action(\'template_redirect\', \'redirect_search\' );
此函数导致url如下所示:http://www.xxxxxxx.com/search/New/Billings/MT

我在其中添加了参数,函数如下所示:

function redirect_search() {
    $var_status = var_status();
    $var_ci = var_ci();
    $var_st = var_st();
    $zip = var_z();
    $radius = var_r();
    if (is_search() && !empty($_GET[\'s\'])) {
        wp_redirect(home_url("/search/".$var_status.\'/\'.$var_ci.\'/\'.$var_st.\'/?s=\'.get_search_query().\'&z=\'.$zip.\'&r=\'.$radius.\'etc... etc...\'));
        exit();
    }
}
add_action(\'template_redirect\', \'redirect_search\' );
不幸的是,这种方法似乎会取消已创建的文件夹,结果url如下所示:

http://www.xxxxxxx.com/search/?s=BMW&z=59101
关于如何获取文件夹和其中的参数,有什么想法吗?谢谢

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

*haha* 这真的很有趣。你真的射中了自己的脚。

看看源代码link-template.php line 1922 表示:

if ( ! empty( $path ) && is_string( $path ) && strpos( $path, \'..\' ) === false )
最后一个条件strpos( $path, \'..\' ) 实际上与.\'etc... etc...\' 在您的示例中。这个$path 参数输入home_url() 检查是否包含任何.. 防止目录遍历攻击。这个$path param仅在不包含任何\'..\'. 只要去掉这个,你就会更进一步。

下一步是,任何包含/search/anything-else 在wordpress中被视为搜索结果页。默认模式为search/(.+)/?$ 您可以通过安装Rewrite analyzer 插件并仅筛选字符串search/anything-else.

因此,您需要确保url/search/Used/MT/Billings/ 实际上是在这里触发您的搜索逻辑,而不是wordpress搜索。否则,您的搜索url将以/search/test/test/test4/?s=asdasd&z=test&r=test 实际上会创建重定向循环,因为您使用的是permalink版本/search/term 连同$_GET 参数版本?s=term.

这并不是你的问题的一部分,而是你需要考虑的:即使重定向在第一部分中工作正常,wordpress可能会决定在重定向后的页面加载处重新格式化URL,因为它无法识别你的搜索URL结构,这就是为什么你需要确保在wordpress这样做之前在所有URL上执行你的逻辑。

例如,您可以使用添加自己的重写规则add_rewrite_rule(), 或钩住parse_request action(在我看来,这是处理自定义url参数的一个很好的操作)。当然,您也可以通过向添加一些自定义内容来处理此外部(在wordpress之前)。htacces甚至通过添加目录结构/search/Used/MT/Billings/index.php (这可能是最简单的方法,但我不建议以后通过执行wordpress更新来覆盖这个原因)。

根据你的最新评论,我真的相信你最好使用一些重写规则,这些规则在wordpress之前生效,而不是在wordpress核心/Relevansi上乱搞。我不会在插件中使用它,但它可能正好适合定制开发。

RewriteEngine On
RewriteRule ^search/(.*)/(.*)/(.*)/page/([1-9]) /page/$4/?status=$1&st=$2&ci=$3 [QSA]
RewriteRule ^search/(.*)/(.*)/(.*)/ /?status=$1&st=$2&ci=$3 [QSA]
该规则将在内部重写此URL:

/search/Used/MT/Billings/?s=BMW&z=59105&r=150&m=150000&pmin=1000&pmax=30000&submit=Refine
此URL(据我所知,Relevansi将需要此URL):

?status=Used&st=MT&ci=Billings&s=BMW&z=59105&r=150&m=150000&pmin=1000&pmax=30000&submit=Refine
您可能需要更换(.*) 使用一些更具体的正则表达式,关于查询变量的可能内容

结束