2010-07-09 14 views
13

Necesito obtener el nombre de dominio de una URL. Los siguientes ejemplos deben devolver todo google.com:¿Cómo obtener el nombre de dominio base de una URL usando PHP?

google.com 
images.google.com 
new.images.google.com 
www.google.com 

Del mismo modo las siguientes URL debe devolver todo google.co.uk.

google.co.uk 
images.google.co.uk 
new.images.google.co.uk 
http://www.google.co.uk 

estoy reticentes a utilizar expresiones regulares, porque algo así como domain.com/google.com podría devolver resultados incorrectos.

¿Cómo puedo obtener el dominio de nivel superior utilizando PHP? Esto debe funcionar en todas las plataformas y hosts.

+1

Esto es complicado. Para 'google.com', le interesan los nombres de dominio de segundo nivel y TLD. Para 'google.co.uk', desea los nombres de dominio de TLD y segundo y tercer nivel. No hay un "nombre base" definido, lo que quiere decir con "nombre base" es diferente para los diferentes registradores/TLD. – deceze

+1

Estoy bastante seguro de que tienes que ponerte un poco largo aquí, lo que estás pidiendo es comer tu torta y tenerla también. Sin una lista de TLD no hay forma de diferenciar entre co.uk y google.com, ambos son el nombre de host. –

+0

Supongo que ustedes tienen razón, no parece que nada va a funcionar sin un montón de código – Rohan

Respuesta

16

usted puede hacer esto:

$urlData = parse_url($url); 

$host = $urlData['host']; 

** Actualización **

La mejor manera que puedo pensar es tener un mapeo de todos los dominios de primer nivel que desea manejar, ya que ciertos TLD pueden ser complicados (co.uk).

// you can add more to it if you want 
$urlMap = array('com', 'co.uk'); 

$host = ""; 
$url = "http://www.google.co.uk"; 

$urlData = parse_url($url); 
$hostData = explode('.', $urlData['host']); 
$hostData = array_reverse($hostData); 

if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
} elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
    $host = $hostData[1] . '.' . $hostData[0]; 
} 

echo $host; 
3

Intente utilizar: http://php.net/manual/en/function.parse-url.php. Algo como esto debería funcionar:

$urlParts = parse_url($yourUrl); 
$hostParts = explode('.', $urlParts['host']); 
$hostParts = array_reverse($hostParts); 
$host = $hostParts[1] . '.' . $hostParts[0]; 
+1

Eso se rompería si tiene algo como esto: http: //www.google.co.uk - en ese caso, devolvería "co.uk". – xil3

+1

De hecho, la única manera de obtener eso ordenado es mediante el uso de una lista de TLD. –

-3

Utilice esta función:

function getHost($url){ 
    if (strpos($url,"http://")){ 
     $httpurl=$url; 
    } else { 
     $httpurl="http://".$url; 
    } 
    $parse = parse_url($httpurl); 
    $domain=$parse['host']; 

    $portion=explode(".",$domain); 
    $count=sizeof($portion)-1; 
    if ($count>1){ 
     $result=$portion[$count-1].".".$portion[$count]; 
    } else { 
     $result=$domain; 
    } 
    return $result; 
} 

Respuesta todas las variantes del ejemplo de URL.

5

dominios de primer nivel y dominios de segundo nivel pueden tener 2 caracteres de longitud pero un subdominio registrado debe tener al menos 3 caracteres de longitud.

EDIT: debido al comentario de pjv, aprendí que los nombres de dominio australianos son una excepción porque permiten 5 TLD como SLD (com, net, org, asn, id) ejemplo: somedomain.com.au. Supongo que com.au es un nombre de dominio controlado nacionalmente que "comparte". entonces, técnicamente, "com.au" aún sería el "dominio base", pero eso no es útil.

EDITAR: hay 47,952 nombres de dominio de tres letras posibles (patrón: [a-zA-Z0-9] [a-zA-Z0-9 -] [a-zA-Z0-9] o 36 * 37 * 36) combinado con solo 8 de los TLDS más comunes (com, org, etc.) tenemos 383,616 posibilidades, sin siquiera agregar todo el alcance de los TLD. Los nombres de dominio de 1 y 2 letras aún existen, pero no son válidos en el futuro.

en google.com - "google" es un subdominio de "com"

en google.co.uk - "google" es un subdominio de "co", que a su vez es un subdominio de "Reino Unido", o un dominio de segundo nivel realmente, ya que "co" también es un dominio de nivel superior válido

en www.google.com - "www" es un subdominio de "google" que es un subdominio de "com"

"co.uk" no es un host válida porque no hay un nombre de dominio válido

ir con esa assumpt Esta función devolverá el "dominio basado" apropiado en casi todos los casos, sin requerir un "mapa de url".

Si usted es uno de los pocos casos, quizás pueda modificar esto para satisfacer sus necesidades particulares ...

EDITAR: debe pasar la cadena del dominio como una URL con su protocolo (http: //, ftp: //, etc.) o parse_url() no lo considerará una URL válida (a menos que desee modificar el código para comportarse de manera diferente)

function basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

si tiene que ser el uso exacto fopen o curl para abrir esta URL: http://data.iana.org/TLD/tlds-alpha-by-domain.txt

luego leer las líneas en una matriz y utilizar eso para comparar las partes dominio

EDIT: para permitir dominios de Australia:

function au_basedomain($str = '') 
{ 
    // $str must be passed WITH protocol. ex: http://domain.com 
    $url = @parse_url($str); 
    if (empty($url['host'])) return; 
    $parts = explode('.', $url['host']); 
    $slice = (strlen(reset(array_slice($parts, -2, 1))) == 2) && (count($parts) > 2) ? 3 : 2; 
    if (preg_match('/\.(com|net|asn|org|id)\.au$/i', $url['host'])) $slice = 3; 
    return implode('.', array_slice($parts, (0 - $slice), $slice)); 
} 

NOTAS ADICIONALES IMPORTANTE: No utilizar esta función para validar dominios. Es un código genérico que solo uso para extraer el dominio base para el servidor en el que se ejecuta desde el $_SERVER['SERVER_NAME'] global para su uso dentro de varios scripts internos. Teniendo en cuenta que solo he trabajado en sitios dentro de los EE. UU., Nunca me he encontrado con las variantes australianas sobre las que pjv preguntó. Es útil para uso interno, pero está muy lejos de un proceso completo de validación de dominio. Si está intentando usarlo de esta forma, le recomiendo que no lo haga porque hay demasiadas posibilidades para unir dominios no válidos.

+1

Si cambia ese 'strlen() == 2' a' <= 3', obtendrá el 99% de los dominios, guardará los subdominios en el localhost y lo que sea. Aquí está mi revisión arreglada: https://gist.github.com/anonymous/fe77c97e632675411c3c – Mahn

+0

No, la revisión no funciona correctamente. Tiene que ser == 2 porque <= 3 coincidirá cuando la próxima a la última parte sea 3, lo que no queremos hacer. Queremos que devuelva "google.com" de "www.google.com" o "mail.google.com", y queremos que devuelva "google.co.uk" de "www.google.co.uk" o "mail.google.co.uk" – aequalsb

+0

@Mahn Además, hay muchos bits adicionales en su revisión: asignaciones de variables innecesarias y anidación de condición innecesaria. Más código y resultado no deseado: ¿ha probado su revisión a fondo? – aequalsb

0

Mezclando con xil3 responda esto, tengo que comprobar localhost y también ip, por lo que también puede trabajar en un entorno de desarrollo.
Aún debe definir qué TLD desea usar. aparte de eso todo funciona bien.

<?php 
function getTopLevelDomain($url){ 
    $urlData = parse_url($url); 
    $urlHost = isset($urlData['host']) ? $urlData['host'] : ''; 
    $isIP = (bool)ip2long($urlHost); 
    if($isIP){ /** To check if it's ip then return same ip */ 
     return $urlHost; 
    } 
    /** Add/Edit you TLDs here */ 
    $urlMap = array('com', 'com.pk', 'co.uk'); 

    $host = ""; 
    $hostData = explode('.', $urlHost); 
    if(isset($hostData[1])){ /** To check "localhost" because it'll be without any TLDs */ 
     $hostData = array_reverse($hostData); 

     if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0]; 
     } elseif(array_search($hostData[0], $urlMap) !== FALSE) { 
      $host = $hostData[1] . '.' . $hostData[0]; 
     } 
     return $host; 
    } 
    return ((isset($hostData[0]) && $hostData[0] != '') ? $hostData[0] : 'error no domain'); /* You can change this error in future */ 
} 
?> 

se puede utilizar de esta manera

$string = 'http://googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com.pk:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://adad.asdasd.googl.com:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101:23'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://192.168.0.101'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'http://localhost'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = 'https;//'; 
echo getTopLevelDomain($string) . '<br>'; 

$string = ''; 
echo getTopLevelDomain($string) . '<br>'; 

Usted obtendrá como resultado cadena como esta

googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
googl.com.pk 
googl.com.pk 
googl.com 
googl.com 
192.168.0.101 
192.168.0.101 
localhost 
error no domain 
error no domain 
Cuestiones relacionadas