Question
In PHP, what is the difference between $_SERVER['HTTP_HOST'] and $_SERVER['SERVER_NAME']?
When should you use one instead of the other, and what are the practical reasons for choosing one in real applications?
Short Answer
By the end of this page, you will understand what $_SERVER['HTTP_HOST'] and $_SERVER['SERVER_NAME'] represent in PHP, where their values come from, how they differ in practice, and which one is usually safer or more appropriate depending on your use case.
Concept
$_SERVER is a PHP superglobal that contains information about the current request and the server environment.
Two commonly confused entries are:
$_SERVER['HTTP_HOST']$_SERVER['SERVER_NAME']
They may look similar, but they come from different places.
$_SERVER['HTTP_HOST']
HTTP_HOST usually comes from the HTTP Host header sent by the client browser.
For example, if the browser requests:
GET /profile HTTP/1.1
Host: example.com
then PHP will usually expose:
$_SERVER['HTTP_HOST'] === 'example.com'
This means HTTP_HOST reflects what the client asked for.
$_SERVER['SERVER_NAME']
SERVER_NAME usually comes from the web server configuration.
For example, in Apache or Nginx, the server may be configured with a hostname such as:
example.comwww.example.comlocalhost
Mental Model
Think of it like visiting a building.
HTTP_HOSTis the name written by the visitor on the sign-in form: “I came here asking for this building.”SERVER_NAMEis the official name registered by the building management.
Most of the time they match. But they do not have to.
If you want to know what the visitor typed, look at HTTP_HOST.
If you want to know the building’s configured official name, look at SERVER_NAME.
That simple difference explains most real-world usage.
Syntax and Examples
The basic syntax is:
$hostHeader = $_SERVER['HTTP_HOST'] ?? null;
$serverName = $_SERVER['SERVER_NAME'] ?? null;
The ?? null part is a safe fallback in case the value is missing.
Example 1: Reading both values
<?php
$httpHost = $_SERVER['HTTP_HOST'] ?? 'not set';
$serverName = $_SERVER['SERVER_NAME'] ?? 'not set';
echo "HTTP_HOST: " . $httpHost . PHP_EOL;
echo "SERVER_NAME: " . $serverName . PHP_EOL;
Possible output:
HTTP_HOST: shop.example.com
SERVER_NAME: example.com
This can happen in setups where the request was made to a subdomain, but the server configuration uses a different default name.
Example 2: Building a URL based on the requested host
= (!([]) && [] !== ) ? : ;
= [] ?? ;
= . . . ;
;
Step by Step Execution
Consider this code:
<?php
$_SERVER['HTTP_HOST'] = 'blog.example.com';
$_SERVER['SERVER_NAME'] = 'example.com';
$httpHost = $_SERVER['HTTP_HOST'] ?? 'not set';
$serverName = $_SERVER['SERVER_NAME'] ?? 'not set';
if ($httpHost === $serverName) {
echo 'Same host';
} else {
echo 'Different values';
}
Here is what happens step by step:
$_SERVER['HTTP_HOST']is set toblog.example.com.$_SERVER['SERVER_NAME']is set toexample.com.$httpHostreceivesblog.example.com.$serverNamereceivesexample.com.
Real World Use Cases
When HTTP_HOST is useful
1. Multi-domain applications
A single PHP app may respond to multiple domains:
app.comadmin.app.comcustomer.app.com
You may want to detect which host the user requested and change branding, routing, or tenant data.
2. Generating links that match the current domain
If a user visits store.example.com, you may want password reset links or navigation links to stay on that same host.
3. Domain-based tenant resolution
In a SaaS app, each customer may have a different hostname. HTTP_HOST helps identify which tenant is making the request.
When SERVER_NAME is useful
1. Server diagnostics
If you want to inspect how the web server is configured, SERVER_NAME can be useful for logging or debugging.
2. Environment awareness
In some hosting setups, the configured server name may help distinguish between local, staging, and production environments.
3. Default server identity
If you need the server’s configured name rather than the user-requested name, is the clearer choice.
Real Codebase Usage
In real PHP codebases, developers often avoid using either value directly without checks.
Common patterns
Guard clauses for missing values
<?php
$host = $_SERVER['HTTP_HOST'] ?? null;
if ($host === null || $host === '') {
throw new RuntimeException('Host header is missing.');
}
This prevents undefined index notices and makes failures explicit.
Validation against allowed hosts
<?php
$allowedHosts = ['example.com', 'api.example.com'];
$host = $_SERVER['HTTP_HOST'] ?? '';
if (!in_array($host, $allowedHosts, true)) {
http_response_code(400);
exit('Bad Request');
}
This is common in apps that generate absolute URLs, handle redirects, or route tenants by domain.
Common Mistakes
1. Assuming both values are always identical
Beginners often write code as if these are interchangeable.
<?php
if ($_SERVER['HTTP_HOST'] === $_SERVER['SERVER_NAME']) {
echo 'Always true';
}
This is not guaranteed.
How to avoid it
Treat them as different concepts:
HTTP_HOST= requested hostSERVER_NAME= configured server name
2. Trusting HTTP_HOST without validation
Broken example:
<?php
$resetUrl = 'https://' . $_SERVER['HTTP_HOST'] . '/reset-password';
If the host header is manipulated, this can generate incorrect or unsafe links.
How to avoid it
Validate against a whitelist or use a configured base URL.
3. Not handling missing indexes
Broken example:
Comparisons
| Aspect | $_SERVER['HTTP_HOST'] | $_SERVER['SERVER_NAME'] |
|---|---|---|
| Source | HTTP Host request header | Web server configuration |
| Controlled by | Client request | Server setup |
| Reflects | What hostname was requested | What the server is named/configured as |
| Trust level | Untrusted input | More trusted than request header, but still environment-dependent |
| Best for | Current request domain, multi-domain behavior | Server identity, diagnostics, configuration awareness |
| Can differ? | Yes | Yes |
Related comparison: request data vs server config
HTTP_HOST is closer to request data.
is closer to server environment data.
Cheat Sheet
$_SERVER['HTTP_HOST'] // Host requested by the client, usually from the Host header
$_SERVER['SERVER_NAME'] // Server's configured name
Quick rules
- Use
HTTP_HOSTwhen you need the hostname the user requested. - Use
SERVER_NAMEwhen you need the server’s configured identity. - Do not trust
HTTP_HOSTwithout validation. - Use
??to avoid undefined index notices.
Safe access
$host = $_SERVER['HTTP_HOST'] ?? null;
$name = $_SERVER['SERVER_NAME'] ?? null;
Good practice for important URLs
$baseUrl = 'https://example.com';
Use configuration for trusted absolute URLs when possible.
Common edge cases
- Reverse proxy or load balancer setups
- Multiple domains pointing to the same app
FAQ
What is HTTP_HOST in PHP?
It is usually the hostname sent by the client in the HTTP Host header, such as example.com.
What is SERVER_NAME in PHP?
It is usually the server name defined by the web server configuration and exposed to PHP.
Is HTTP_HOST always the same as SERVER_NAME?
No. They often match, but they can differ depending on the request and server setup.
Which one should I use to get the current domain?
Usually HTTP_HOST, because it reflects the hostname the user actually requested.
Is HTTP_HOST safe to trust?
Not by itself. It comes from the request, so validate it before using it in sensitive logic.
Should I use SERVER_NAME for generating absolute URLs?
Not always. In many applications, a configured base URL is safer and more predictable.
Why do frameworks often use configuration instead of these variables?
Because configuration is more stable and trusted, especially for email links, redirects, and production deployments.
Mini Project
Description
Build a small PHP script that inspects the incoming hostname and decides whether it is allowed. This demonstrates the practical difference between a client-requested host (HTTP_HOST) and a server-configured name (SERVER_NAME), while also teaching safe validation.
Goal
Create a PHP page that displays both values and only accepts requests for approved hostnames.
Requirements
- Read both
$_SERVER['HTTP_HOST']and$_SERVER['SERVER_NAME']safely. - Display both values in the response.
- Validate the requested host against a small allowlist.
- Return an error message if the requested host is not allowed.
Keep learning
Related questions
Are PDO Prepared Statements Enough to Prevent SQL Injection in PHP?
Learn how PDO prepared statements prevent SQL injection in PHP, what they protect, and the mistakes that still leave MySQL apps vulnerable.
Can You Bind an Array to an IN Clause in PHP PDO?
Learn how PDO handles placeholders in IN() clauses, why arrays cannot be bound directly, and the safe PHP pattern to build dynamic queries.
Choosing the Right MySQL Collation for PHP and UTF-8
Learn how MySQL character sets and collations work with PHP, and how to choose a practical UTF-8 setup for web applications.