在 PHP 中获取完整的 URL

2022-08-30 05:46:28

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

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

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

我需要的是获取URL,URL中写的内容,仅此而已,仅此而已 - 完整的URL。

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


答案 1

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

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

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

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

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

编者注:使用此代码具有安全隐患。客户端可以将HTTP_HOST和REQUEST_URI设置为所需的任意值。


答案 2

用于在网页上输出链接的简短版本

$url =  "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";

$escaped_url = htmlspecialchars( $url, ENT_QUOTES, 'UTF-8' );
echo '<a href="' . $escaped_url . '">' . $escaped_url . '</a>';

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

完整版

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 的大幅修改版本(已不复存在)

网址结构:

scheme:// 用户名:密码@domain:端口/路径?query_string#fragment_id

粗体部分将不包括在函数中

笔记:

  • 此函数不包括来自完整 URL 或片段(哈希)。username:password
  • 它不会显示 HTTP 的默认端口 80 和 HTTPS 的默认端口 443。
  • 仅使用 http 和 https 方案进行测试。
  • 客户端(浏览器)不会将 发送到服务器,也不会添加到完整 URL 中。#fragment_id
  • $_GET将仅包含类似 .foo=bar2/example?foo=bar1&foo=bar2
  • 某些 CMS 和环境将重写并返回 URL,如 在这种情况下使用 。$_SERVER['REQUEST_URI']/example?foo=bar2/example?foo=bar1&foo=bar2$_SERVER['QUERY_STRING']
  • 请记住,URI = ,但由于使用方式普遍,URL 现在同时表示 URI 和 URL。URL + URN
  • 如果您不打算使用代理或平衡器,则应将其删除。HTTP_X_FORWARDED_HOST
  • 规范规定标头必须包含端口号,除非它是默认编号。Host

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

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

服务器控制的变量:

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

相关:

PHP中的HTTP_HOST和SERVER_NAME有什么区别?
HTTP“主机”标头参数中是否需要端口号?
https://stackoverflow.com/a/28049503/175071


推荐