PHP中获取的完整URL

Get the full URL in PHP

我使用此代码获取完整的URL:

1
$actual_link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];

问题是我在我的.htaccess中使用了一些掩码,所以我们在URL中看到的并不总是文件的真正路径。

我需要的是得到URL,写在URL中的内容,不多也不少完整的URL。

我需要了解它在Web浏览器的导航栏中的显示方式,而不是服务器上文件的实际路径。


看一下$_SERVER['REQUEST_URI'],即

1
$actual_link ="http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

(请注意,双引号字符串语法完全正确)

如果要同时支持HTTP和HTTPS,可以使用

1
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ?"https" :"http") ."://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

编者按:使用此代码具有安全含义。客户机可以设置http_主机并请求u uri到任何它想要的任意值。


网页上的短版本到输出链接

1
2
3
4
$url = "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

$escaped_url = htmlspecialchars( $url, ENT_QUOTES, 'UTF-8' );
echo '' . $escaped_url . '';

以下是有关//example.com/path/格式的问题和边缘案例的更多详细信息

完整版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function url_origin( $s, $use_forwarded_host = false )
{
    $ssl      = ( ! empty( $s['HTTPS'] ) && $s['HTTPS'] == 'on' );
    $sp       = strtolower( $s['SERVER_PROTOCOL'] );
    $protocol = substr( $sp, 0, strpos( $sp, '/' ) ) . ( ( $ssl ) ? 's' : '' );
    $port     = $s['SERVER_PORT'];
    $port     = ( ( ! $ssl && $port=='80' ) || ( $ssl && $port=='443' ) ) ? '' : ':'.$port;
    $host     = ( $use_forwarded_host && isset( $s['HTTP_X_FORWARDED_HOST'] ) ) ? $s['HTTP_X_FORWARDED_HOST'] : ( isset( $s['HTTP_HOST'] ) ? $s['HTTP_HOST'] : null );
    $host     = isset( $host ) ? $host : $s['SERVER_NAME'] . $port;
    return $protocol . '://' . $host;
}

function full_url( $s, $use_forwarded_host = false )
{
    return url_origin( $s, $use_forwarded_host ) . $s['REQUEST_URI'];
}

$absolute_url = full_url( $_SERVER );
echo $absolute_url;

这是http://snipplr.com/view.php?codeview&id=2734的一个经过重大修改的版本。

URL结构:

scheme://username:password@domain:port/path?查询字符串片段ID

粗体部分不包含在功能中

笔记:

  • 此函数不包括来自完整URL或片段(哈希)的username:password
  • 它不会显示HTTP的默认端口80和HTTPS的端口443。
  • 仅使用HTTP和HTTPS方案进行测试。
  • #fragment_id不是由客户机(浏览器)发送到服务器的,也不会添加到完整的URL中。
  • 对于像/example?foo=bar1&foo=bar2这样的URL,$_GET只包含foo=bar2
  • 有些CMS和环境会重写$_SERVER['REQUEST_URI'],并返回/example?foo=bar2,对于类似/example?foo=bar1&foo=bar2的URL,在这种情况下使用$_SERVER['QUERY_STRING']
  • 请记住,uri=URL + URN,但由于广泛使用,url现在意味着uri和url。
  • 如果不打算使用代理或平衡程序,则应删除HTTP_X_FORWARDED_HOST
  • 规范指出,除非是默认编号,否则Host头必须包含端口号。

客户端(浏览器)控制变量:

  • $_SERVER['REQUEST_URI']。任何不支持的字符在发送前都由浏览器进行编码。
  • 根据php手册:http://php.net/manual/en/reserved.variables.php中的注释,$_SERVER['HTTP_HOST']并不总是可用的。
  • $_SERVER['HTTP_X_FORWARDED_HOST']由平衡程序设置,在PHP手册的$_SERVER变量列表中没有提到。

服务器控制变量:

  • $_SERVER['HTTPS']。客户机选择使用它,但是服务器返回空值或"on"值。
  • $_SERVER['SERVER_PORT']。服务器只接受允许的数字作为端口。
  • $_SERVER['SERVER_PROTOCOL']。服务器只接受某些协议。
  • $_SERVER['SERVER_NAME']。它是在服务器配置中手动设置的,根据Kralyk,它不可用于IPv6。

相关:

HTTP主机与服务器名称HTTP"主机"头参数中是否需要端口号?https://stackoverflow.com/a/28049503/175071