Obter domínio atual

140

Eu tenho meu site no servidor

http://www.myserver.uk.com

Para isso eu tenho dois domínios,

http://one.com

e

http://two.com

Gostaria de obter com o domínio atual do PHP, mas se eu usar $_SERVER['HTTP_HOST'], isso me mostrará

myserver.uk.com

ao invés de:

one.com or two.com

Como posso obter o domínio, não o nome do servidor?

Eu tenho o PHP versão 5.2.

Tony Evyght
fonte
Você só pode obter URl principal. Qual é a Primária dentre essas três?
Code Spy
2
Exatamente como seus dois domínios 'redirecionam' as solicitações para o seu servidor?
Xiaofeng.li
1
@infgeoax provavelmente um quadro ...
CodeCaster
primário é myserver.uk.com. Então, como posso obter o nome de domínio atual? Se i site aberto com endereço one.com eu gostaria get one.com vez de myserver.uk.com
Tony Evyght
@TonyEvyght, é esse o ponto que eu tento enfatizar, você deve obter o nome do host com o qual está se conectando $_SERVER['HTTP_HOST']. Se os sites one.come two.comestá "redirecionando" usando um (i) quadro, a própria página ainda vem de myserver.uk.com, assim você não vai obter o domínio real. Para que serve a fonte HTML one.com?
CodeCaster

Respostas:

175

Tente usar isto: $_SERVER['SERVER_NAME']

Ou analisar

$_SERVER['REQUEST_URI']

apache_request_headers ()

uma metade
fonte
23
-1: Somente com esta resposta, não sei exatamente o que as diferentes sugestões que estou procurando fazer. Claro, isso me dá um ponto para continuar procurando a partir, mas por si só isso não é realmente uma boa resposta ...
Jasper
4
apenas print_r (apache_request_headers ()) e você vai entender tudo :)
onehalf
2
@SarahLewis HTTP_X_ORIGINAL_HOSTpode ser modificado pelo usuário e não é confiável. Isso nem sempre pode ser um problema, mas é algo para estar ciente.
Wp-overwatch.com
64

O melhor uso seria

echo $_SERVER['HTTP_HOST'];

E pode ser usado assim:

if (strpos($_SERVER['HTTP_HOST'], 'banana.com') !== false) {
    echo "Yes this is indeed the banana.com domain";
}

Este código abaixo é uma boa maneira de ver todas as variáveis ​​em $ _SERVER em uma saída HTML estruturada com suas palavras-chave destacadas que param imediatamente após a execução. Já que às vezes esqueço qual usar - acho que isso pode ser bacana.

<?php
    // Change banana.com to the domain you were looking for..
    $wordToHighlight = "banana.com";
    $serverVarHighlighted = str_replace( $wordToHighlight, '<span style=\'background-color:#883399; color: #FFFFFF;\'>'. $wordToHighlight .'</span>',  $_SERVER );
    echo "<pre>";
    print_r($serverVarHighlighted);
    echo "</pre>";
    exit();
?>
K. Kilian Lindberg
fonte
39

Usar $_SERVER['HTTP_HOST']me (subdomínio.) Maindomain.extension. Parece a solução mais fácil para mim.

Se você estiver realmente 'redirecionando' por meio de um iFrame, poderá adicionar um parâmetro GET que indica o domínio.

<iframe src="myserver.uk.com?domain=one.com"/>

E então você pode definir uma variável de sessão que persista esses dados em todo o aplicativo.

Raz0rwire
fonte
1
o mais importante é que inclui o número da porta, para que eu não precise concatená-lo posteriormente. O phpinfo sugerido por bsdnoobz me ajuda a encontrar a solução certa.
30

A única maneira segura de fazer isso

Todas as outras respostas nesta página têm implicações de segurança que você precisa estar ciente.

O único método seguro garantido de recuperar o domínio atual é para 𝔂𝓸𝓾𝓻𝓼𝓮𝓵𝓯 𝓲𝓽 𝓲𝓷 𝓪 𝓼𝓮𝓬𝓾𝓻𝓮 𝓵𝓸𝓬𝓪𝓽𝓲𝓸𝓷.

A maioria das estruturas cuida de armazenar o domínio para você, portanto, você deve consultar a documentação para sua estrutura específica. Se você não estiver usando uma estrutura, considere armazenar o domínio em um dos seguintes locais:

+ ------------------------------------------------- --- + ----------------------------------- +
 | Métodos seguros de armazenamento do domínio | Usado por |
+ ------------------------------------------------- --- + ----------------------------------- +
 | Um arquivo de configuração | Joomla, Drupal / Symfony |
 | O banco de dados | WordPress |
 | Uma variável ambiental | Laravel
 | Um registro de serviço | DNS do Kubernetes |
+ ------------------------------------------------- --- + ----------------------------------- +


Você pode usar o seguinte ... mas eles não são seguros

Os hackers podem fazer com que essas variáveis ​​produzam o domínio que quiserem. Isso pode levar a envenenamento de cache e ataques de phishing quase imperceptíveis.

$_SERVER['HTTP_HOST']

Isso obtém o domínio dos cabeçalhos de solicitação abertos à manipulação por hackers . Mesmo com:

$_SERVER['SERVER_NAME']

Este pode ser melhorado se a configuração do Apache usecanonicalname estiver desativada; nesse caso $_SERVER['SERVER_NAME'], não será mais permitido preencher valores arbitrários e estará seguro. No entanto, isso não é o padrão e não é tão comum em uma instalação.


Em sistemas populares

Abaixo está como você pode obter o domínio atual nas seguintes estruturas / sistemas:

WordPress

$urlparts = parse_url(home_url());
$domain = $urlparts['host'];

Se você estiver construindo um URL no WordPress, use home_url ou site_url , ou qualquer outra função de URL .

Laravel

request()->getHost()

A request()->getHostfunção é herdada do Symfony e está segura desde que o CVE-2013-4752 de 2013 foi corrigido.

Drupal

O instalador ainda não se encarrega de torná-lo seguro ( problema nº 2404259 ). Mas no Drupal 8 há documentação que você pode seguir em Configurações do host confiável para proteger sua instalação do Drupal, após a qual o seguinte pode ser usado:

\Drupal::request()->getHost();

Outras estruturas

Sinta-se à vontade para editar esta resposta para incluir como obter o domínio atual em sua estrutura favorita. Ao fazer isso, inclua um link para o código-fonte relevante ou para qualquer outra coisa que me ajude a verificar se a estrutura está fazendo as coisas com segurança.




Termo aditivo

Exemplos de exploração:

  1. O envenenamento por cache pode ocorrer se uma botnet solicitar continuamente uma página usando o cabeçalho de hosts incorretos. O HTML resultante incluirá links para o site do invasor, onde eles poderão fraudar seus usuários. Inicialmente, os links maliciosos serão enviados apenas de volta ao hacker, mas se o hacker fizer solicitações suficientes, a versão maliciosa da página acabará no seu cache, onde será distribuída a outros usuários.

  2. Um ataque de phishing pode ocorrer se você armazenar links no banco de dados com base no cabeçalho do host. Por exemplo, digamos que você armazene o URL absoluto nos perfis de um usuário em um fórum. Ao usar o cabeçalho errado, um hacker pode fazer com que qualquer pessoa que clica no link do perfil seja enviada para um site de phishing.

  3. O envenenamento por redefinição de senha pode ocorrer se um hacker usar um cabeçalho de host malicioso ao preencher o formulário de redefinição de senha para um usuário diferente. Esse usuário receberá um e-mail contendo um link de redefinição de senha que leva a um site de phishing.

  4. Aqui estão alguns exemplos mais maliciosos

Advertências e notas adicionais:

  • Quando usecanonicalname está desativado, $_SERVER['SERVER_NAME']é preenchido com o mesmo cabeçalho$_SERVER['HTTP_HOST'] teria usado de qualquer maneira (mais a porta). Esta é a configuração padrão do Apache. Se você ou o devops ativam isso, então você está bem - ish - mas você realmente quer confiar em uma equipe separada, ou em você mesmo daqui a três anos, para manter o que parece ser uma configuração menor em um ambiente não -valor padrão? Mesmo que isso torne as coisas seguras, eu recomendaria não confiar nessa configuração.
  • O Redhat, no entanto, é ativado por via canônica por padrão [ fonte ].
  • Se serverAlias for usado na entrada de hosts virtuais e o domínio aliasado for solicitado, $_SERVER['SERVER_NAME']não retornará o domínio atual, mas retornará o valor da diretiva serverName.
  • Se o serverName não puder ser resolvido, o comando hostname do sistema operacional será usado em seu lugar [origem] .
  • Se o cabeçalho do host for deixado de fora, o servidor se comportará como se o usecanonical estivesse em [origem] .
  • Por fim, tentei explorar isso no meu servidor local e não consegui falsificar o cabeçalho do host. Não tenho certeza se houve uma atualização no Apache que abordou isso, ou se eu estava apenas fazendo algo errado. Independentemente disso, esse cabeçalho ainda seria explorável em ambientes onde os hosts virtuais não estão sendo usados.

Little Rant:

     Esta pergunta recebeu centenas de milhares de visualizações sem uma única menção aos problemas de segurança em questão! Não deve ser assim, mas apenas porque uma resposta de estouro de pilha é popular, isso não significa que é segura.



wp-overwatch.com
fonte
1
Você pode mencionar a diferença entre home_url e site_url. wordpress.stackexchange.com/a/50605/13
Volomike:
1
+1 para usuários do wordpress. Bom se você precisar examinar se instalado no subdir, mas observe que a chave parse_url: $urlparts['path']não está configurada se estiver instalada no diretório raiz do domínio. Senão $urlparts['path']retorna o subdiretório.
Jonas Lundman # 23/18
9

Tente $_SERVER['SERVER_NAME'].

Dicas: Crie um arquivo PHP que chama a função phpinfo()e consulte a seção "Variáveis ​​PHP". Há um monte de variáveis ​​úteis em que nunca pensamos lá.

Flui livremente
fonte
Você pode sempre tentar print_r-ing o $ _SERVER e pesquisa
3

Sei que isso pode não estar totalmente relacionado ao assunto, mas, na minha experiência, acho útil armazenar o WWW-ness da URL atual em uma variável.

Edit: Além disso, por favor, veja o meu comentário abaixo, para ver o que isso está acontecendo.

Isso é importante ao determinar se deve enviar chamadas Ajax com "www" ou sem:

$.ajax("url" : "www.site.com/script.php", ...

$.ajax("url" : "site.com/script.php", ...

Ao despachar uma chamada Ajax, o nome do domínio deve corresponder ao da barra de endereços do navegador, caso contrário você terá o Uncaught SecurityError no console.

Então, eu vim com esta solução para resolver o problema:

<?php
    substr($_SERVER['SERVER_NAME'], 0, 3) == "www" ? $WWW = true : $WWW = false;

    if ($WWW) {
        /* We have www.example.com */
    } else {
        /* We have example.com */
    }
?>

Em seguida, com base em se $ WWW é verdadeiro ou falso, execute a chamada Ajax adequada.

Sei que isso pode parecer trivial, mas esse é um problema tão comum que é fácil tropeçar.

InfiniteStack
fonte
O OP pediu explicitamente o domínio, e não o SERVER_NAME .
Sebastian G. Marinescu
É verdade, mas hoje em dia você também precisa se preocupar com o problema do www.
InfiniteStack
Por quê? Em JS, você pode procurar window.location. Em PHP você conseguiu SERVER_NAME.
Sebastian G. Marinescu
4
SERVER_NAME retorna "www.site.com" mesmo quando "site.com" é inserido na barra de endereços. Se você estiver usando SERVER_NAME em todo o código, inevitavelmente encontrará o problema de segurança www / no-www, especialmente quando se trata de fazer chamadas para o Ajax. Mas, para responder à sua pergunta, na programação avançada do PHP, algumas vezes o PHP precisa gerar dinamicamente o código que faz uma chamada HTTP para o servidor. Se o URL de destino contiver "www" em uma página que não contém, ele gerará um erro de segurança.
InfiniteStack
Ok ok ... Eu li sobre isso e você está certo. Portanto, sua resposta pode ser relevante para alguém. Bom trabalho :)
Sebastian G. Marinescu
3

Todo mundo está usando a parse_urlfunção, mas às vezes o usuário pode passar o argumento em um formato diferente.

Para corrigir isso, eu criei a função. Veja isso:

function fixDomainName($url='')
{
    $strToLower = strtolower(trim($url));
    $httpPregReplace = preg_replace('/^http:\/\//i', '', $strToLower);
    $httpsPregReplace = preg_replace('/^https:\/\//i', '', $httpPregReplace);
    $wwwPregReplace = preg_replace('/^www\./i', '', $httpsPregReplace);
    $explodeToArray = explode('/', $wwwPregReplace);
    $finalDomainName = trim($explodeToArray[0]);
    return $finalDomainName;
}

Basta passar o URL e obter o domínio.

Por exemplo,

echo fixDomainName('https://stackoverflow.com');

retornará o resultado será

stackoverflow.com

E em alguma situação:

echo fixDomainName('stackoverflow.com/questions/id/slug');

E também retornará stackoverflow.com.

Manojkiran.A
fonte
1
$_SERVER['HTTP_HOST'] 

// para obter o domínio

$protocol=strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
$domainLink=$protocol.'://'.$_SERVER['HTTP_HOST'];

// domínio com protocolo

$url=$protocol.'://'.$_SERVER['HTTP_HOST'].'?'.$_SERVER['QUERY_STRING'];

// protocolo, domínio, queryString total ** Como o $ _SERVER ['SERVER_NAME'] não é confiável para hospedagem de vários domínios!

Sarkar
fonte
-2

Simplesmente tente:

echo apache_request_headers()[3];
Movimento
fonte