如何在PHP中重定向到同一页面,但没有特定参数?

如何在PHP中重定向到同一页面,但没有特定参数?,php,Php,假设我的访客到达: mydomain.com/nice url/?p1=a&p2=b 我希望将它们重定向到: mydomain.com/nice url/?p1=a (可能带有标题(“位置:) 所以我想去掉p2=b字符串 由于这只是一个示例,可能还有许多其他参数,我正在寻找最智能的解决方案,包括以下方法: 剥去以p2开头的任何内容 去除任何不以p1开头的内容 请记住,漂亮的url也可以是各种各样的东西,例如: 第一名,第二名,等等 另外,我不寻找.htaccess解决方案,因为我想在会话中存储剥

假设我的访客到达:

mydomain.com/nice url/?p1=a&p2=b

我希望将它们重定向到:

mydomain.com/nice url/?p1=a

(可能带有
标题(“位置:

所以我想去掉
p2=b
字符串

由于这只是一个示例,可能还有许多其他参数,我正在寻找最智能的解决方案,包括以下方法:

  • 剥去以
    p2开头的任何内容
  • 去除任何不以
    p1开头的内容
  • 请记住,
    漂亮的url
    也可以是各种各样的东西,例如:

    第一名
    第二名
    ,等等


    另外,我不寻找
    .htaccess
    解决方案,因为我想在会话中存储剥离参数的值。

    您可能需要这样的解决方案:

    if (count($_GET) > 1 || !$_GET['p1']) {
        header ("location: mydomain.com/nice-url/?p1=a");
    }
    

    我想这应该是可行的:使用$_SERVER[“REQUEST_URI”]获取原始url,使用parse_url/parse_str解析url,然后使用unset()删除您不需要的任何数据,然后使用http_build_query重建url,例如:

    <?php
    header('content-type: text/plain;charset=utf8');
    $urlinfo=parse_url($_SERVER["REQUEST_URI"]);
    var_dump($urlinfo);
    $query=isset($urlinfo['query'])?$urlinfo['query']:'';
    parse_str($query,$queryinfo);
    var_dump($queryinfo);
    unset($queryinfo['p2']);
    var_dump($queryinfo);
    $newurl=$urlinfo['path'].'?'.http_build_query($queryinfo);
    var_dump($newurl);
    
    其中301表示“永久移动”,302表示“临时移动”


    编辑2:302的含义稍微复杂一些,你可以在这里阅读更多的内容,你可以使用
    parse_url
    ()。这里有一种比hanshenrik发布的更通用的方式。它使用了注释中的
    unparse_url
    稍微修改(
    $query
    行被修剪为
    &
    )还有一些正则表达式:

    <?
    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);
    }
    
    function keep_only_query($url, $query_to_keep) {
      $parsed = parse_url($url);
      $parsed['query'] = preg_replace('/(^|&)(?!'.$query_to_keep.')[^&]*/', '', $parsed['query']);
      return unparse_url($parsed);
    }
    
    $url = 'mydomain.com/nice-url/?p1=a&p2=b';
    
    # or for request url
    # $url = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    
    # "Strip anything that starts with p2"
    var_dump(strip_query($url, 'p2'));
    # --> string(27) "mydomain.com/nice-url/?p1=a"
    
    # "Strip anything that doesn't start with p1"
    var_dump(keep_only_query($url, 'p1'));
    # --> string(27) "mydomain.com/nice-url/?p1=a"
    
    # redirect
    $new_url = strip_query($url, 'p2')); # or whatever query you want to strip/keep
    header("Location: $new_url");
    
    注意:与regex版本相反,这只适用于名称为的参数(例如
    p1
    p2
    ),而regex版本适用于名称为的参数(例如,
    p1=…
    p2=…
    ,但也有
    p1something=…
    p2_whatever=…
    )。从问题的措词来看,我不知道这是否是目的,但我首先是这样理解的:

  • 剥去任何以开头的
  • 当然,底部的版本也可以扩展以比较查询键的开头…使用regex;-)(或
    substr


    最后一个版本没有任何奇怪的正则表达式,但带有
    substr
    ,按照OP的意图检查键的开头

    function strip_query($url, $query_to_strip) {
      $len = strlen($query_to_strip);
      $parsed = parse_url($url);
      parse_str($parsed['query'], $query);
      foreach($query as $query_key => $query_val) {
        if(substr($query_key, 0, $len) == $query_to_strip) unset($query[$query_key]);
      }
      $parsed['query'] = http_build_query($query);
      return unparse_url($parsed);
    }
    
    function keep_only_query($url, $query_to_keep) {
      $len = strlen($query_to_keep);
      $parsed = parse_url($url);
      parse_str($parsed['query'], $query);
      foreach($query as $query_key => $query_val) {
        if(substr($query_key, 0, $len) != $query_to_keep) unset($query[$query_key]);
      }
      $parsed['query'] = http_build_query($query);
      return unparse_url($parsed);
    }
    

    parse_url
    然后构建,如果againI不知道如何成功地编写这样的代码:/no,代码需要完全动态,没有常量值,比如
    mydomain
    nice url
    但是为什么
    $url='mydomain.com/nice url/?p1=a&p2=b';
    ?我的想法是寻找一个独立的代码,一个也可以在
    yourdomain.com/另一个漂亮的url上使用的代码
    不涉及任何内容您想获取当前url吗?
    url=“http://$\u SERVER[http://$\u HOST]$\u SERVER[REQUEST\u URI]”;
    是的。虽然这段代码不起作用,但我得到了一个
    string(28)“tested domain.com/tested page.php?p1=a”字符串(28)tested domain.com/tested page.php?p1=a“
    error不确定您的意思。两个
    var\u dump
    都输出这些字符串。您只需要脚本中的函数,并在需要的地方使用它们。我添加了重定向头。尝试理解代码并使用它。这不是复制粘贴解决方案。我收到以下错误消息:
    array(2){[“path”]=>string(11)“/test.php”[“query”]=>string(4)“p2=a”}数组(1){[“p2”]=>string(1)“a”}数组(0){}字符串(12)“/test.php?”
    @rockyraw是的,这很有效,不是吗?GET中只有一个变量,即“p2”=>“a”…添加更多变量,您只会看到p2被删除
    function strip_query($url, $query_to_strip) {
      $parsed = parse_url($url);
      parse_str($parsed['query'], $query);
      unset($query[$query_to_strip]);
      $parsed['query'] = http_build_query($query);
      return unparse_url($parsed);
    }
    
    function keep_only_query($url, $query_to_keep) {
      $parsed = parse_url($url);
      parse_str($parsed['query'], $query);
      foreach($query as $query_key => $query_val) {
        if($query_key != $query_to_keep) unset($query[$query_key]);
      }
      $parsed['query'] = http_build_query($query);
      return unparse_url($parsed);
    }
    
    function strip_query($url, $query_to_strip) {
      $len = strlen($query_to_strip);
      $parsed = parse_url($url);
      parse_str($parsed['query'], $query);
      foreach($query as $query_key => $query_val) {
        if(substr($query_key, 0, $len) == $query_to_strip) unset($query[$query_key]);
      }
      $parsed['query'] = http_build_query($query);
      return unparse_url($parsed);
    }
    
    function keep_only_query($url, $query_to_keep) {
      $len = strlen($query_to_keep);
      $parsed = parse_url($url);
      parse_str($parsed['query'], $query);
      foreach($query as $query_key => $query_val) {
        if(substr($query_key, 0, $len) != $query_to_keep) unset($query[$query_key]);
      }
      $parsed['query'] = http_build_query($query);
      return unparse_url($parsed);
    }