Have a look at $_SERVER['REQUEST_URI'], i.e.
$actual_link = "https://$_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
$actual_link = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
Answer from ax. on Stack Overflow⚠️ This code has security implications because the client and the server can set
HTTP_HOSTandREQUEST_URIto arbitrary values. It is absolutely necessary to sanitize both values and do proper input validation (CWE-20). They must not be used in any security context.
Have a look at $_SERVER['REQUEST_URI'], i.e.
$actual_link = "https://$_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
$actual_link = (empty($_SERVER['HTTPS']) ? 'http' : 'https') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
⚠️ This code has security implications because the client and the server can set
HTTP_HOSTandREQUEST_URIto arbitrary values. It is absolutely necessary to sanitize both values and do proper input validation (CWE-20). They must not be used in any security context.
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
Full version
function url_origin(
use_forwarded_host = false )
{
$ssl = ( ! empty( $s['HTTPS'] ) && $s['HTTPS'] == 'on' );
$sp = strtolower( $s['SERVER_PROTOCOL'] );
$protocol = substr( $sp, 0, strpos(
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(
use_forwarded_host = false )
{
return url_origin(
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 (Which no longer exists)
URL structure:
scheme://username:password@domain:port/path?query_string#fragment_id
The parts in bold will not be included by the function
Notes:
- This function does not include
username:passwordfrom 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_idis not sent to the server by the client (browser) and will not be added to the full URL. $_GETwill only containfoo=bar2for an URL like/example?foo=bar1&foo=bar2.- Some CMS's and environments will rewrite
$_SERVER['REQUEST_URI']and return/example?foo=bar2for 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_HOSTif you do not plan to use proxies or balancers. - The spec says that the
Hostheader must contain the port number unless it is the default number.
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$_SERVERvariables in the PHP manual.
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.
Related:
What is the difference between HTTP_HOST and SERVER_NAME in PHP?
Is Port Number Required in HTTP "Host" Header Parameter?
https://stackoverflow.com/a/28049503/175071
$_SERVER['REQUEST_URI']
For more details on what info is available in the $_SERVER array, see the PHP manual page for it.
If you also need the query string (the bit after the ? in a URL), that part is in this variable:
$_SERVER['QUERY_STRING']
If you want just the parts of URL after http://domain.example, try this:
<?php echo $_SERVER['REQUEST_URI']; ?>
If the current URL was http://domain.example/some-slug/some-id, echo will return only /some-slug/some-id.
If you want the full URL, try this:
<?php echo 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; ?>