我使用这段代码来获得完整的URL:
$actual_link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
问题是我在我的.htaccess中使用了一些掩码,所以我们在URL中看到的并不总是文件的真实路径。
我需要的是得到URL, URL中写了什么,不多不少——完整的URL。
我需要得到它如何出现在web浏览器的导航栏,而不是服务器上文件的真实路径。
我使用这段代码来获得完整的URL:
$actual_link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
问题是我在我的.htaccess中使用了一些掩码,所以我们在URL中看到的并不总是文件的真实路径。
我需要的是得到URL, URL中写了什么,不多不少——完整的URL。
我需要得到它如何出现在web浏览器的导航栏,而不是服务器上文件的真实路径。
当前回答
在网页上输出链接的简短版本
$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(现在已经不存在了)
URL结构:
scheme://username:password@domain:port/path?query_string#fragment_id
粗体部分将不包含在函数中
注:
This function does not include username:password from a full URL or the fragment (hash). It will not show the default port 80 for HTTP and port 443 for HTTPS. Only tested with http and https schemes. The #fragment_id is not sent to the server by the client (browser) and will not be added to the full URL. $_GET will only contain foo=bar2 for an URL like /example?foo=bar1&foo=bar2. Some CMS's and environments will rewrite $_SERVER['REQUEST_URI'] and return /example?foo=bar2 for an URL like /example?foo=bar1&foo=bar2, use $_SERVER['QUERY_STRING'] in this case. Keep in mind that an URI = URL + URN, but due to popular use, URL now means both URI and URL. You should remove HTTP_X_FORWARDED_HOST if you do not plan to use proxies or balancers. The spec says that the Host header must contain the port number unless it is the default number.
客户端(浏览器)控制变量:
$ _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
其他回答
function full_path()
{
$s = &$_SERVER;
$ssl = (!empty($s['HTTPS']) && $s['HTTPS'] == 'on') ? true:false;
$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 = 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;
$uri = $protocol . '://' . $host . $s['REQUEST_URI'];
$segments = explode('?', $uri, 2);
$url = $segments[0];
return $url;
}
注意:我刚刚更新了Timo Huovinen的代码,所以你不会在URL中得到任何get参数。这个URL很简单,删除了诸如?hi=i&am=a&get之类的东西。
例子:
http://www.example.com/index?get=information
将显示为:
http://www.example.com/index
这很好,除非您使用GET参数来定义一些特定的内容,在这种情况下,您应该使用他的代码!: -)
下面是一个使用三元语句的解决方案,保持代码最小化:
$url = "http" . (($_SERVER['SERVER_PORT'] == 443) ? "s" : "") . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
这是做到这一点的最小和最简单的方法,假设您的web服务器使用HTTPS的标准端口443。
我最喜欢的查找当前URL的跨平台方法是:
$url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
看一下$_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设置为它想要的任意值。
下面是更安全版本的接受答案的基础,使用PHP的filter_input函数,这也弥补了$_SERVER['REQUEST_URI']的潜在缺失:
$protocol_https = filter_input(INPUT_SERVER, 'HTTPS', FILTER_SANITIZE_STRING);
$host = filter_input(INPUT_SERVER, 'HTTP_HOST', FILTER_SANITIZE_URL);
$request_uri = filter_input(INPUT_SERVER, 'REQUEST_URI', FILTER_SANITIZE_URL);
if(strlen($request_uri) == 0)
{
$request_uri = filter_input(INPUT_SERVER, 'SCRIPT_NAME', FILTER_SANITIZE_URL);
$query_string = filter_input(INPUT_SERVER, 'QUERY_STRING', FILTER_SANITIZE_URL);
if($query_string)
{
$request_uri .= '?' . $query_string;
}
}
$full_url = ($protocol_https ? 'https' : 'http') . '://' . $host . $request_uri;
你可以使用一些不同的过滤器来调整它到你的喜欢。