获取 PHP 中的完整 URL
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6768793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get the full URL in PHP
提问by DiegoP.
I use this code to get the full URL:
我使用此代码获取完整 URL:
$actual_link = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
The problem is that I use some masks in my .htaccess
, so what we see in the URL is not always the real path of the file.
问题是我在我的 中使用了一些掩码.htaccess
,所以我们在 URL 中看到的并不总是文件的真实路径。
What I need is to get the URL, what is written in the URL, nothing more and nothing less—the full URL.
我需要的是获取 URL,URL 中写的内容,仅此而已——完整的 URL。
I need to get how it appears in the Navigation Bar in the web browser, and not the real path of the file on the server.
我需要了解它在 Web 浏览器的导航栏中的显示方式,而不是服务器上文件的真实路径。
回答by ax.
Have a look at $_SERVER['REQUEST_URI']
, i.e.
看看$_SERVER['REQUEST_URI']
,即
$actual_link = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
(Note that the double quoted string syntax is perfectly correct)
(请注意,双引号字符串语法是完全正确的)
If you want to support both HTTP and HTTPS, you can use
如果你想同时支持 HTTP 和 HTTPS,你可以使用
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
Editor's note:using this code has security implications. The client can set HTTP_HOST and REQUEST_URI to any arbitrary value it wants.
编者注:使用此代码有安全隐患。客户端可以将 HTTP_HOST 和 REQUEST_URI 设置为它想要的任意值。
回答by Timo Huovinen
Short version to output link on a webpage
在网页上输出链接的简短版本
$url = "//{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
$escaped_url = htmlspecialchars( $url, ENT_QUOTES, 'UTF-8' );
echo '<a href="' . $escaped_url . '">' . $escaped_url . '</a>';
Here are some more details about the issues and edge cases of the //example.com/path/ format
以下是有关//example.com/path/ 格式的问题和边缘情况的更多详细信息
Full version
完整版本
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;
This is a heavily modified version of http://snipplr.com/view.php?codeview&id=2734
.
这是http://snipplr.com/view.php?codeview&id=2734
.
URL structure:
网址结构:
scheme://username:password@domain:port/path?query_string#fragment_id
方案://用户名:密码@域:端口/路径?query_string# fragment_id
The parts in bold will not be included by the function
粗体部分将不包含在函数中
Notes:
笔记:
- 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 containfoo=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 specsays that the
Host
header must contain the port number unless it is the default number.
- 此函数不包括
username:password
来自完整 URL 或片段(哈希)。 - 它不会显示 HTTP 的默认端口 80 和 HTTPS 的端口 443。
- 仅使用 http 和 https 方案进行了测试。
- 该
#fragment_id
不是由客户端(浏览器)发送到服务器并不会被添加到完整的URL。 $_GET
将只包含foo=bar2
像/example?foo=bar1&foo=bar2
.- 某些 CMS 和环境将重写
$_SERVER['REQUEST_URI']
并返回/example?foo=bar2
类似 的 URL/example?foo=bar1&foo=bar2
,$_SERVER['QUERY_STRING']
在这种情况下使用。 - 请记住URI=
URL + URN
,但由于普遍使用,URL 现在表示 URI 和 URL。 HTTP_X_FORWARDED_HOST
如果您不打算使用代理或平衡器,则应删除。- 该规范说,
Host
标题必须包含端口号,除非它是缺省值。
Client (Browser) controlled variables:
客户端(浏览器)控制变量:
$_SERVER['REQUEST_URI']
. Any unsupported characters are encoded by the browser before they are sent.$_SERVER['HTTP_HOST']
and is not always available according to comments in the PHP manual: http://php.net/manual/en/reserved.variables.php$_SERVER['HTTP_X_FORWARDED_HOST']
gets set by balancers and is not mentioned in the list of$_SERVER
variables in the PHP manual.
$_SERVER['REQUEST_URI']
. 任何不受支持的字符在发送之前都由浏览器编码。$_SERVER['HTTP_HOST']
根据 PHP 手册中的注释,并不总是可用:http: //php.net/manual/en/reserved.variables.php$_SERVER['HTTP_X_FORWARDED_HOST']
由平衡器设置,$_SERVER
PHP 手册的变量列表中未提及。
Server controlled variables:
服务器控制变量:
$_SERVER['HTTPS']
. The client chooses to use this, but the server returns the actual value of either empty or "on".$_SERVER['SERVER_PORT']
. The server only accepts allowed numbers as ports.$_SERVER['SERVER_PROTOCOL']
. The server only accepts certain protocols.$_SERVER['SERVER_NAME']
. It is set manually in the server configuration and is not available for IPv6 according to kralyk.
$_SERVER['HTTPS']
. 客户端选择使用它,但服务器返回空或“on”的实际值。$_SERVER['SERVER_PORT']
. 服务器只接受允许的数字作为端口。$_SERVER['SERVER_PROTOCOL']
. 服务器只接受某些协议。$_SERVER['SERVER_NAME']
. 它是在服务器配置中手动设置的,根据kralyk 的说法不适用于 IPv6 。
Related:
有关的:
HTTP_HOST vs. SERVER_NAME
Is Port Number Required in HTTP "Host" Header Parameter?
https://stackoverflow.com/a/28049503/175071
HTTP_HOST 与 SERVER_NAME
HTTP“主机”标头参数中是否需要端口号?
https://stackoverflow.com/a/28049503/175071
回答by T.Todua
Examples for: https://(www.)example.com/subFolder/myfile.php?var=blabla#555
示例: https://(www.)example.com/subFolder/myfile.php?var=blabla#555
// ======= PATHINFO ====== //
$x = pathinfo($url);
$x['dirname'] https://example.com/subFolder
$x['basename'] myfile.php?var=blabla#555 // Unsecure!
$x['extension'] php?var=blabla#555 // Unsecure!
$x['filename'] myfile
// ======= PARSE_URL ====== //
$x = parse_url($url);
$x['scheme'] https
$x['host'] example.com
$x['path'] /subFolder/myfile.php
$x['query'] var=blabla
$x['fragment'] 555
//=================================================== //
//========== self-defined SERVER variables ========== //
//=================================================== //
$_SERVER["DOCUMENT_ROOT"] /home/user/public_html
$_SERVER["SERVER_ADDR"] 143.34.112.23
$_SERVER["SERVER_PORT"] 80(or 443 etc..)
$_SERVER["REQUEST_SCHEME"] https //similar: $_SERVER["SERVER_PROTOCOL"]
$_SERVER['HTTP_HOST'] example.com (or with WWW) //similar: $_SERVER["ERVER_NAME"]
$_SERVER["REQUEST_URI"] /subFolder/myfile.php?var=blabla
$_SERVER["QUERY_STRING"] var=blabla
__FILE__ /home/user/public_html/subFolder/myfile.php
__DIR__ /home/user/public_html/subFolder //same: dirname(__FILE__)
$_SERVER["REQUEST_URI"] /subFolder/myfile.php?var=blabla
parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH) /subFolder/myfile.php
$_SERVER["PHP_SELF"] /subFolder/myfile.php
// ==================================================================//
//if "myfile.php" is included in "PARENTFILE.php" , and you visit "PARENTFILE.PHP?abc":
$_SERVER["SCRIPT_FILENAME"] /home/user/public_html/parentfile.php
$_SERVER["PHP_SELF"] /parentfile.php
$_SERVER["REQUEST_URI"] /parentfile.php?var=blabla
__FILE__ /home/user/public_html/subFolder/myfile.php
// =================================================== //
// ================= handy variables ================= //
// =================================================== //
//If site uses HTTPS:
$HTTP_or_HTTPS = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS']!=='off') || $_SERVER['SERVER_PORT']==443) ? 'https://':'http://' ); //in some cases, you need to add this condition too: if ('https'==$_SERVER['HTTP_X_FORWARDED_PROTO']) ...
//To trim values to filename, i.e.
basename($url) myfile.php
//excellent solution to find origin
$debug_files = debug_backtrace();
$caller_file = count($debug_files) ? $debug_files[count($debug_files) - 1]['file'] : __FILE__;
Notice ! ! !
注意 !!!
- hashtag
#
parts were manually used in the above example just for illustration purposes, however, server-side languages (includingphp
) can't natively detect them (Only Javascript can do that, as hashtag is onlybrowser/client side
functionality ). DIRECTORY_SEPARATOR
returns\
for Windows-type hosting, instead of/
.
#
在上面的示例中手动使用了hashtag部分只是为了说明目的,但是,服务器端语言(包括php
)无法本地检测它们(只有 Javascript 可以做到这一点,因为 hashtag 只是browser/client side
功能性)。DIRECTORY_SEPARATOR
返回\
Windows 类型的托管,而不是/
.
For WordPress
对于 WordPress
//(let's say, if wordpress is installed in subdirectory: http://example.com/wpdir/)
home_url() http://example.com/wpdir/ //if is_ssl() is true, then it will be "https"
get_stylesheet_directory_uri() http://example.com/wpdir/wp-content/themes/THEME_NAME [same: get_bloginfo('template_url') ]
get_stylesheet_directory() /home/user/public_html/wpdir/wp-content/themes/THEME_NAME
plugin_dir_url(__FILE__) http://example.com/wpdir/wp-content/themes/PLUGIN_NAME
plugin_dir_path(__FILE__) /home/user/public_html/wpdir/wp-content/plugins/PLUGIN_NAME/
回答by honyovk
Here's a solution using a ternary statement, keeping the code minimal:
这是使用三元语句的解决方案,保持代码最少:
$url = "http" . (($_SERVER['SERVER_PORT'] == 443) ? "s" : "") . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
This is the smallest and easiest way to do this, assuming one's web server is using the standard port 443 for HTTPS.
这是执行此操作的最小和最简单的方法,假设一个人的 Web 服务器使用标准端口 443 进行HTTPS。
回答by Daniel Gillespie
My favorite cross platform method for finding the current URL is:
我最喜欢的用于查找当前 URL 的跨平台方法是:
$url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
回答by HappyCoder
Simply use:
只需使用:
$uri = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']
回答by Alex Westergaard
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;
}
Note: I just made an update to Timo Huovinen's code, so you won't get any GET parameters in the URL. This URL is plain and removes things like ?hi=i&am=a&get
.
注意:我刚刚更新了Timo Huovinen 的代码,因此您不会在 URL 中获得任何 GET 参数。此 URL 很简单,并删除了诸如?hi=i&am=a&get
.
Example:
例子:
http://www.example.com/index?get=information
will be shown as:
将显示为:
http://www.example.com/index
This is fine unless you use GET paramaters to define some specific content, in which case you should use his code! :-)
这很好,除非你使用 GET 参数来定义一些特定的内容,在这种情况下你应该使用他的代码!:-)
回答by Andreas
Clear code, working in all webservers (Apache, nginx, IIS, ...):
清晰的代码,适用于所有网络服务器(Apache、nginx、IIS 等):
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
回答by Kai Noack
HTTP_HOST and REQUEST_URI must be in quotes, otherwise it throws an error in PHP 7.2
HTTP_HOST 和 REQUEST_URI 必须用引号引起来,否则在 PHP 7.2 中会抛出错误
Use:
用:
$actual_link = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
If you want to support both HTTP and HTTPS:
如果您想同时支持 HTTP 和 HTTPS:
$actual_link = (isset($_SERVER['HTTPS']) ? 'https' : 'http').'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
回答by OzzyCzech
Here is my solution - code is inspired by Tracy Debugger. It was changed for support different server ports. You can get full current URL including $_SERVER['REQUEST_URI']
or just the basic server URL. Check my function:
这是我的解决方案 - 代码的灵感来自Tracy Debugger。它已更改以支持不同的服务器端口。您可以获得完整的当前 URL,包括$_SERVER['REQUEST_URI']
或仅包含基本服务器 URL。检查我的功能:
function getCurrentUrl($full = true) {
if (isset($_SERVER['REQUEST_URI'])) {
$parse = parse_url(
(isset($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off') ? 'https://' : 'http://') .
(isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '')) . (($full) ? $_SERVER['REQUEST_URI'] : null)
);
$parse['port'] = $_SERVER["SERVER_PORT"]; // Setup protocol for sure (80 is default)
return http_build_url('', $parse);
}
}
Here is test code:
下面是测试代码:
// Follow $_SERVER variables was set only for test
$_SERVER['HTTPS'] = 'off'; // on
$_SERVER['SERVER_PORT'] = '9999'; // Setup
$_SERVER['HTTP_HOST'] = 'some.crazy.server.5.name:8088'; // Port is optional there
$_SERVER['REQUEST_URI'] = '/150/tail/single/normal?get=param';
echo getCurrentUrl();
// http://some.crazy.server.5.name:9999/150/tail/single/normal?get=param
echo getCurrentUrl(false);
// http://some.crazy.server.5.name:9999/