When would you consider using one over the other and why?
相关问题
- Views base64 encoded blob in HTML with PHP
- Laravel Option Select - Default Issue
- PHP Recursively File Folder Scan Sorted by Modific
- Can php detect if javascript is on or not?
- Using similar_text and strpos together
Depends what I want to find out. SERVER_NAME is the host name of the server, whilst HTTP_HOST is the virtual host that the client connected to.
The
HTTP_HOST
is obtained from the HTTP request header and this is what the client actually used as "target host" of the request. TheSERVER_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 theSERVER_NAME
correctly configured. Taking Apache HTTPD as an example, here's an extract from its documentation: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 forSERVER_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 usingURLConnection
to modify theHost
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 whenSERVER_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 setUseCanonicalName
directive toon
in the<VirtualHost>
entry of theServerName
inhttpd.conf
(also check the warning at the bottom of the document!).This worked for me.
Summarized,
SERVER_NAME
is more reliable, but you're dependent on the server config!As I mentioned in this answer, if the server runs on a port other than 80 (as might be common on a development/intranet machine) then
HTTP_HOST
contains the port, whileSERVER_NAME
does not.(At least that's what I've noticed in Apache port-based virtualhosts)
Note that
HTTP_HOST
does not contain:443
when running on HTTPS (unless you're running on a non-standard port, which I haven't tested).As others have noted, the two also differ when using IPv6:
Please note that if you want to use IPv6, you probably want to use
HTTP_HOST
rather thanSERVER_NAME
. If you enterhttp://[::1]/
the environment variables will be the following:This means, that if you do a mod_rewrite for example, you might get a nasty result. Example for a SSL redirect:
This applies ONLY if you access the server without an hostname.
if you want to check through a server.php or what ever you want to call it with the following:
or
Then access it with all the valid urls for your site and check out the difference.
Assuming one has a simple setup (CentOS 7, Apache 2.4.x, and PHP 5.6.20) and only one website (not assuming virtual hosting) ...
In the PHP sense,
$_SERVER['SERVER_NAME']
is an element PHP registers in the$_SERVER
superglobal based on your Apache configuration (**ServerName**
directive withUseCanonicalName On
) in httpd.conf (be it from an included virtual host configuration file, whatever, etc ...). HTTP_HOST is derived from the HTTPhost
header. Treat this as user input. Filter and validate before using.Here is an example of where I use
$_SERVER['SERVER_NAME']
as the basis for a comparison. The following method is from a concrete child class I made namedServerValidator
(child ofValidator
).ServerValidator
checks six or seven elements in $_SERVER before using them.In determining if the HTTP request is POST, I use this method.
By the time this method is called, all filtering and validating of relevant $_SERVER elements would have occurred (and relevant properties set).
The line ...
... checks that the
$_SERVER['HTTP_HOST']
value (ultimately derived from the the requestedhost
HTTP header) matches$_SERVER['SERVER_NAME']
.Now, I am using superglobal speak to explain my example, but that is just because some people are unfamiliar with
INPUT_GET
,INPUT_POST
, andINPUT_SERVER
in regards tofilter_input_array()
.The bottom line is, I do not handle POST requests on my server unless all four conditions are met. Hence, in terms of POST requests, failure to provide an HTTP
host
header (presence tested for earlier) spells doom for strict HTTP 1.0 browsers. Moreover, the requested host must match the value forServerName
in the httpd.conf, and, by extention, the value for$_SERVER('SERVER_NAME')
in the$_SERVER
superglobal. Again, I would be usingINPUT_SERVER
with the PHP filter functions, but you catch my drift.Keep in mind that Apache frequently uses
ServerName
in standard redirects (such as leaving the trailing slash off a URL: Example, http://www.foo.com becoming http://www.foo.com/), even if you are not using URL rewriting.I use
$_SERVER['SERVER_NAME']
as the standard, not$_SERVER['HTTP_HOST']
. There is a lot of back and forth on this issue.$_SERVER['HTTP_HOST']
could be empty, so this should not be the basis for creating code conventions such as my public method above. But, just because both may be set does not guarantee they will be equal. Testing is the best way to know for sure (bearing in mind Apache version and PHP version).