【问题标题】:Request string without GET arguments [duplicate]不带 GET 参数的请求字符串 [重复]
【发布时间】:2012-03-19 06:18:29
【问题描述】:

有没有一种简单的方法可以在不使用 GET 参数的情况下获取请求的文件或目录?例如,如果 URL 是 http://example.com/directory/file.php?paramater=value,我只想返回 http://example.com/directory/file.php。我很惊讶$_SERVER[] 中没有一个简单的索引。我错过了吗?

【问题讨论】:

  • 不使用 GET 使用 POST 吗?或者那是不可能的。
  • 不,这是一个更大的网络应用程序的一部分。无法确定是否会使用 GET 或 POST。

标签: php http url query-string


【解决方案1】:

编辑:@T.Todua 使用 parse_url 提供了一个更新的 answer to this question

(请为该答案投票,以便更明显)。

Edit2:有人一直在发垃圾邮件和编辑关于提取方案的内容,所以我在底部添加了。

parse_url解决方案

最简单的解决方案是:

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

Parse_url 是一个内置的 php 函数,其唯一目的是从 url 中提取特定的组件,包括 PATH(第一个 ? 之前的所有内容)。因此,这是我对这个问题的新“最佳”解决方案。

strtok解决方案

Stackoverflow: How to remove the querystring and get only the url?

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

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

性能说明: 这个问题也可以使用explode来解决。

  • 对于仅在单个分隔符上拆分 sring 的情况,Explode 往往表现更好。
  • Strtok 在使用多个分隔符的情况下往往表现更好。

这个应用 strtok 在字符的第一个实例之前返回字符串中的所有内容,这将比 PHP 中的 any 其他方法执行得更好,尽管会将查询字符串留在内存中。

关于 Scheme (http/https) 和 $_SERVER vars 的旁白

虽然 OP 没有询问,但我认为值得一提: parse_url 应该用于从 url 中提取任何特定组件,请参阅该函数的文档:

parse_url($actual_link, PHP_URL_SCHEME); 

这里需要注意的是,从请求中获取完整的 URL 不是一项简单的任务,并且具有许多安全隐患。 $_SERVER 变量在这里是你的朋友,但他们是一个善变的朋友,因为 apache/nginx 配置、php 环境,甚至客户端,都可以省略或更改这些变量。所有这些都超出了这个问题的范围,但已经进行了彻底的讨论:

https://stackoverflow.com/a/6768831/1589379

请务必注意,这些$_SERVER 变量是在运行时填充的,由执行执行的引擎(/var/run/php//etc/php/[version]/fpm/)填充。这些变量从操作系统传递到 web 服务器 (apache/nginx) 到 php 引擎,并在每一步进行修改和修正。唯一可以依赖的此类变量是 REQUEST_URI(因为它是 php 所必需的),以及那些列在 RFC 3875 中的变量(参见:PHP: $_SERVER),因为它们是网络服务器所必需的。

请注意:在其他问题中向您的答案发送垃圾链接是不好的。

【讨论】:

    【解决方案2】:

    您可以使用$_SERVER['REQUEST_URI'] 获取请求的路径。然后,您需要删除参数...

    $uri_parts = explode('?', $_SERVER['REQUEST_URI'], 2);
    

    然后,添加主机名和协议。

    echo 'http://' . $_SERVER['HTTP_HOST'] . $uri_parts[0];
    

    如果您将http:https:// 混合使用,您还必须检测协议。 作为练习留给你。 $_SERVER['REQUEST_SCHEME'] 返回协议。


    把它们放在一起:

    echo $_SERVER['REQUEST_SCHEME'] .'://'. $_SERVER['HTTP_HOST'] 
         . explode('?', $_SERVER['REQUEST_URI'], 2)[0];
    

    ...返回,例如:

    http://example.com/directory/file.php


    php.com 文档:

    • $_SERVER — 服务器和执行环境信息
    • explode — 用字符串分割字符串
    • parse_url — 解析 URL 并返回其组件(可能是更好的解决方案)

    【讨论】:

    • 太棒了。我知道这一定很简单。我删除了关于爆炸的最后一个论点,它就像一个魅力。谢谢!
    • @BrNathanH,我编辑了限制,现在它是 2。这对你来说没关系,但如果你想要查询字符串部分(在? 之后),并且有人有在其中卡住第二个?,然后将explode() 限制为2 个元素。
    • isset($_SERVER['HTTPS'])? “https”:“http”
    【解决方案3】:

    令人震惊的是,这些赞成/接受的答案中有多少是不完整的,所以他们在 7 年后没有回答 OP 的问题!

    • 如果您访问的页面的 URL 类似于:http://example.com/directory/file.php?paramater=value

    • ...而您只想返回:http://example.com/directory/file.php

    • 然后使用:

      echo $_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'];

    【讨论】:

    • 你为什么在 cmets 和问题上到处发垃圾邮件?撇开 OP not 询问该方案不谈,$_SERVER['PHP_SELF'] 不可靠,不应该这样使用,因为它在 CGI/FCGI 实现中通常为空.
    【解决方案4】:

    我实际上认为这不是解析它的好方法。不干净或者有点跑题了……

    • 爆炸很重
    • 会话很重
    • PHP_SELF 不处理 URLRewriting

    我会做类似...

    if ($pos_get = strpos($app_uri, '?')) $app_uri = substr($app_uri, 0, $pos_get);
    
    • 这会检测是否存在实际的“?” (GET 标准格式)
    • 如果没问题,那会在“?”之前剪切我们的变量保留用于获取数据

    考虑将 $app_uri 作为我网站的 URI/URL。

    【讨论】:

      【解决方案5】:
      $uri_parts = explode('?', $_SERVER['REQUEST_URI'], 2);
      $request_uri = $uri_parts[0];
      echo $request_uri;
      

      【讨论】:

      • 不错的copypasta。
      • @j4k3 它可能看起来像复制粘贴,但我实际上在我的项目中使用相同的代码。
      【解决方案6】:

      我知道这是一篇旧帖子,但我遇到了同样的问题,我用这种方式解决了它

      $current_request = preg_replace("/\?.*$/","",$_SERVER["REQUEST_URI"]);
      

      或者等价

      $current_request = preg_replace("/\?.*/D","",$_SERVER["REQUEST_URI"]);
      

      【讨论】:

        【解决方案7】:

        解决方案:

        echoparse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);

        【讨论】:

        • 虽然这可能是一个很好的答案,但最好解释一下答案背后的原因stackoverflow.com/help/how-to-answer
        • 感谢这项工作,这是最好的方法。
        • 我认为这是最好的答案,我认为不需要解释,如果我们需要解释,我们会去文档
        • @pythonian29033,但正如你所提到的,“转到文档”——那么至少应该有指向文档的链接。
        • 别偷懒了
        【解决方案8】:

        不是每个人都会觉得这很简单,但我相信这是最好的解决方法:

        preg_match('/^[^\?]+/', $_SERVER['REQUEST_URI'], $return);
        $url = 'http' . ('on' === $_SERVER['HTTPS'] ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . $return[0]
        


        所做的只是从字符串的开头遍历 REQUEST_URI,然后在遇到“?”时停止。 (实际上,只有在获取参数时才会发生)。

        然后创建 url 并将其保存到 $url:
        创建 $url 时...我们所做的只是写“http”然后检查是否使用了 https,如果是,我们也写“s”,然后我们连接“://”,连接 HTTP_HOST (服务器,fx:“stackoverflow.com”),并将我们之前找到的 $return 连接到那个(它是一个数组,但我们只想要其中的第一个索引......只能有一个索引,因为我们从正则表达式中字符串的开头开始检查。)。

        我希望有人可以使用这个...

        PS。这已被确认在使用 SLIM 重新路由 URL 时有效。

        【讨论】:

        • 您能解释一下相对于parse_url 和/或strtok 的优势吗?
        • 我希望您关注的是 preg_match... 使用 strtok() 您确实可以获得与使用 preg_match() 相同的行为,我不知道您会查看任何性能差异。我只是更喜欢 preg_match 并认为它更常见且文档更好,因此其他开发人员会更轻松地使用它。您很可能会使用 parse_url 并从中获取所需的一切。这可能是一种更轻量级的方法,但我还没有找到测试它的理由。但是人们显然不知道它,所以从它创建的数组中获取东西会更难访问,imo。
        • 我是一个正则表达式狂热者,所以我理解使用它作为你所有解析需求的魔法药丸的愿望。但是,parse_urlclearly documented,并且不熟悉正则表达式的人更容易在代码中理解。 explode 会表现得更好,strtok 会表现最好,正则表达式是每个benchmarksphp docs 最慢的选项。因此,我很好奇这与这里的其他答案相比有什么优势?
        • 我并不是要暗示你的答案是错误的,它仍然是一个很好的答案。
        • 您当然是对的,如果人们不熟悉正则表达式,那么遇到它会很麻烦。问题是,在我工作的公司,每个开发人员都知道正则表达式(只有一个人不“流利”),但通过彼此交谈,我发现这里的人比他们更了解正则表达式 parse_url和strtok。而且由于它是一个不重复的简单操作,因此性能对我们来说没有可读性那么有价值。总而言之,这种方法对我们来说是最好的,因为我们衡量它的标准。但说它是一般最好的方法,是不科学的。
        【解决方案9】:

        当我想要一个返回主页的链接时,我遇到了同样的问题。我试过了,它奏效了:

        <a href="<?php echo $_SESSION['PHP_SELF']; ?>?">
        

        注意最后的问号。我相信这会告诉机器停止代表编码器思考:)

        【讨论】:

        • 请详细说明这如何解决问题中所述的问题。
        • 在我的例子中,所有 POST 参数都默认包含在 $_SESSION['PHP_SELF'] 生成的链接中,但我注意到如果我添加一个 '?'最后,它不会添加任何参数。
        【解决方案10】:

        这里是考虑到不同端口和https的解决方案:

        $pageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
        
        if ($_SERVER['SERVER_PORT'] != '80')
          $pageURL .= $_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT'].$_SERVER['PHP_SELF'];
        else 
          $pageURL .= $_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'];  
        

        或者不考虑其他端口的更基本的解决方案:

        $pageURL = (@$_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
        $pageURL .= $_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF']; 
        

        【讨论】:

          【解决方案11】:

          你可以使用$_GET作为url参数,或者$_POST作为post参数,但是$_REQUEST包含来自$_GET$_POST$_COOKIE的参数,如果你想隐藏URI参数用户可以将其转换为会话变量,如下所示:

          <?php
          
          session_start();
          if (isset($_REQUEST['param']) && !isset($_SESSION['param'])) {
          
              // Store all parameters received
              $_SESSION['param'] = $_REQUEST['param'];
          
              // Redirect without URI parameters
              header('Location: /file.php');
              exit;
          }
          ?>
          <html>
          <body>
          <?php
            echo $_SESSION['param'];
          ?>
          </body>
          </html>
          

          编辑

          使用$_SERVER['PHP_SELF'] 获取当前文件名或$_SERVER['REQUEST_URI'] 获取请求的URI

          【讨论】:

          • 谢谢,但我想知道他们请求的页面没有 GET 参数。
          • 这与 OP 所要求的相反
          • @ashleedawg 然后对其投反对票(或者只是阅读EDIT 以获得正确答案),不知道为什么我需要提醒我大约 7 年前做错的事情 - 你在审核其余的答案呢?
          【解决方案12】:

          为什么这么复杂? =)

          $baseurl = 'http://mysite.com';
          $url_without_get = $baseurl.$_SERVER['PHP_SELF'];
          

          这确实应该这样做;)

          【讨论】:

          • 谢谢,我使用 RewriteEngine 通过 index.php(一个 MVC 应用程序)过滤所有内容,所以这不起作用。
          • 这不适用于 url 重写
          猜你喜欢
          • 1970-01-01
          • 2018-01-13
          • 2013-09-08
          • 1970-01-01
          • 2015-02-03
          • 2015-02-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多