Getting current page URL using PHP
First appeared on mobifreaks.com · Updated
This was one of my first tutorials. I wrote it on Mobifreaks in 2011 and shared a shorter version on munwr.com in 2014. The idea still works, but the code needed fixing, so here is the original and what I would write today.
The two building blocks
PHP keeps details about the current request in the $_SERVER array. Two of its keys give you most of a URL:
$_SERVER['HTTP_HOST']is the host name, likewww.example.com.$_SERVER['REQUEST_URI']is the path and query string, like/2011/04/html-introduction?ref=home.
Join them with a scheme in front and you have the full URL.
The 2011 version
<?php
$Get_url = "http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
echo $Get_url;
?>
In 2014 I shortened it to $get-url = ..., which is worse: PHP variable names can't contain a hyphen, so that line is a syntax error.
Both versions also have two real problems:
- They assume
http://. Most sites are served over HTTPS now. - They are unsafe to echo as is.
HTTP_HOSTandREQUEST_URIcome from the request, so a visitor can put markup in them.
What I would write today
<?php
$isHttps = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off')
|| (int) ($_SERVER['SERVER_PORT'] ?? 0) === 443;
$currentUrl = ($isHttps ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
?>
<a href="<?= htmlspecialchars($currentUrl, ENT_QUOTES) ?>">Permalink</a>
$_SERVER['HTTPS']is set to a non-empty value on HTTPS requests. IIS sets it tooffon plain HTTP, hence the extra check.htmlspecialchars()escapes the URL before it goes into your HTML.
Behind a proxy or load balancer
If a proxy (Cloudflare, a load balancer, a container platform) handles HTTPS for you, PHP sees plain HTTP. The proxy usually passes the original scheme in an X-Forwarded-Proto header. Only trust that header when your own proxy sets it, because anyone can send it.
Using a framework?
Let it do the work. It already handles proxies and schemes:
- Laravel:
url()->current()(without the query string) orurl()->full()(with it). - Symfony:
$request->getUri().