我有以下规则检查网址是否包含以p2
开头的所有参数:
function unparse_url($parsed_url) {
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
$user = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$query = isset($parsed_url['query']) ? '?' . trim($parsed_url['query'], '&') : '';
$fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : '';
return "$scheme$user$pass$host$port$path$query$fragment";
}
function strip_query($url, $query_to_strip) {
$parsed = parse_url($url);
$parsed['query'] = preg_replace('/(^|&)'.$query_to_strip.'[^&]*/', '', $parsed['query']);
return unparse_url($parsed);
}
$url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$new_url = (strip_query($url, 'p2'));
# redirect if url contains anything that starts with p2
$filtered = array_filter(array_keys($_GET), function($k) {
return strpos($k, 'p2') === 0;
});
if ( !empty($filtered) ) {
header ("Location: $new_url");
}
else {
}
如果网址包含任何p2*
参数,则会在没有这些参数的情况下对同一网页进行重定向。
示例:
domain.com/?a=3&p2=1
将重定向到
domain.com/?a=3
但是,根据当前规则,如果原始网址为:
domain.com/?p2=1
然后它将重定向到:
domain.com/?
但由于它没有意义,我希望在这种情况下它会重定向到:
domain.com/
怎么做?
答案 0 :(得分:1)
与@dontfight一样,我建议使用mod_rewrite,但如果您更喜欢PHP,则可以在执行重定向之前使用rtrim
rtrim($url, '?');
使用您的代码可以像这样使用
$filtered = array_filter(array_keys($_GET), function($k) {
return strpos($k, 'p2') === 0;
});
$new_url_trim = rtrim($new_url, '?');
if ( !empty($filtered) ) {
header ("Location: $new_url_trim");
}
else {
}
答案 1 :(得分:1)
这是删除查询参数的另一种方法:
示例:
<?php
function removeQuery($url, $param) {
$parsed = parse_url($url);
parse_str($parsed['query'], $query);
unset($query[$param]);
$parsed['scheme'] .= '://';
$parsed['query'] = http_build_query($query);
if (!empty($parsed['query']))
$parsed['path'] .= '?';
return implode($parsed);
}
echo removeQuery('http://domain.com/?a=3&p2=1', 'a') . "\n";
echo removeQuery('http://domain.com/?a=3&p2=1', 'p2') . "\n";
echo removeQuery('http://domain.com/?p2=1', 'p2');
http://domain.com/?p2=1
http://domain.com/?a=3
http://domain.com/
另外我注意到你想删除p2
,如果它出现在字符串中的任何地方,那么这是另一个版本就是为了做到这一点:
<?php
function removeP2($url) {
$parsed = parse_url($url);
parse_str($parsed['query'], $query);
foreach ($query as $key => $value)
if (strpos($key, 'p2') === 0)
unset($query[$key]);
$parsed['scheme'] .= '://';
$parsed['query'] = http_build_query($query);
if (!empty($parsed['query']))
$parsed['path'] .= '?';
return implode($parsed);
}
echo removeP2('http://domain.com/?a=3&p2=1') . "\n";
echo removeP2('http://domain.com/?a=3&p2sks=1') . "\n";
echo removeP2('http://domain.com/?p2=1');
http://domain.com/?a=3
http://domain.com/?a=3
http://domain.com/
现在要让它重定向,你已经知道如何重定向:
header("Location: " . removeP2('http://' . $_SERVER[HTTP_HOST] . $_SERVER[REQUEST_URI]));
答案 2 :(得分:1)
因为没有人费心去告诉你什么是错的......
您的问题是,strip_query()
函数始终将$url["query"]
设置为值,即使该值为空字符串:
$parsed['query'] = preg_replace('/(^|&)'.$query_to_strip.'[^&]*/', '', $parsed['query']);
当您的unparse_url()
函数获取网址时,它会使用始终通过的isset()
检查该数组索引:
$query = isset($parsed_url['query']) ? '?' . trim($parsed_url['query'], '&') : '';
您可以使用isset()
而不是使用empty()
进行检查,如果值为,则会返回false;如果是空字符串,则返回:
$query = !empty($parsed_url['query']) ? '?' . trim($parsed_url['query'], '&') : '';
答案 3 :(得分:0)
如果mod_rewrite可用,则可以在没有php代码的情况下完成。
答案 4 :(得分:0)
这不是答案,而是评论,但有点长。
为什么你如此热衷于从URL中删除此变量?你有什么害处,你必须竭尽全力根除它的存在?为什么不呢......
unset($_GET['p2']);
但是因为它毫无意义,
以什么方式?
我可以在unparse_url($parsed_url)
函数中看到一些优点,如果你修复了错误(提示:尝试一些带有用户名和/或密码的测试用例),那么它的结构相当合理 - 但随后的代码用于操作数据是正则表达式字符串拼接的混乱 - 这不是处理这种结构化数据的正确方法 - PHP具有相应的功能。
但最糟糕的是注入另一个完整的RTT来解析URL。
你比这个更好!