PHP Detective: What Lies Behind HTTP_HOST and SERVER_NAME?
\n\nIf you've ever looked into the PHP superglobal array $_SERVER, you've probably seen two very similar keys: HTTP_HOST and SERVER_NAME. At first glance, they seem to be the same thing — the server name. But experienced developers know: the devil is in the details. This topic has garnered thousands of views on Stack Overflow, and for good reason. Choosing the wrong one can lead to bugs in redirects, failures in cross-domain requests, and even vulnerabilities.
In this article, we won't just list dry definitions. We'll conduct a real investigation: we'll break down where these values come from, how they behave on different servers (Apache, Nginx), and most importantly — when to use which one. Buckle up, it's going to be interesting.
\n\nWhat is HTTP_HOST?
\nHTTP_HOST is the value of the Host header that the browser (or any other HTTP client) sends to the server as part of the request. This header is mandatory in HTTP/1.1 and contains the domain name and, optionally, the port number.
Example request from a browser:
\nGET /page.php HTTP/1.1\nHost: pythonlib.ru:8080\nUser-Agent: Mozilla/5.0\n...\nIn PHP, this value ends up in $_SERVER['HTTP_HOST']. Note: this is an unverified value. The client can send any text in the Host header, for example, evil-site.com or 192.168.1.1. This is where the main danger lies.
What is SERVER_NAME?
\nSERVER_NAME is a value set by the web server itself based on its configuration. It is usually taken from the ServerName directive in Apache or server_name in Nginx. This is the name of the virtual host that processed the request.
Example Apache configuration:
\n<VirtualHost *:80>\n ServerName pythonlib.ru\n DocumentRoot /var/www/pythonlib\n</VirtualHost>\nIn this case, $_SERVER['SERVER_NAME'] will be equal to pythonlib.ru. Unlike HTTP_HOST, this value is controlled by the server administrator, not the client. However, there is a nuance: SERVER_NAME may not include the port (depends on the UseCanonicalName setting).
Key Differences in a Table
\nFor clarity, let's summarize everything in a table:
\n| Parameter | \nHTTP_HOST | \nSERVER_NAME | \n
|---|---|---|
| Source | \nHTTP request header from client | \nWeb server configuration | \n
| Control | \nClient (can be spoofed) | \nServer administrator | \n
| Port | \nIncludes port if non-standard (e.g., site.com:8080) | \n Usually without port (depends on UseCanonicalName) | \n
| Reliability | \nLow (do not trust without validation) | \nHigh (but not absolute) | \n
| Usage | \nRedirects, user-facing links | \nInternal logic, security | \n
When to Use What? Practical Examples
\nNow let's move on to the most important part — code. Let's look at three typical scenarios.
\n\n