协慌网

登录 贡献 社区

获取 PHP 中的完整 URL

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

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

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

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

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

答案

看看$_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 设置为它想要的任意值。

短版本输出网页上的链接

$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:// username:password @domain:port / path?query_string# fragment_id

功能不包括粗体部分

笔记:

  • 此功能不包括username:password完整 URL 或片段(哈希)的username:password
  • 它不会显示 HTTP 的默认端口 80 和 HTTPS 的端口 443。
  • 仅使用 http 和 https 方案进行测试。
  • #fragment_id不会被客户端(浏览器)发送到服务器,也不会添加到完整的 URL。
  • $_GET将只包含foo=bar2像一个 URL /example?foo=bar1&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'] 。在发送之前,浏览器会对任何不受支持的字符进行编码。
  • $_SERVER['HTTP_HOST']并不总是根据 PHP 手册中的注释提供: http//php.net/manual/en/reserved.variables.php
  • $_SERVER['HTTP_X_FORWARDED_HOST']由平衡器设置,在 PHP 手册的$_SERVER变量列表中没有提到。

服务器控制变量:

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

有关:

HTTP_HOST 与 SERVER_NAME
HTTP“主机” 标头参数中是否需要端口号?
https://stackoverflow.com/a/28049503/175071

示例: https://(www.)example.com/subFolder/myfile.php?var=blabla#555

// ======= PATHINFO ====== //
$x = pathinfo($url);
$x['dirname']      ? https://example.com/subFolder
$x['basename']     ?                               myfile.php?
$x['extension']    ?                                      php?k=blaa#12345 // Unsecure! also, read my notice about hashtag parts    
$x['filename']     ?                               myfile

// ======= PARSE_URL ====== //
$x = parse_url($url);
$x['scheme']       ? https
$x['host']         ?         example.com
$x['path']         ?                    /subFolder/myfile.php
$x['query']        ?                                          k=blaa
$x['fragment']     ?                                                 12345 // ! read my notice about hashtag parts

//=================================================== //
//========== 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?k=blaa
$_SERVER["QUERY_STRING"]   ?                                             k=blaa
__FILE__                   ? /home/user/public_html/subFolder/myfile.php
__DIR__                    ? /home/user/public_html/subFolder              //same: dirname(__FILE__)
$_SERVER["REQUEST_URI"]    ?                       /subFolder/myfile.php?k=blaa
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?abc
__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__;

注意!:

  • hashtag(#...)无法从 PHP(服务器端)检测到 URL 部分。为此,请使用 JavaScript。
  • DIRECTORY_SEPARATOR返回\用于 Windows 类型的托管,而不是/



对于 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/