975

I use this code to get the full 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.

What I need is to get the URL, what is written in the URL, nothing more and nothing less—the full 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.

11
  • 24
    @Brade URL bar is on the user browser, so why would PHP have any functionalities regarding that? PHP is server side.
    – eis
    Commented Oct 19, 2013 at 11:53
  • 33
    @eis Believe me, there's plenty of reasons to want this. Landing pages that use the same template but need to be tracked separately, etc. And the fact is that PHP (or any server side lang) can return all the various parts of the URL, but never seem to provide the whole thing in one string. It just seems dumb.
    – Brade
    Commented Oct 29, 2013 at 19:14
  • 12
    Whole thing is never sent to server side as it shouldn't matter, which is the reason it's not readily available anywhere. I would regard any functionality relying on that broken. But, that's just my opinion.
    – eis
    Commented Oct 29, 2013 at 20:31
  • 5
    My example above for the need of a self URL: "filling FORM action URLs" may be wrong, as PHP_SELF (path only, sans domain etc.) should be enough for that. But it doesn't necessarily mean that all other needs for the canonical self URL are invalid. If they indeed are, it would be awesome to see a thorough explanation, why.
    – Sz.
    Commented Dec 7, 2013 at 12:58
  • 4
    One of the reasons why you should not hardcode your URL in config is when you have different platforms where your project will be installed on(dev, integration, production). Each one of them will have their specific URL, and you don't want to change your code according to which server your project is installed on. Commented Apr 27, 2016 at 7:40

27 Answers 27

2523
Answer recommended by PHP Collective

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_HOST and REQUEST_URI to 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.

59
  • 146
    What if you're on a https link? What if HTTP_HOST is not available or has been tampered with by client side? This answer seems incomplete and unreliable.
    – Manachi
    Commented Apr 5, 2013 at 2:07
  • 24
    Not much you can do about it, this is the proper method for the question asked.
    – Mfoo
    Commented Apr 27, 2013 at 12:45
  • 202
    You can just add the check of HTTPS: 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}/{$_SERVER['REQUEST_URI']}"
    – ivkremer
    Commented Feb 22, 2014 at 21:33
  • 9
    If you're outputting the URL to a browser as a link, just leave the http: off. See: stackoverflow.com/questions/4978235 Commented Feb 26, 2014 at 12:34
  • 10
    These comments from both parties are no longer contributing to the original post, and do not add value. Tooltip on Add Comment states "Use comments to ask for more information or suggest improvements". Please stick to that. Commented Aug 6, 2014 at 17:16
485

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( $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 (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: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.

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 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

27
  • 16
    This code will fail if the server is given by IPv6 IP address. To fix that, replace SERVER_NAME with HTTP_HOST.
    – kralyk
    Commented Nov 22, 2012 at 17:05
  • 1
    note: $_SERVER['REQUEST_URI'] will show /example?foo=bar2 for url like /example?foo=bar1&foo=bar2 Commented May 9, 2013 at 13:36
  • 3
    This would not contain anything defined after a #, those aren't passed through to the server Commented Jun 5, 2013 at 18:57
  • 1
    I'm unsure if that is no security risk. In your example you can send the Host header to reach the correct page but might let the page think it is called via another host using the HTTP_X_FORWARDED_HOST header. When the application uses this information (for whatever) it can be indeed a security problem as it allows you to promise something what isn't the case.
    – hek2mgl
    Commented Dec 6, 2013 at 11:08
  • 1
    @Matt3o12 The value of the port is taken directly from the Host header, haven't seen it set like that, thanks for mentioning it, will add it as a tweak Commented Apr 25, 2014 at 20:19
285

Examples for: https://www.site.xyz/fold/my.php?var=bla#555

Notice 1:

  • the hashtag # part was added manually in below php example snippet only for theoretical & illustrational purposes, however Server-Side languages (including PHP) are unable to detect them, because hashtags parts are only recognized in Client-Side browser/javascript...*

Notice 2:

  • DIRECTORY_SEPARATOR returns \ for Windows-OS, while UNIX returns /.
========== PATHINFO (use for filepathes, not urls) ==========

$x = PATHINFO ($url);
$x['dirname']              🡺 https://www.site.xyz/fold
$x['basename']             🡺                           my.php?var=bla#555 // unsafe!
$x['extension']            🡺                              php?var=bla#555 // unsafe!
$x['filename']             🡺                           my

========== PARSE_URL (use for urls, not filepathes) ==========

$x = PARSE_URL ($url);
$x['scheme']               🡺 https
$x['host']                 🡺         www.site.xyz
$x['path']                 🡺                     /fold/my.php
$x['query']                🡺                                  var=bla
$x['fragment']             🡺                                          555

Global variable $_SERVER

$_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                           
$_SERVER["SERVER_PROTOCOL"]🡺 <same>
$_SERVER['HTTP_HOST']      🡺        www.site.xyz
$_SERVER["SERVER_NAME"]    🡺           <same>
$_SERVER["REQUEST_URI"]    🡺                    /fold/my.php?var=bla
$_SERVER["QUERY_STRING"]   🡺                                 var=bla

__FILE__                   🡺 /home/user/public_html/fold/my.php
$_SERVER["SCRIPT_FILENAME"]🡺 <same>                              // Note! it will show entry file's path, if `my.php` is not called directly.
__DIR__                    🡺 /home/user/public_html/fold
dirname(__FILE__)          🡺 <same>
$_SERVER["REQUEST_URI"]    🡺                       /fold/my.php?var=bla  // Note! it will show entry file's path, if `my.php` is not called directly.
parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH)🡺  /fold/my.php
$_SERVER["PHP_SELF"]       🡺                       /fold/my.php  // Note! it will show entry file's path, if `my.php` is not called directly.
// detect https
$is_HTTPS = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS']!=='off') || $_SERVER['SERVER_PORT']==443);            //in some cases, you need to add this condition too: if ('https'==$_SERVER['HTTP_X_FORWARDED_PROTO']) 

PHP Functions

dirname($url)              🡺 https://www.site.xyz/fold/
basename($url)             🡺                           my.php
debug_backtrace()          🡺 SHOWS FULL TRACE OF ALL INCLUDED FILES




< For WordPress >

// (Let's say, if WordPress is installed in subdirectory:  http://site.xyz/sub/)
home_url()                      🡺 http://site.xyz/sub/        // If is_ssl() is true, then it will be "https"
get_stylesheet_directory_uri()  🡺 http://site.xyz/sub/wp-content/themes/THEME_NAME  [same: get_bloginfo('template_url') ]
get_stylesheet_directory()      🡺 /home/user/public_html/sub/wp-content/themes/THEME_NAME
plugin_dir_url(__FILE__)        🡺 http://site.xyz/sub/wp-content/themes/PLUGIN_NAME
plugin_dir_path(__FILE__)       🡺 /home/user/public_html/sub/wp-content/plugins/PLUGIN_NAME/
5
  • Where is the # part, Is there no way we can access part after # on the server side? Commented Aug 8, 2016 at 7:01
  • @RohitKhatri that part is only accessible in the browser and is not sent to server
    – beppe9000
    Commented Dec 24, 2019 at 13:53
  • What is the wordpress function to get the url with query string too ?
    – beppe9000
    Commented Dec 24, 2019 at 13:54
  • WARN: pathinfo() does not behave with more complex URL's as you would expect - although / character is not strictly forbidden in parameters (see stackoverflow.com/questions/1455578/…), parsing such URL will not give you script basename/filename. Try print_r(pathinfo("https://example.com/subFolder/myfile.php?var=path/to/another/file.png"));
    – Jiří
    Commented Aug 17, 2021 at 10:17
  • For me, I had to do basename ($_SERVER["PHP_https://stackoverflow.com/questions/6768793/get-the-full-url-in-phpSELF"] ) to get the main script name without query string (I need it for the main script in the sidebar links list)
    – Salem
    Commented Jun 14, 2022 at 11:13
71

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.

3
  • 22
    Or use $_SERVER["HTTPS"] == "on" to check if SSL is on.
    – Dzhuneyt
    Commented Aug 5, 2013 at 9:08
  • 19
    You should be using $_SERVER["HTTPS"] because port 443 is only the default SSL port, not an SSL indicator. Commented Sep 18, 2013 at 22:22
  • 5
    @AlexBarker - That's why I said "assuming one's web server is using the standard Port 443 for HTTPS."
    – honyovk
    Commented Sep 18, 2013 at 22:59
48

My favorite cross platform method for finding the current URL is:

$url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
1
  • 10
    Close, but I needed to change it to this: $url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    – Erik Allen
    Commented Feb 12, 2016 at 16:46
38

Simply use:

$uri = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']
5
  • 1
    As much as I want to use this, it doesn't work in IIS. stackoverflow.com/questions/18008135/…
    – Erik Allen
    Commented Feb 12, 2016 at 16:44
  • 1
    What does it output?
    – HappyCoder
    Commented Feb 13, 2016 at 17:08
  • 7
    PHP Notice: Undefined index: REQUEST_SCHEME
    – Erik Allen
    Commented Feb 16, 2016 at 16:24
  • 1
    i love this solution ! but can you also make it work for nginx ?
    – cowboysaif
    Commented Feb 29, 2016 at 16:29
  • 2
    http://example.com :8080 /request.php and fail. These answers are complicated for a reason. Commented Sep 29, 2016 at 16:14
24
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.

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! :-)

2
  • hey thats, pretty cool :) you could also remove anything after a hash "#" (url fragment) in case it somehow slips in Commented Nov 22, 2012 at 18:37
  • 1
    Not really, because if you set in " explode('#',$segment[0]) ", it will count as error, because " # " the symbol breaks the URL, and can only be read by Javascript. But what you can do, to be sure, is that you can remake the " return $url; " with " return trim($url,'#'); ", because then you will remove it, in case it will be there. But it will not remove the following content. You can read up on "Parse_url" if you want to. :-) Commented Nov 28, 2012 at 17:27
20

Same technique as the accepted answer, but with HTTPS support, and more readable:

$current_url = sprintf(
    '%s://%s/%s',
    isset($_SERVER['HTTPS']) ? 'https' : 'http',
    $_SERVER['HTTP_HOST'],
    $_SERVER['REQUEST_URI']
);

The above gives unwanted slashes. On my setup Request_URI has leading and trailing slashes. This works better for me.

$Current_Url = sprintf(
   '%s://%s/%s',
   isset($_SERVER['HTTPS']) ? 'https' : 'http',
   $_SERVER['HTTP_HOST'],
   trim($_SERVER['REQUEST_URI'],'/\\')
);
2
  • 1
    This is the simplest and cleanest one and it works. Commented Feb 6, 2022 at 0:02
  • Points for readability, thanks.
    – gregdev
    Commented Mar 27, 2022 at 22:24
19

Clear code, working in all webservers (Apache, nginx, IIS, ...):

$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
17

HTTP_HOST and REQUEST_URI must be in quotes, otherwise it throws an error in PHP 7.2

Use:

$actual_link = 'https://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];

If you want to support both HTTP and HTTPS:

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

⚠️ Using this code has security implications because the client can set HTTP_HOST and REQUEST_URI to arbitrary values. It is absolutely necessary to sanitize both values and do input validation.

Having said this, it is best to determine the link server side without relying on the URL of the browser.

12

Here is my solution - code is inspired by Tracy Debugger. It was changed for supporting different server ports. You can get full current URL including $_SERVER['REQUEST_URI'] or just the basic server URL. Check my function:

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/
1
  • 1
    Notice: http_build_url requires pecl_http installed Commented Mar 21, 2019 at 11:07
8

This is quite easy to do with your Apache environment variables. This only works with Apache 2, which I assume you are using.

Simply use the following PHP code:

<?php
    $request_url = apache_getenv("HTTP_HOST") . apache_getenv("REQUEST_URI");
    echo $request_url;
?>
1
  • I tried this $actual_link = 'http' . (isset($_SERVER['HTTPS']) ? 's' : '') . '://' . "{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"; Commented Jun 10, 2020 at 6:53
8

I've made this function to handle the URL:

 <?php
     function curPageURL()
     {
         $pageURL = 'http';
         if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
         $pageURL .= "://";
         if ($_SERVER["SERVER_PORT"] != "80") {
             $pageURL .=
             $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
         }
         else {
             $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
         }
         return $pageURL;
     }
 ?>
7

This is the solution for your problem:

//Fetch page URL by this

$url = $_SERVER['REQUEST_URI'];
echo "$url<br />";

//It will print
//fetch host by this

$host=$_SERVER['HTTP_HOST'];
echo "$host<br />";

//You can fetch the full URL by this

$fullurl = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
echo $fullurl;
6

Try this:

print_r($_SERVER);

$_SERVER is an array containing information such as headers, paths, and script locations. The entries in this array are created by the web server. There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here. That said, a large number of these variables are accounted for in the » CGI/1.1 specification, so you should be able to expect those.

$HTTP_SERVER_VARS contains the same initial information, but is not a superglobal. (Note that $HTTP_SERVER_VARS and $_SERVER are different variables and that PHP handles them as such)

0
6

You can use http_build_url with no arguments to get the full URL of the current page:

$url = http_build_url();
1
  • 6
    Note that http_build_url() is a PECL function only: (PECL pecl_http >= 0.21.0)
    – Volomike
    Commented Jul 10, 2015 at 22:59
6

Use this one-liner to find the parent folder URL (if you have no access to http_build_url() that comes along with pecl_http):

$url = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://').$_SERVER['SERVER_NAME'].str_replace($_SERVER['DOCUMENT_ROOT'], '', dirname(dirname(__FILE__)));
1
  • 6
    you mix url and file absolute location on disk
    – sd1sd1
    Commented Oct 1, 2015 at 8:49
4

Here is the basis of a more secure version of the accepted answer, using PHP's filter_input function, which also makes up for the potential lack of $_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;

You could use some different filters to tweak it to your liking.

4
    public static function getCurrentUrl($withQuery = true)
    {
        $protocol = (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
        or (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
        or (!empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
        or (isset($_SERVER['SERVER_PORT']) && intval($_SERVER['SERVER_PORT']) === 443) ? 'https' : 'http';

        $uri = $protocol . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

        return $withQuery ? $uri : str_replace('?' . $_SERVER['QUERY_STRING'], '', $uri);
    }
1
  • Seems to work nicely but I had to replace the ors with ||
    – Gavin
    Commented Jan 15, 2022 at 12:29
3

I have used the below code, and it is working fine for me, for both cases, HTTP and HTTPS.

function curPageURL() {
  if(isset($_SERVER["HTTPS"]) && !empty($_SERVER["HTTPS"]) && ($_SERVER["HTTPS"] != 'on' )) {
        $url = 'https://'.$_SERVER["SERVER_NAME"];//https url
  }  else {
    $url =  'http://'.$_SERVER["SERVER_NAME"];//http url
  }
  if(( $_SERVER["SERVER_PORT"] != 80 )) {
     $url .= $_SERVER["SERVER_PORT"];
  }
  $url .= $_SERVER["REQUEST_URI"];
  return $url;
}

echo curPageURL();

Demo

2
  • interchange position of http and https.
    – Shwet
    Commented Feb 8, 2017 at 5:29
  • Unless I'm mistaken, $_SERVER['HTTPS'] = 'off' will trigger the HTTPS path. That doesn't seem right. On the other hand, I don't think the original logic was right either. Commented Feb 8, 2017 at 21:00
3

I used this statement.

$base = "http://$_SERVER[SERVER_NAME]:$_SERVER[SERVER_PORT]$my_web_base_path";
$url = $base . "/" . dirname(dirname(__FILE__));
2

Very simple use:

function current_url() {
    $current_url  = ( $_SERVER["HTTPS"] != 'on' ) ? 'http://'.$_SERVER["SERVER_NAME"] :  'https://'.$_SERVER["SERVER_NAME"];
    $current_url .= ( $_SERVER["SERVER_PORT"] != 80 ) ? ":".$_SERVER["SERVER_PORT"] : "";
    $current_url .= $_SERVER["REQUEST_URI"];

    return $current_url;
}
3
  • 4
    Hi, given how many answers there already are on this page, could you add a bit of explanation about why this is better than the others, or what it does differently?
    – IMSoP
    Commented May 12, 2018 at 17:25
  • Hi, Indeed there are many solutions and my function is simple, clean and easy to understand.
    – Abbas Arif
    Commented May 3, 2021 at 21:21
  • Completely missing the point of IMSoP's comment... Commented Sep 27, 2022 at 21:20
2

Use:

$base_dir = __DIR__; // Absolute path to your installation, ex: /var/www/mywebsite
$doc_root = preg_replace("!{$_SERVER['SCRIPT_NAME']}$!", '', $_SERVER['SCRIPT_FILENAME']); # ex: /var/www
$base_url = preg_replace("!^{$doc_root}!", '', $base_dir); # ex: '' or '/mywebsite'
$base_url = str_replace('\\', '/', $base_url);//On Windows
$base_url = str_replace($doc_root, '', $base_url);//On Windows
$protocol = empty($_SERVER['HTTPS']) ? 'http' : 'https';
$port = $_SERVER['SERVER_PORT'];
$disp_port = ($protocol == 'http' && $port == 80 || $protocol == 'https' && $port == 443) ? '' : ":$port";
$domain = $_SERVER['SERVER_NAME'];
$full_url = "$protocol://{$domain}{$disp_port}{$base_url}"; # Ex: 'http://example.com', 'https://example.com/mywebsite', etc. 

Source: PHP Document Root, Path and URL detection

1
1

This works for both HTTP and HTTPS.

echo 'http' . (($_SERVER['HTTPS'] == 'on') ? 's' : '') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];

Output something like this.

https://example.com/user.php?token=3f0d9sickc0flmg8hnsngk5u07&access_level=application

1

You can make use of HTTP_ORIGIN as illustrated in the snippet below:

if ( ! array_key_exists( 'HTTP_ORIGIN', $_SERVER ) ) {
    $this->referer = $_SERVER['SERVER_NAME'];
} else {
    $this->referer = $_SERVER['HTTP_ORIGIN'];
}
2
  • What is HTTP_ORIGIN supposed to do? Why is it necessary? Commented Sep 27, 2022 at 21:17
  • 1
    OK, the answerer has left the building ("Last seen more than 4 years ago "). Perhaps somebody else can chime it? Commented Sep 27, 2022 at 21:18
0

I think this method is good..try it

if($_SERVER['HTTP_HOST'] == "localhost"){
    define('SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
    define('SITEPATH', $_SERVER['DOCUMENT_ROOT']);
    define('CSS', $_SERVER['DOCUMENT_ROOT'] . '/css/');
    define('IMAGES', $_SERVER['DOCUMENT_ROOT'] . '/images/');
}
else{
    define('SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
    define('SITEPATH', $_SERVER['DOCUMENT_ROOT']);
    define('TEMPLATE', $_SERVER['DOCUMENT_ROOT'] . '/incs/template/');
    define('CSS', $_SERVER['DOCUMENT_ROOT'] . '/css/');
    define('IMAGES', $_SERVER['DOCUMENT_ROOT'] . '/images/');
}
-1
$page_url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

For more: How to get the full URL of a page using PHP

2

Not the answer you're looking for? Browse other questions tagged or ask your own question.