【问题标题】:How to remove the querystring and get only the url?如何删除查询字符串并仅获取 url?
【发布时间】:2011-10-21 15:06:37
【问题描述】:

我正在使用 PHP 来构建当前页面的 URL。有时,格式为

的 URL
www.mydomian.com/myurl.html?unwantedthngs

被请求。我想删除 ? 和它后面的所有内容(查询字符串),这样生成的 URL 就变成了:

www.mydomain.com/myurl.html

我当前的代码是这样的:

<?php
function curPageURL() {
    $pageURL = 'http';
    if ($_SERVER["HTTPS"] == "on") {
        $pageURL .= "s";
    }
    $pageURL .= "://";
    if ($_SERVER["SERVER_PORT"] != "80") {
        $pageURL .= $_SERVER["SERVER_NAME"] . ":" .
            $_SERVER["SERVER_PORT"] . $_SERVER["REQUEST_URI"];
    } else {
        $pageURL .= $_SERVER["SERVER_NAME"] . $_SERVER["REQUEST_URI"];
    }
    return $pageURL;
}
?>

【问题讨论】:

  • 顺便说一句,这就是所谓的“查询字符串”。

标签: php query-string


【解决方案1】:

您可以在?第一次出现之前使用strtok获取字符串

$url = strtok($_SERVER["REQUEST_URI"], '?');

strtok() 表示直接提取查询字符串中? 之前的子字符串的最简洁技术。 explode() 不太直接,因为它必须生成一个潜在的二元素数组,必须通过该数组访问第一个元素。

当查询字符串丢失或可能改变 url 中的其他/非预期子字符串时,其他一些技术可能会中断 -- 应避免使用这些技术。

demonstration:

$urls = [
    'www.example.com/myurl.html?unwantedthngs#hastag',
    'www.example.com/myurl.html'
];

foreach ($urls as $url) {
    var_export(['strtok: ', strtok($url, '?')]);
    echo "\n";
    var_export(['strstr/true: ', strstr($url, '?', true)]); // not reliable
    echo "\n";
    var_export(['explode/2: ', explode('?', $url, 2)[0]]);  // limit allows func to stop searching after first encounter
    echo "\n";
    var_export(['substr/strrpos: ', substr($url, 0, strrpos( $url, "?"))]);  // not reliable; still not with strpos()
    echo "\n---\n";
}

输出:

array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => 'www.example.com/myurl.html',
)
---
array (
  0 => 'strtok: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'strstr/true: ',
  1 => false,                       // bad news
)
array (
  0 => 'explode/2: ',
  1 => 'www.example.com/myurl.html',
)
array (
  0 => 'substr/strrpos: ',
  1 => '',                          // bad news
)
---

【讨论】:

  • +1 用于直接使用 $_SERVER 而不是重建 url 只是为了再次解析它。为了简洁起见,如果可能的话,会再给一个 +1。
  • 糟糕——将这些参数反转为explode(),分隔符先行。 array_shift(explode('?',$_SERVER["REQUEST_URI"]))
  • 它不返回 bool(false) 如果?不存在于字符串中,它返回字符串。
  • 太棒了!.. 即使? 不存在,它仍在返回网址。
  • @sepehr,我只是看不出不使用完全符合您需要的函数并使用另一个函数并解析它的结果(即在爆炸后得到 [0])(当然,除非有一个特定的原因,比如更好的性能、缺乏不必要的依赖等)。
【解决方案2】:

假设您仍想获取不带查询参数的 URL(如果未设置),只需使用简写 if 语句检查 strpos

$request_uri = strpos( $_SERVER['REQUEST_URI'], '?' ) !== false ? strtok( $_SERVER["REQUEST_URI"], '?' ) : $_SERVER['REQUEST_URI'];

【讨论】:

    【解决方案3】:

    您可以像这样使用 parse_url 内置函数:

    $baseUrl = $_SERVER['SERVER_NAME'] . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
    

    【讨论】:

      【解决方案4】:

      也可以按照php manual comment 使用关注

      $_SERVER['REDIRECT_URL']
      

      请注意,这仅适用于某些 PHP 环境,请按照该页面的以下评论获取更多信息;

      Purpose:当前PHP文件的URL路径名,path-info为N/A 并且不包括 URL 查询字符串。包括前导斜杠。

      警告:这是在 URL 重写之前(即,它与原来的一样) 调用 URL)。

      警告:并非在所有 PHP 环境中都设置,绝对只有在 URL 重写。

      在网络模式下工作:是

      在 CLI 模式下工作:否

      【讨论】:

        【解决方案5】:

        最简单的方法

        $url = 'https://www.youtube.com/embed/ROipDjNYK4k?rel=0&autoplay=1';
        $url_arr = parse_url($url);
        $query = $url_arr['query'];
        print $url = str_replace(array($query,'?'), '', $url);
        
        //output
        https://www.youtube.com/embed/ROipDjNYK4k
        

        【讨论】:

        • 我不同意这是最简单的方法。不,粗体字不会使您的陈述更具说服力。这个答案缺乏解释。
        • @mickmackusa 您能否详细说明您的评论?我需要在哪里解释我的答案?我会感激你的。
        • Stackoverflow 上的所有答案都应该包括对解决方案如何工作以及为什么您认为它是一种理想技术的解释。也欢迎提供文档链接。我完全理解您的解决方案,但其他研究人员可能不会。仅代码答案在 Stackoverflow 上的价值很低,因为它们对教育/授权成千上万的未来研究人员几乎没有作用。关于不是最简单的——3v4l.org/RE0GD 将是您的答案的一个更简单的版本,因为它声明的变量更少,并且只替换一个而不是两个。公认的答案是最简单的。
        • 另一个区别是接受的答案也会处理可能的片段,但你的不会。 3v4l.org/ERr4V 或更糟的是,它可能会破坏查询字符串左侧的 URL 3v4l.org/L61q1
        【解决方案6】:

        您至少需要 PHP 5.4 版才能实现此解决方案,而不会在一行中分解为变量并在下一行连接,但简单的一行是:

        $_SERVER["HTTP_HOST"].explode('?', $_SERVER["REQUEST_URI"], 2)[0];
        

        服务器变量:http://php.net/manual/en/reserved.variables.server.php
        数组解引用:https://wiki.php.net/rfc/functionarraydereferencing

        【讨论】:

          【解决方案7】:

          试试这个:

          $urrl=$_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME']
          

          $urrl=$_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']
          

          【讨论】:

          • 抱歉,这是错误的 - URI 可以由 htaccess 重写 - 这将导致返回脚本名称而不是当前 URI。
          • 很危险,因为它可以被欺骗。
          • 确认错误。假设您正在编写 proxy.php,它是 .htaccess 重定向到对各种资源(如 index.php、price.php、about.php)的请求,并为请求的名称动态构建视图。如果你使用它,脚本将始终看到 proxy.php 而不是它想要构建的所需资源。
          【解决方案8】:

          使用PHP Manual - parse_url() 获取您需要的部件。

          编辑(@Navi Gamage 的示例用法)

          你可以这样使用它:

          <?php
          function reconstruct_url($url){    
              $url_parts = parse_url($url);
              $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . $url_parts['path'];
          
              return $constructed_url;
          }
          
          ?>
          

          编辑(第二个完整示例):

          更新功能以确保附加方案并且不会出现任何通知消息:

          function reconstruct_url($url){    
              $url_parts = parse_url($url);
              $constructed_url = $url_parts['scheme'] . '://' . $url_parts['host'] . (isset($url_parts['path'])?$url_parts['path']:'');
          
              return $constructed_url;
          }
          
          
          $test = array(
              'http://www.mydomian.com/myurl.html?unwan=abc',
              'http://www.mydomian.com/myurl.html',
              'http://www.mydomian.com',
              'https://mydomian.com/myurl.html?unwan=abc&ab=1'
          );
          
          foreach($test as $url){
              print_r(parse_url($url));
          }       
          

          将返回:

          Array
          (
              [scheme] => http
              [host] => www.mydomian.com
              [path] => /myurl.html
              [query] => unwan=abc
          )
          Array
          (
              [scheme] => http
              [host] => www.mydomian.com
              [path] => /myurl.html
          )
          Array
          (
              [scheme] => http
              [host] => www.mydomian.com
          )
          Array
          (
              [path] => mydomian.com/myurl.html
              [query] => unwan=abc&ab=1
          )
          

          这是通过没有第二个参数的 parse_url() 传递示例 url 的输出(仅用于解释)。

          这是构造 url 后的最终输出:

          foreach($test as $url){
              echo reconstruct_url($url) . '<br/>';
          }   
          

          输出:

          http://www.mydomian.com/myurl.html
          http://www.mydomian.com/myurl.html
          http://www.mydomian.com
          https://mydomian.com/myurl.html
          

          【讨论】:

          • 我读过它。如果是 php 新手,我有点困惑。你能帮我处理上面的 php 代码吗?
          • 我在第 9 行之后添加了这段代码 $pageURL = substr( $pageURL, 0, strrpos( $pageURL, "?"));
          • 它清除了 url 中的查询部分...> www.mydomain.com/myurl.html?unwantedthings 结果是好的! > www.mydomian.com/myurl.html 完成...但是当它带有普通 url > www.mydomain.com/myurl.html 结果什么都没有..空
          • strrpos() in 'www.mydomain.com/myurl.html' 将返回 0 (FALSE 转换为布尔值更正确),因此您的 substr 将为空。使用 one: substr() OR parse_url() 因为两者都使用没有意义;)
          • 我的意思是 FALSE 转换为 int ;D
          【解决方案9】:

          因为我同时处理相对 URL 和绝对 URL,所以我更新了 veritas 的解决方案,如下面的代码。
          你可以在这里尝试一下:https://ideone.com/PvpZ4J

          function removeQueryStringFromUrl($url) {
              if (substr($url,0,4) == "http") {
                  $urlPartsArray = parse_url($url);
                  $outputUrl = $urlPartsArray['scheme'] . '://' . $urlPartsArray['host'] . ( isset($urlPartsArray['path']) ? $urlPartsArray['path'] : '' );
              } else {
                  $URLexploded = explode("?", $url, 2);
                  $outputUrl = $URLexploded[0];
              }
              return $outputUrl;
          }
          

          【讨论】:

            【解决方案10】:

            最佳解决方案:

            echo parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
            

            如果您要向同一个域提交表单,则无需在您的 http://domain.com 中包含。

            【讨论】:

            • 请注意 parse_url 需要一个绝对 URL,因此在某些情况下您会得到不正确的结果,例如如果您的 REQUEST_URL 以多个连续的斜杠开头。这些将被解释为与协议相关的 URI。
            • @AndyLorenz 你试过了吗?因为它实际上确实删除了查询字符串。
            • @Ludo-Offtherecord 你是对的 - 我已经删除了我的评论。道歉!
            【解决方案11】:

            试试这个

            $url_with_querystring = 'www.mydomian.com/myurl.html?unwantedthngs';
            $url_data = parse_url($url_with_querystring);
            $url_without_querystring = str_replace('?'.$url_data['query'], '', $url_with_querystring);
            

            【讨论】:

              【解决方案12】:

              如果要获取请求路径(more info):

              echo parse_url($_SERVER["REQUEST_URI"])['path']
              

              如果你想删除查询和(可能还有片段):

              function strposa($haystack, $needles=array(), $offset=0) {
                      $chr = array();
                      foreach($needles as $needle) {
                              $res = strpos($haystack, $needle, $offset);
                              if ($res !== false) $chr[$needle] = $res;
                      }
                      if(empty($chr)) return false;
                      return min($chr);
              }
              $i = strposa($_SERVER["REQUEST_URI"], ['#', '?']);
              echo strrpos($_SERVER["REQUEST_URI"], 0, $i);
              

              【讨论】:

                【解决方案13】:

                要从请求 URI 中删除查询字符串,请将查询字符串替换为空字符串:

                function request_uri_without_query() {
                    $result = $_SERVER['REQUEST_URI'];
                    $query = $_SERVER['QUERY_STRING'];
                    if(!empty($query)) {
                        $result = str_replace('?' . $query, '', $result);
                    }
                    return $result;
                }
                

                【讨论】:

                • 我认为www.example.com/myurl.html? 可能存在问题。
                【解决方案14】:

                你可以试试:

                <?php
                $this_page = basename($_SERVER['REQUEST_URI']);
                if (strpos($this_page, "?") !== false) $this_page = reset(explode("?", $this_page));
                ?>
                

                【讨论】:

                  【解决方案15】:
                  $val = substr( $url, 0, strrpos( $url, "?"));
                  

                  【讨论】:

                  • 各位回答你的问题我已经完成了..谢谢你的帮助..它可以清除 url 中的查询部分...
                  • > www.mydomain.com/myurl.html?unwantedthings 结果是好的! > www.mydomian.com/myurl.html 完成...但是当它带有普通 url > www.mydomain.com/myurl.html 结果什么都没有..空
                  • 新的php代码code code
                  • 我认为这是解决问题的一个相当甜蜜和简单的解决方案。不需要大量的扩展或功能。我用它来获取当前调用的文件名。 $base = basename($_SERVER['REQUEST_URI']); $page = substr($base, 0, strrpos($base, "?"));
                  • 正如 Navi 所说,这个答案并不可靠。 3v4l.org/nhVii如果url中没有querystring,则删除整个url!这种技术不支持 url-component-aware。 这个答案是不可取的。
                  猜你喜欢
                  • 2018-08-01
                  • 1970-01-01
                  • 2018-12-08
                  • 2019-01-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-02-02
                  相关资源
                  最近更新 更多