php - will - use of undefined constant undefined assumed undefined in




Qual é a diferença entre HTTP_HOST e SERVER_NAME no PHP? (6)

Como balusC disse SERVER_NAME não é confiável e pode ser alterado na configuração do apache, configuração do nome do servidor do servidor e firewall que pode ser entre você e o servidor.

A seguinte função sempre retorna o host real (host digitado pelo usuário) sem porta e é quase confiável:

function getRealHost(){
   list($realHost,)=explode(':',$_SERVER['HTTP_HOST']);
   return $realHost;
}

Quando você consideraria usar um sobre o outro e por quê?


Como mencionei nesta resposta , se o servidor for executado em uma porta diferente de 80 (como pode ser comum em uma máquina de desenvolvimento / intranet), o HTTP_HOST conterá a porta, enquanto SERVER_NAME não.

$_SERVER['HTTP_HOST'] == 'localhost:8080'
$_SERVER['SERVER_NAME'] == 'localhost'

(Pelo menos é o que eu notei em virtualhosts baseados em porta Apache)

Observe que o HTTP_HOST não contém :443 quando executado em HTTPS (a menos que você esteja executando em uma porta não padrão, que eu não testei).

Como outros notaram, os dois também diferem ao usar o IPv6:

$_SERVER['HTTP_HOST'] == '[::1]'
$_SERVER['SERVER_NAME'] == '::1'

Depende do que eu quero descobrir. SERVER_NAME é o nome do host do servidor, enquanto HTTP_HOST é o host virtual ao qual o cliente está conectado.


O HTTP_HOST é obtido do cabeçalho da solicitação HTTP e é isso que o cliente realmente usou como "host de destino" da solicitação. O SERVER_NAME é definido na configuração do servidor. Qual deles usar depende do que você precisa para isso. Agora, você deve perceber que um é um valor controlado pelo cliente, que pode, portanto, não ser confiável para uso na lógica de negócios e o outro é um valor controlado pelo servidor, que é mais confiável. No entanto, você precisa garantir que o servidor da Web em questão tenha o SERVER_NAME configurado corretamente. Tomando o Apache HTTPD como exemplo, aqui está um extrato de sua documentação :

Se nenhum ServerName for especificado, o servidor tentará deduzir o nome do host executando uma pesquisa inversa no endereço IP. Se nenhuma porta for especificada no ServerName , o servidor usará a porta da solicitação de entrada. Para confiabilidade e previsibilidade ideais, você deve especificar um nome de host e uma porta explícitos usando a diretiva ServerName .

Update : depois de verificar a resposta de Pekka em sua pergunta que contém um link para a resposta de bobince que o PHP sempre retornaria o valor de HTTP_HOST para SERVER_NAME , o que vai contra minhas próprias experiências PHP 4.x + Apache HTTPD 1.2.x de um par de anos atrás, eu tirei um pouco de poeira do meu ambiente XAMPP atual no Windows XP (Apache HTTPD 2.2.1 com PHP 5.2.8), iniciei, criei uma página PHP que imprime os dois valores, criei um aplicativo de teste Java usando URLConnection para modificar o cabeçalho do Host e os testes me ensinaram que isso é realmente (incorretamente) o caso.

Depois de primeiro suspeitar de PHP e vasculhar alguns relatórios de bugs do PHP sobre o assunto, aprendi que a raiz do problema está no servidor web usado, que ele retornou incorretamente o cabeçalho do Host HTTP quando SERVER_NAME foi solicitado. Então eu procurei os relatórios de bugs do Apache HTTPD usando várias palavras-chave sobre o assunto e finalmente encontrei um bug relacionado . Esse comportamento foi introduzido desde o entorno do Apache HTTPD 1.3. Você precisa configurar a diretiva UseCanonicalName para UseCanonicalName na entrada <VirtualHost> do ServerName no httpd.conf (também verifique o aviso na parte inferior do UseCanonicalName !).

<VirtualHost *>
    ServerName example.com
    UseCanonicalName on
</VirtualHost> 

Isso funcionou para mim.

Resumido, o SERVER_NAME é mais confiável, mas você depende da configuração do servidor!


Supondo que um tenha uma configuração simples (CentOS 7, Apache 2.4.xe PHP 5.6.20) e apenas um site (não assumindo hospedagem virtual) ...

No sentido do PHP, $_SERVER['SERVER_NAME'] é um elemento que o PHP registra no superglobal $_SERVER baseado na sua configuração do Apache ( **ServerName** diretiva com UseCanonicalName On ) no httpd.conf (seja de um host virtual incluído arquivo de configuração, qualquer que seja, etc ...). HTTP_HOST é derivado do cabeçalho do host HTTP. Trate isso como entrada do usuário. Filtrar e validar antes de usar.

Aqui está um exemplo de onde eu uso $_SERVER['SERVER_NAME'] como base para uma comparação. O método a seguir é de uma classe filha concreta que eu fiz chamada ServerValidator (filho do Validator ). ServerValidator verifica seis ou sete elementos em $ _SERVER antes de usá-los.

Ao determinar se a solicitação HTTP é POST, eu uso esse método.

public function isPOST()
{
    return (($this->requestMethod === 'POST')    &&  // Ignore
            $this->hasTokenTimeLeft()            &&  // Ignore
            $this->hasSameGETandPOSTIdentities() &&  // Ingore
            ($this->httpHost === filter_input(INPUT_SERVER, 'SERVER_NAME')));
}

No momento em que esse método é chamado, toda a filtragem e a validação de elementos relevantes do $ _SERVER teriam ocorrido (e o conjunto de propriedades relevantes).

A linha ...

($this->httpHost === filter_input(INPUT_SERVER, 'SERVER_NAME')

... verifica se o $_SERVER['HTTP_HOST'] (derivado do cabeçalho HTTP do host solicitado) corresponde a $_SERVER['SERVER_NAME'] .

Agora, estou usando falar superglobal para explicar meu exemplo, mas isso é apenas porque algumas pessoas não estão familiarizadas com INPUT_GET , INPUT_POST e INPUT_SERVER em relação a filter_input_array() .

A linha inferior é, eu não manejo solicitações POST no meu servidor, a menos que todas as quatro condições sejam atendidas. Portanto, em termos de solicitações POST, a falha em fornecer um cabeçalho de host HTTP (presença testada anteriormente) faz com que o erro ocorra para navegadores HTTP 1.0 estritos. Além disso, o host solicitado deve corresponder ao valor de ServerName no httpd.conf e, por extensão, ao valor de $_SERVER('SERVER_NAME') no superglobal $_SERVER . Mais uma vez, eu estaria usando INPUT_SERVER com as funções de filtro do PHP, mas você me entende.

Tenha em mente que o Apache usa frequentemente o ServerName em redirecionamentos padrão (como deixar a barra de uma URL: Exemplo, http://www.foo.com/ se tornando http://www.foo.com/ ), mesmo se você estiver não está usando reescrita de URL.

Eu uso $_SERVER['SERVER_NAME'] como padrão, não $_SERVER['HTTP_HOST'] . Há muitas idas e vindas nesta questão. $_SERVER['HTTP_HOST'] pode estar vazio, então isso não deve ser a base para criar convenções de código, como meu método público acima. Mas, só porque ambos podem ser definidos não garante que eles serão iguais. O teste é a melhor maneira de saber com certeza (tendo em mente a versão do Apache e a versão do PHP).


se você quiser verificar através de um server.php ou o que você quiser chamá-lo com o seguinte:

<?php

phpinfo(INFO_VARIABLES);

?>

ou

<?php

header("Content-type: text/plain");

print_r($_SERVER);

?>

Em seguida, acesse-o com todos os URLs válidos do seu site e confira a diferença.





server-variables