Question

HTTP_HOST vs SERVER_NAME in PHP: What’s the Difference?

phpapacheserver-variables

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.com
  • www.example.com
  • localhost

PHP exposes that configured name through SERVER_NAME.

This means SERVER_NAME reflects what the server thinks its name is.

Why this matters

In real programs, the distinction affects:

  • URL generation
  • redirects
  • multi-domain applications
  • security decisions
  • logging and debugging

A request can be made with a host header that differs from the configured server name. In that case, HTTP_HOST and SERVER_NAME may not match.

Important practical idea

  • Use HTTP_HOST when you need the hostname the user actually requested.
  • Use SERVER_NAME when you need the server’s configured identity.

However, because HTTP_HOST is influenced by client input, you should not trust it blindly for security-sensitive logic.

Mental Model

Think of it like visiting a building.

  • HTTP_HOST is the name written by the visitor on the sign-in form: “I came here asking for this building.”
  • SERVER_NAME is 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.

Take Quiz

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

<?php

$scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https' : 'http';
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
$url = $scheme . '://' . $host . '/account';

echo $url;

This is useful if you want the generated link to match the domain the user used.

Example 3: Using the configured server name

<?php

$serverName = $_SERVER['SERVER_NAME'] ?? 'localhost';

echo "Configured server name: " . $serverName;

This is more about server identity than about the incoming request.

Key caution

Do not blindly use HTTP_HOST in security-sensitive code without validation:

<?php

$allowedHosts = ['example.com', 'www.example.com'];
$host = $_SERVER['HTTP_HOST'] ?? '';

if (!in_array($host, $allowedHosts, true)) {
    http_response_code(400);
    exit('Invalid host');
}

Because the host header comes from the client request, it should be treated as untrusted input.

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:

  1. $_SERVER['HTTP_HOST'] is set to blog.example.com.
  2. $_SERVER['SERVER_NAME'] is set to example.com.
  3. $httpHost receives blog.example.com.
  4. $serverName receives example.com.
  5. PHP compares the two strings with ===.
  6. They are not identical, so the else block runs.
  7. The output is:
Different values

What this demonstrates

It shows that the client-requested host and the configured server name can differ.

That is the core reason these variables are not interchangeable.

Real World Use Cases

When HTTP_HOST is useful

1. Multi-domain applications

A single PHP app may respond to multiple domains:

  • app.com
  • admin.app.com
  • customer.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, SERVER_NAME is the clearer choice.

Practical rule

For user-facing host detection, HTTP_HOST is usually more relevant. For server-configuration identity, SERVER_NAME is usually more relevant.

Take Quiz

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.

Early return for invalid host values

<?php

$host = $_SERVER['HTTP_HOST'] ?? '';

if ($host === '') {
    return;
}

// Continue only if host exists

Configuration-first approach

Many mature applications do not depend on request headers to know their main app URL. Instead, they use configuration:

<?php

$appUrl = 'https://example.com';

This is often safer for:

  • email links
  • canonical URLs
  • redirects
  • trusted system-to-system integrations

Real-world recommendation

If the hostname affects important business logic, validate it or use a trusted configuration value instead of assuming the request value is safe.

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 host
  • SERVER_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:

<?php

echo $_SERVER['HTTP_HOST'];

This may trigger a notice in some environments.

How to avoid it

Use null coalescing:

<?php

echo $_SERVER['HTTP_HOST'] ?? 'unknown';

4. Using SERVER_NAME when you actually need the requested domain

If your app serves multiple hostnames, SERVER_NAME may not reflect the hostname the user typed.

How to avoid it

Use HTTP_HOST when the exact requested host matters.

5. Building security decisions on untrusted input

Broken example:

<?php

if ($_SERVER['HTTP_HOST'] === 'admin.example.com') {
    $isAdminArea = true;
}

This alone should not define access control.

How to avoid it

Use proper authentication and authorization. Host-based checks should be secondary and validated.

Comparisons

Aspect$_SERVER['HTTP_HOST']$_SERVER['SERVER_NAME']
SourceHTTP Host request headerWeb server configuration
Controlled byClient requestServer setup
ReflectsWhat hostname was requestedWhat the server is named/configured as
Trust levelUntrusted inputMore trusted than request header, but still environment-dependent
Best forCurrent request domain, multi-domain behaviorServer identity, diagnostics, configuration awareness
Can differ?YesYes

Related comparison: request data vs server config

HTTP_HOST is closer to request data. SERVER_NAME is closer to server environment data.

That is why they are useful for different tasks.

Take Quiz

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_HOST when you need the hostname the user requested.
  • Use SERVER_NAME when you need the server’s configured identity.
  • Do not trust HTTP_HOST without 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
  • Local development environments
  • Missing server variables in CLI or unusual server configurations

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.

Take Quiz

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.
Take Quiz

Keep learning

Related questions

View more