Question
I want to get the full current URL in PHP exactly as it appears in the browser's address bar.
I currently use this code:
$actual_link = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
However, this does not work correctly when I use URL rewriting rules in .htaccess, because the visible URL is not always the real file path on the server.
I need the URL exactly as the user sees it in the browser, including the rewritten path rather than the underlying server file path.
Short Answer
By the end of this page, you will understand how PHP builds the current request URL, why $_SERVER['PHP_SELF'] can be misleading with rewritten routes, and how to reliably get the full browser-visible URL using the correct server variables.
Concept
In PHP, the current URL is usually reconstructed from values in the $_SERVER superglobal. The important detail is that not all server variables represent the same thing.
For example:
$_SERVER['PHP_SELF']often points to the executing script path.$_SERVER['REQUEST_URI']contains the path and query string that the browser actually requested.$_SERVER['HTTP_HOST']contains the requested host name.$_SERVER['HTTPS']helps determine whether the request usedhttporhttps.
This matters because URL rewriting tools such as Apache .htaccess rules can map a friendly URL like:
/products/42
to a real server file such as:
/index.php?id=42
If you use PHP_SELF, you may get the script path instead of the URL the user typed or clicked. If you want the browser-visible URL, REQUEST_URI is usually the correct choice.
A common way to build the full URL is:
= (([]) && [] !== ? : )
. . [] . [];
Mental Model
Think of a web request like a package delivery label:
HTTP_HOSTis the building name.REQUEST_URIis the apartment number and any delivery instructions.PHP_SELFis the internal office room where the package was actually processed.
If you want to know what the visitor asked for, use the delivery label they wrote: REQUEST_URI.
If you want to know which PHP file handled it internally, use something like PHP_SELF.
With URL rewriting, those two can be different.
Syntax and Examples
The most common beginner-friendly approach is:
<?php
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
echo $url;
Example
If the browser shows:
https://example.com/blog/php?sort=new
then the variables are commonly like this:
$_SERVER['HTTPS']->on$_SERVER['HTTP_HOST']->example.com$_SERVER['REQUEST_URI']->/blog/php?sort=new
So the final result becomes:
Step by Step Execution
Consider this code:
<?php
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'];
$uri = $_SERVER['REQUEST_URI'];
$currentUrl = $scheme . '://' . $host . $uri;
echo $currentUrl;
Assume the browser requested:
https://shop.example.com/products/15?page=2
Step-by-step
-
PHP checks
$_SERVER['HTTPS'].- It is set and not equal to
'off'. - So
$schemebecomes'https'.
- It is set and not equal to
-
PHP reads
$_SERVER['HTTP_HOST'].
Real World Use Cases
Getting the full current URL is useful in many real applications:
-
Redirect back after login
- Store the current page so users return to it after authenticating.
-
Canonical URL generation
- Build the preferred page URL for SEO.
-
Analytics and logging
- Save the exact requested URL for debugging or traffic reports.
-
Sharing links
- Generate a copyable link to the current page.
-
Pagination and filters
- Preserve the current path and query string when building navigation links.
-
Error reporting
- Include the exact request URL in logs when something fails.
Example logging use:
<?php
error_log('User visited: ' . getCurrentUrl());
Real Codebase Usage
In real projects, developers usually do not build URLs inline everywhere. Instead, they wrap the logic in a helper function or service.
Common patterns include:
Guard clauses for missing values
<?php
function getCurrentUrl(): string
{
if (empty($_SERVER['HTTP_HOST']) || empty($_SERVER['REQUEST_URI'])) {
return '';
}
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
return $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
}
Validation before redirects
Developers often use the current URL as a return_url, but validate it first to avoid unsafe redirects.
= ();
( !== ) {
[] = ;
}
Common Mistakes
1. Using PHP_SELF for the visible URL
Broken example:
<?php
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
Why it is a problem:
PHP_SELFmay point to the executing script.- It may not match the rewritten route the user sees.
Use this instead:
<?php
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
2. Hardcoding http
Broken example:
<?php
$url = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
Why it is a problem:
- It gives the wrong result on HTTPS pages.
Comparisons
| Variable / Approach | What it represents | Includes query string? | Good for browser-visible URL? |
|---|---|---|---|
$_SERVER['PHP_SELF'] | Executing script path | No | No |
$_SERVER['REQUEST_URI'] | Requested path from browser | Yes | Yes |
$_SERVER['SCRIPT_NAME'] | Script filename path | No | No |
$_SERVER['HTTP_HOST'] | Host name from request | No | Only as one part |
$_SERVER['QUERY_STRING'] | Only the query part | Yes, but only query |
Cheat Sheet
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$fullUrl = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
Quick rules
- Use
REQUEST_URIfor the browser-requested path. - Do not use
PHP_SELFif URL rewriting is involved. - Use
HTTPSto detecthttpvshttps. - Use
HTTP_HOSTfor the domain part. REQUEST_URIusually includes the query string.
Common variables
$_SERVER['HTTP_HOST']-> host/domain$_SERVER['REQUEST_URI']-> path + query string$_SERVER['PHP_SELF']-> executing script path
FAQ
How do I get the current full URL in PHP?
Use HTTP_HOST, REQUEST_URI, and the request scheme:
$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$url = $scheme . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
Why is $_SERVER['PHP_SELF'] not giving the visible URL?
PHP_SELF usually points to the script being executed on the server, not the rewritten or friendly URL requested by the browser.
Does REQUEST_URI include the query string?
Yes, it usually includes both the path and the query string, such as /products?page=2.
How do I detect HTTPS in PHP?
A common check is:
!empty($_SERVER[]) && [] !==
Mini Project
Description
Build a small PHP page that displays the exact current URL requested by the browser. This demonstrates how to combine scheme, host, and request URI correctly, even when friendly URLs or rewritten routes are used.
Goal
Create a reusable PHP function that prints the full current URL exactly as the user requested it.
Requirements
- Create a function that returns the current full URL.
- Detect whether the request uses HTTP or HTTPS.
- Include the host name and full request URI.
- Print the URL on the page.
- Handle missing server values with sensible fallbacks.
Keep learning
Related questions
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.
Convert a PHP Object to an Associative Array
Learn how to convert a PHP object to an associative array, including quick methods, recursion, pitfalls, and practical examples.
Convert a Postman Request to cURL and PHP cURL
Learn how to convert a Postman POST request into a cURL command and use the same request in PHP cURL with headers and body.