@Mike Lewis - Isso resolve o problema de vários subdomínios, como usa.en.example.com? Apenas pensando (minha própria resposta não, aliás).
Jared Farrish
@Jared, acabou de adicionar uma solução para detectar vários subdomínios.
Mike Lewis
1
@Mike - Isso funcionará com tx.usa.en.example.com? (ou science.news.bbc.co.uk )? (aliás, esse não é um link funcional, apenas um exemplo, embora news.bbc.co.uk funcione)
Jared Farrish
4
Isso funciona para tudo que tem um único TLD de 'palavra' como net, com, biz etc. No entanto, ao lidar com co.uk, por exemplo, não funciona. Como visto aqui, este é realmente um problema mais difícil de resolver.
Mike Lewis
2
isso também falhará se não houver subdomínio.
raveren
32
Você pode fazer isso primeiro obtendo o nome do domínio (por exemplo, sub.example.com => example.co.uk) e, em seguida, use strstr para obter os subdomínios.
Esta parece ser a melhor solução, pois também permite domínios sem um subdomínio, em vez de refazer o nome do domínio como o subdomínio sendo a parte antes do primeiro ponto. Muito útil para verificar a existência de um subdomínio.
Karl MW
Eu precisava obter o domínio "base" (sem o subdomínio), e estava fazendo minha própria solução explodindo o host e obtendo os últimos elementos da matriz com um forloop, mas tive que verificar seu comprimento (para detectar se eles eram parte do domínio, como "co.uk"). Na verdade, sua solução é muito mais simples do que o que eu estava fazendo. Regex salvar vidas, obrigado!
Yoone
1
Incrível .. isso funciona tão bem para todos os tipos de domínio e subdomínios .. bom.
jon
2
enquanto esta solução é muito limpo e pode trabalhar em quase todos os casos, estar ciente de que nomes de domínios pode ter mais de 6 caracteres, como pvt.k12.ma.us, health.vnou mesmo k12.ak.us. Além disso, os nomes de domínio podem usar o conjunto de caracteres chinês ou russo para que a parte do regex [a-z\.]{2,6}não corresponda a eles. Confira aqui para ter exemplos de nomes de domínios: publicsuffix.org/list
Como a única fonte confiável de sufixos de domínio são os registradores de domínio, você não pode encontrar o subdomínio sem seu conhecimento. Existe uma lista com todos os sufixos de domínio em https://publicsuffix.org . Este site também tem um link para uma biblioteca PHP: https://github.com/jeremykendall/php-domain-parser .
Por favor, encontre um exemplo abaixo. Também adicionei a amostra para en.test.co.uk, que é um domínio com um sufixo múltiplo (co.uk).
PS - Não tenho ideia do que está escrito no texto russo. Peguei algumas palavras casuais de ru.wikipedia.org ;)
Kamafeather
Não é ucraniano? .uaé o código do país da Ucrânia.
basicamente
Não. Apenas informações misturadas. Mas não tenho certeza, não sou bom o suficiente para distingui-los;)
Kamafeather
3
Em relação ao russo, uma tradução do google do russo para o inglês volta como "valores publicados" (caso alguém estivesse curioso como eu)
Jeremy Harris,
@Kamafeather isso parece à prova de balas. Alguma maneira de conseguir o $match[1]papel? $match[0]parece desnecessário.
Andres SK
3
$REFERRER = $_SERVER['HTTP_REFERER'];// Or other method to get a URL for decomposition
$domain = substr($REFERRER, strpos($REFERRER,'://')+3);
$domain = substr($domain,0, strpos($domain,'/'));// This line will return 'en' of 'en.example.com'
$subdomain = substr($domain,0, strpos($domain,'.'));
Existem maneiras melhores de detectar automaticamente o host atual (como $_SERVER['HTTP_HOST']) do que confiar em um cabeçalho de referência capaz de falsificar, assumindo que essa é a ideia geral por trás da resposta.
Mateus
Certo, eu estava usando um código antigo. O exemplo ainda permanece, no entanto. Essa não é a raiz da questão.
Jared Farrish
Só para somar os comentários acima, confiar em $ _SERVER ['HTTP_HOST'] pode não ser eficiente, pois há uma chance de que ele não esteja definido.
gmslzr de
2
PHP 7.0: Use a função explodir e crie uma lista de todos os resultados.
Na verdade, não existe uma solução 100% dinâmica - também estou tentando descobrir isso e, devido às diferentes extensões de domínio (DTL), essa tarefa seria realmente difícil sem realmente analisar todas essas extensões e verificá-las a cada vez:
.com vs .co.uk vs org.uk
A opção mais confiável é definir uma constante (ou entrada de banco de dados etc.) que armazena o nome de domínio real e removê-lo do $_SERVER['SERVER_NAME']usosubstr()
Agora, se você estiver usando esta função com o http://test.mymaindomain.co.ukque lhe dará testou se você tem vários níveis de sub-domínio http://another.test.mymaindomain.co.ukvocê vai ter another.test- a menos que você atualizar o DOMAIN.
Usar regex, funções de string, parse_url () ou suas combinações não é uma solução real. Basta testar qualquer uma das soluções propostas com domínio test.en.example.co.uk, não haverá nenhum resultado correto.
A solução correta é usar o pacote que analisa o domínio com a Lista de sufixos públicos . Eu recomendo TLDExtract , aqui está o código de amostra:
$extract =newLayerShifter\TLDExtract\Extract();
$result = $extract->parse('test.en.example.co.uk');
$result->getSubdomain();// will return (string) 'test.en'
$result->getSubdomains();// will return (array) ['test', 'en']
$result->getHostname();// will return (string) 'example'
$result->getSuffix();// will return (string) 'co.uk'
// For www.abc.en.example.com
$host_Array = explode(".",$_SERVER['HTTP_HOST']);// Get HOST as array www, abc, en, example, com
array_pop($host_Array); array_pop($host_Array);// Remove com and exmaple
array_shift($host_Array);// Remove www (Optional)
echo implode($host_Array,".");// Combine array abc.en
Cortei a substring em 12 em vez de 11 porque as substrings começam em 1 para o segundo parâmetro. Portanto, agora, se você inserisse test.example.com, o valor de $subdomainseria test.
Isso é melhor do que usar explodeporque se o subdomínio tiver um .nele, isso não o cortará.
Isso só funcionará se não houver wwwno início da string. Abordagem um pouco trivial demais.
FooBar
Isso simplifica as coisas para outros desenvolvedores da equipe, prefiro usar isso do que alguma experiência de registro avançada. Se você quiser cortar www, use trim ($ s, 'www'); ou apenas ajustá-lo à sua lógica de negócios ...
tasmaniski
1
Para fins de integridade, wwwé na verdade um subdomínio. É comumente um alias para o próprio nome de domínio por razões históricas.
Usamos esta função para lidar com vários subdomínios e vários tld também para lidar com ip e localhost
function analyse_host($_host){
$my_host = explode('.', $_host);
$my_result =['subdomain'=>null,'root'=>null,'tld'=>null];// if host is ip, only set as rootif(filter_var($_host, FILTER_VALIDATE_IP)){// something like 127.0.0.5
$my_result['root']= $_host;}
elseif(count($my_host)===1){// something like localhost
$my_result['root']= $_host;}
elseif(count($my_host)===2){// like jibres.com
$my_result['root']= $my_host[0];
$my_result['tld']= $my_host[1];}
elseif(count($my_host)>=3){// some conditons like// ermile.ac.ir// ermile.jibres.com// ermile.jibres.ac.ir// a.ermile.jibres.ac.ir// get last one as tld
$my_result['tld']=end($my_host);
array_pop($my_host);// check last one after remove is probably tld or not
$known_tld =['com','org','net','gov','co','ac','id','sch','biz'];
$probably_tld =end($my_host);if(in_array($probably_tld, $known_tld)){
$my_result['tld']= $probably_tld.'.'. $my_result['tld'];
array_pop($my_host);}
$my_result['root']=end($my_host);
array_pop($my_host);// all remain is subdomainif(count($my_host)>0){
$my_result['subdomain']= implode('.', $my_host);}}return $my_result;}
E se houver um manipulador de protocolo no início, como http: //, https: //, ftp: //, etc ...? ;)
Jared Farrish
@Jared, não há protocolo na string que ele está tentando analisar ... Mas se houvesse, eu usaria parse_url()para extrair o host.
Mateus
Portanto, fornecemos duas abordagens que serão apropriadas em contextos diferentes.
Jared Farrish
Principalmente, estou feliz que alguém não postou uma resposta regex (ainda). Sem falar que a última linha da minha resposta também realiza a mesma coisa que a sua.
(^|://)(.*)\.
e capture o.*
? Eu prefiro ser péssimo em php e regex, mas isso vem à mente.en.foo.bar.example.com
ouen.example.co.uk
?Respostas:
Aqui está uma solução de uma linha:
Ou usando seu exemplo:
EDIT: Corrigido "apenas variáveis devem ser passadas por referência", adicionando parênteses duplos.
EDIT 2 : A partir do PHP 5.4, você pode simplesmente fazer:
fonte
explode(...)[0]
vez de usar o turno atualmente? Há vários anos que não faço PHP.Strict Standards: Only variables should be passed by reference.
www.en.example.com
e retornewww
como subdomínio.Usa a função parse_url .
Para vários subdomínios
fonte
Você pode fazer isso primeiro obtendo o nome do domínio (por exemplo, sub.example.com => example.co.uk) e, em seguida, use strstr para obter os subdomínios.
Saídas:
fonte
for
loop, mas tive que verificar seu comprimento (para detectar se eles eram parte do domínio, como "co.uk"). Na verdade, sua solução é muito mais simples do que o que eu estava fazendo. Regex salvar vidas, obrigado!pvt.k12.ma.us
,health.vn
ou mesmok12.ak.us
. Além disso, os nomes de domínio podem usar o conjunto de caracteres chinês ou russo para que a parte do regex[a-z\.]{2,6}
não corresponda a eles. Confira aqui para ter exemplos de nomes de domínios: publicsuffix.org/listhttp://php.net/parse_url
fonte
Como a única fonte confiável de sufixos de domínio são os registradores de domínio, você não pode encontrar o subdomínio sem seu conhecimento. Existe uma lista com todos os sufixos de domínio em https://publicsuffix.org . Este site também tem um link para uma biblioteca PHP: https://github.com/jeremykendall/php-domain-parser .
Por favor, encontre um exemplo abaixo. Também adicionei a amostra para en.test.co.uk, que é um domínio com um sufixo múltiplo (co.uk).
fonte
Solução mais simples e rápida.
fonte
Simplesmente...
Basta ler $ match [1]
Exemplo de trabalho
Funciona perfeitamente com esta lista de urls
fonte
.ua
é o código do país da Ucrânia.$match[1]
papel?$match[0]
parece desnecessário.fonte
$_SERVER['HTTP_HOST']
) do que confiar em um cabeçalho de referência capaz de falsificar, assumindo que essa é a ideia geral por trás da resposta.PHP 7.0: Use a função explodir e crie uma lista de todos os resultados.
Exemplo: sub.domain.com
Resultado: sub
Resultado: domínio
fonte
.co.uk
- seu snippet não funcionará com esses TLDsO que eu encontrei a melhor e mais curta solução é
fonte
Para aqueles que receberem 'Erro: Padrões rígidos: apenas variáveis devem ser passadas por referência. Use assim:
$env = (explode(".",$_SERVER['HTTP_HOST'])); $env = array_shift($env);
fonte
Como visto na pergunta anterior: Como obter o primeiro subdomínio com PHP?
fonte
Na verdade, não existe uma solução 100% dinâmica - também estou tentando descobrir isso e, devido às diferentes extensões de domínio (DTL), essa tarefa seria realmente difícil sem realmente analisar todas essas extensões e verificá-las a cada vez:
.com vs .co.uk vs org.uk
A opção mais confiável é definir uma constante (ou entrada de banco de dados etc.) que armazena o nome de domínio real e removê-lo do
$_SERVER['SERVER_NAME']
usosubstr()
Agora, se você estiver usando esta função com o
http://test.mymaindomain.co.uk
que lhe darátest
ou se você tem vários níveis de sub-domíniohttp://another.test.mymaindomain.co.uk
você vai teranother.test
- a menos que você atualizar oDOMAIN
.Eu espero que isso ajude.
fonte
Simplesmente
reset(explode(".", $_SERVER['HTTP_HOST']))
fonte
Usar regex, funções de string, parse_url () ou suas combinações não é uma solução real. Basta testar qualquer uma das soluções propostas com domínio
test.en.example.co.uk
, não haverá nenhum resultado correto.A solução correta é usar o pacote que analisa o domínio com a Lista de sufixos públicos . Eu recomendo TLDExtract , aqui está o código de amostra:
fonte
esta é a minha solução, ela funciona com os domínios mais comuns, você pode ajustar a variedade de extensões conforme necessário:
fonte
fonte
Eu sei que estou muito atrasado para o jogo, mas aqui vai.
O que fiz foi pegar a variável do servidor HTTP_HOST (
$_SERVER['HTTP_HOST']
) e o número de letras no domínio (então paraexample.com
ele seria 11).Então usei a
substr
função para obter o subdomínio. eu fizCortei a substring em 12 em vez de 11 porque as substrings começam em 1 para o segundo parâmetro. Portanto, agora, se você inserisse test.example.com, o valor de
$subdomain
seriatest
.Isso é melhor do que usar
explode
porque se o subdomínio tiver um.
nele, isso não o cortará.fonte
se você estiver usando drupal 7
isso vai te ajudar:
fonte
fonte
No PHP 5.3 você pode usar strstr () com o parâmetro true
fonte
www
no início da string. Abordagem um pouco trivial demais.www
é na verdade um subdomínio. É comumente um alias para o próprio nome de domínio por razões históricas.Experimente isso ...
fonte
fonte
$host = explode('.', isset($parsedUrl['path']) ? $parsedUrl['path'] : $parsedUrl['host']);
você pode usar isso também
fonte
Estou fazendo algo assim
fonte
Usamos esta função para lidar com vários subdomínios e vários tld também para lidar com ip e localhost
fonte
Suponha que url atual = sub.example.com
fonte
Se você quiser apenas o que vem antes do primeiro período:
fonte
parse_url()
para extrair o host.