There are two options to choose between when it comes to obtaining the domain name, these are the $_SERVER['SERVER_NAME'] and $_SERVER['HTTP_HOST'] server variables. The main difference between the two, is that one is set by the server, wheres the other is provided by the user in the request header.
The main problem with using either, is to do with security. The HTTP_HOST variable can be manipulated with, and the SERVER_NAME variable will not always be controlled by the server, depending on how the server is configured.
The problem is to due with server configuration, and it will be addressed in detail in this article. Do not let yourself be fooled, the variables are completely reliable if you configure your server correctly.
But before reading the solution to the problem, try reading the part of the article explaining why someone would even want to use the HTTP_HOST header in the first place. It will give you a broader understanding of servers.
Internationalization and applications with multiple domains
Its a common practice to have multiple domains to create internationalized versions of the same application. In a multi-domain environment, the maintainability of your application can increase a lot very quickly, if you do not take the necessary precautions.
Having several copies of the same source code for each separate internationalization, can increase the complexity and maintainability level of a site tremendously, and is therefor not very desirable. To avoid this unnecessary level of complexity, you can make the same application handle the requests for all of the different domains. This will however call for some way to obtain the HTTP_HOST header from the clients HTTP request, and PHPs $_SERVER['HTTP_HOST'] variable dose just that – without forcing you to parse the request manually.
Besides other purposes that the $_SERVER['SERVER_NAME'] and $_SERVER['HTTP_HOST'] variables can be used for, this is just one of them.
Security "Hot Spots" when using HTTP_HOST and SERVER_NAME
The places that you should be extra careful to use the server variables, is in your database queries, and when echo'ing out the content of the variables to the browser. However, if your server has a vhost configuration, any such extra security and validation is quite unnecessary, as any invalid requests typically wont even reach your application in the first place.
In a vhost enviroment you should however still be careful. If your server is setup with a catch-all configuration for unknown hosts, you should make sure that your catch-all does not point to the same application accessible through any of your domain names.
If your catch-all point to an application from one of your sites, then it could potentially be possible for someone to point their domain, to the ip-address of your server, and access your site trough their domain.
In one of the worst case-scenarios, they might even be able to send out password reset emails to your users, from your application, but with reset links pointing to their domain name. This however depends on how your application is setup, and what its function is. But if it's using either of the variables in the generation of password reset links, than this scenario will be a threat.
The solution to security issues with server variables
Some people will recommend that you simply not rely on the server variables for anything, but while this is the easy solution, it is not always the most convenient one – and avoiding security problems with the $_SERVER['HTTP_HOST'] variable is very simple.
You should simply take care to setup your server correctly, so that requests containing fake HTTP_HOST headers will not even reach your application. If you do this, then it is considered completely safe to rely on HTTP_HOST, even without validating its content in your applications.
The best solution is likely to point your catch-all vhost configuration to a page that will simply reject requests containing an unknown host.
This is also likely one of the only exceptions, where validating a value provided by the client becomes irrelevant in PHP.