What is the most dependable, generic method to create a self-referential URL? Quite simply, I wish to create the http://www.site.com[:port] area of the URL the user's browser is striking. I am using PHP running under Apache.

A couple of complications:

  • Depending on $_SERVER["HTTP_HOST"] is harmful, because that appears in the future completely from the HTTP Host header, which someone can forge.

  • There might be virtual hosts.

  • There might be a port specified using Apache's Port directive, but that is probably not the main harbour the user specified, whether it's behind a lot-balancer or proxy.

  • The main harbour might not really participate the URL. For instance, 80 and 443 are often overlooked.

  • PHP's $_SERVER["HTTPS"] does not always provide a reliable value, particularly if you are behind a lot-balancer or proxy.

  • Apache includes a UseCanonicalName directive, which affects the values from the SERVER_Title and SERVER_PORT atmosphere variables. We are able to assume this really is switched on, in the event that helps.

I recommend that the only method to be certain and also to be secure would be to define a continuing for that url in certain type of config apply for the website. You can create the constant with $_SERVER['HTTP_HOST'] like a default and replace a tough coded definition on deployments where security really matters.

define('SITE_URL', $_SERVER['HTTP_HOST']);

and replace when needed:

define('SITE_URL', 'http://foo.bar.com:8080/');

When I recall, for you to do something similar to this:

$protocol = 'http';

if ( (!empty($_SERVER['HTTPS'])) || ($_SERVER['HTTPS'] == 'off') ) {
    $protocol = 'https';
    if ($_SERVER['SERVER_PORT'] != 443)
        $port = $_SERVER['SERVER_PORT'];
} else if ($_SERVER['SERVER_PORT'] != 80) {
    $port = $_SERVER['SERVER_PORT'];
// Server name is going to be whatever the virtual host name is set to in your configuration
$address = $protocol . '://' . $_SERVER['SERVER_NAME'];
if (!empty($port))
    $address .= ':' . $port
$address .= $_SERVER['REQUEST_URI'];
// Optional, if you want the query string intact
if (!empty($_SERVER['QUERY_STRING']))
    $address .= '?' . $_SERVER['QUERY_STRING'];

I've not examined this code, because I do not have PHP handy right now.

Probably the most reliable strategy is to supply it yourself.

The website ought to be coded to become hostname neutral, but to understand about a unique configuration file. This file does not get put in source control for that codebase since it goes towards the webserver's configuration. The file can be used to create such things as the hostname along with other webserver-specific parameters. You are able to accomodate load balancers, altering ports, etc, because you are saying if the HTTP request hits that code, it can assume however much you'll allow it to assume.

This trick likewise helps development, incidentally. :-)

$_SERVER["HTTP_HOST"] is most likely the easiest way, after a little validation obviously.

Yes, the consumer identifies it so it can't be reliable, but it is simple to identify once the user is doing offers by using it.

One idea for validating that $_SERVER['HTTP_HOST'] applies would be to validate it by DNS. I have used this process in a couple of cases without serious effects to hurry but this process fails quietly if provided a Ip.


Peusudo code may be:

define('SITEHOME', in_array(gethostbyname($_SERVER['HTTP_HOST']), array(... valid IP's))) 
: 'default_hostname';

why you want the consumer to carry on using http:///host:port/ that they're on do you want to create full web addresses whan you should use relative web addresses rather than either

say on-page http://xxx:yy/zzz/fff/

you culd use either

../graphics/whatever.digital digital sites as specified

these both avoid mentioning the host:port part and inherit it in the one presently being used