What is the difference between HTTP_HOST and SERVER_NAME in PHP?

apache, php, server-variables

Solution

The `HTTP_HOST` is obtained from the HTTP request header and this is what the client actually used as "target host" of the request. The `SERVER_NAME` is defined in server config. Which one to use depends on what you need it for. You should now however realize that the one is a client-controlled value which may thus not be reliable for use in business logic and the other is a server-controlled value which is more reliable. You however need to ensure that the webserver in question has the `SERVER_NAME` correctly configured. Taking Apache HTTPD as an example, here's an extract from its documentation:

If no `ServerName` is specified, then the server attempts to deduce the hostname by performing a reverse lookup on the IP address. If no port is specified in the `ServerName`, then the server will use the port from the incoming request. For optimal reliability and predictability, you should specify an explicit hostname and port using the `ServerName` directive.

Update: after checking the answer of Pekka on your question which contains a link to bobince's answer that PHP would always return `HTTP_HOST`'s value for `SERVER_NAME`, which goes against my own PHP 4.x + Apache HTTPD 1.2.x experiences from a couple of years ago, I blew some dust from my current XAMPP environment on Windows XP (Apache HTTPD 2.2.1 with PHP 5.2.8), started it, created a PHP page which prints the both values, created a Java test application using `URLConnection` to modify the `Host` header and tests taught me that this is indeed (incorrectly) the case.

After first suspecting PHP and digging in some PHP bug reports regarding the subject, I learned that the root of the problem is in web server used, that it incorrectly returned HTTP `Host` header when `SERVER_NAME` was requested. So I dug into Apache HTTPD bug reports using various keywords regarding the subject and I finally found a related bug. This behaviour was introduced since around Apache HTTPD 1.3. You need to set `UseCanonicalName` directive to `on` in the `<VirtualHost>` entry of the `ServerName` in `httpd.conf` (also check the warning at the bottom of the document!).

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

This worked for me.

Summarized, `SERVER_NAME` is more reliable, but you're dependent on the server config!

Problem

What is the difference between `$_SERVER['HTTP_HOST']` and `$_SERVER['SERVER_NAME']` in PHP? When would you consider using one over the other and why?

Original source

Related problems