如果没有参数,如何在URL中删除`?`?

时间:2015-12-08 21:56:47

标签: php

我有以下规则检查网址是否包含以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/

怎么做?

5 个答案:

答案 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)

这是删除查询参数的另一种方法:

  1. 解析URL以将其分隔为方案,路径和查询
  2. 将查询字符串解析为数组
  3. 取消设置数组
  4. 中的参数
  5. 重新创建网址
  6. 示例:

    <?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');
    

    Output

    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');
    

    Output

    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。

你比这个更好!