Back to blog
Development 3 min read

PHP: Determine the Full URL of the Current Page

How to retrieve the complete URL of the current page in PHP, including protocol, host, port, path, and query string.

16 October 2017

TL;DR

Use a custom function leveraging PHP's $_SERVER superglobal to build the full URL including protocol detection, host, port handling, and query string.

The problem

Sometimes you need to retrieve the complete URL of the current page in PHP. This might be for canonical URLs, redirects, logging, or sharing functionality. A standard URL has this format:

protocol://username:password@host:port/path?query#fragment

Note that credentials and fragments are typically excluded from PHP URL retrieval for security and technical reasons — the fragment (hash) is never sent to the server.

The solution

Here's a reliable function that handles HTTPS detection, non-standard ports, and the full request URI:

function get_current_url()
{
    $url = false;

    if (isset($_SERVER['SERVER_ADDR'])) {
        // Detect HTTPS
        $is_https = isset($_SERVER['HTTPS']) && 'on' == $_SERVER['HTTPS'];
        $protocol = 'http' . ($is_https ? 's' : '');

        // Get host (prefer HTTP_HOST for virtual hosts)
        $host = isset($_SERVER['HTTP_HOST'])
                ? $_SERVER['HTTP_HOST']
                : $_SERVER['SERVER_ADDR'];

        // Get port
        $port = $_SERVER['SERVER_PORT'];

        // Get path and query string
        $path_query = $_SERVER['REQUEST_URI'];

        // Build the URL
        $url = sprintf('%s://%s%s%s',
            $protocol,
            $host,
            $is_https
                ? (443 != $port ? ':' . $port : '')
                : (80 != $port ? ':' . $port : ''),
            $path_query
        );
    }

    return $url;
}

Key features

  • HTTPS detection: Automatically detects if the request is over HTTPS
  • Non-standard ports: Only includes port number when it's not the default (80 for HTTP, 443 for HTTPS)
  • Query string included: Uses REQUEST_URI which contains both path and query string
  • Graceful fallback: Returns false if not running as a web request (e.g., CLI)

Usage example

// Get the current URL
$current_url = get_current_url();

if ($current_url) {
    echo "Current URL: " . $current_url;
    // Output: https://example.com:8443/page?foo=bar
} else {
    echo "Not running as web request";
}

Considerations

When using this in production, be aware of a few edge cases:

  • Reverse proxies: If you're behind a load balancer or reverse proxy, you may need to check X-Forwarded-Proto and X-Forwarded-Host headers
  • Port in HTTP_HOST: Some servers include the port in HTTP_HOST, which could lead to duplication
  • Security: Never trust HTTP_HOST for security-critical operations without validation

Need help with PHP development? Let's talk.

Related posts