Saltar al contenido

Obtener el nombre de dominio (no el subdominio) en php

Gerardo, parte de este gran staff, nos hizo el favor de redactar este escrito ya que conoce muy bien dicho tema.

Solución:

Bueno, puedes usar parse_url para conseguir el anfitrión:

$info = parse_url($url);
$host = $info['host'];

Luego, puede hacer algunas cosas elegantes para obtener solo el TLD y el Host

$host_names = explode(".", $host);
$bottom_host_name = $host_names[count($host_names)-2] . "." . $host_names[count($host_names)-1];

No es muy elegante, pero debería funcionar.


Si quieres una explicación, aquí va:

Primero tomamos todo entre el esquema (http://, etc.), usando parse_urlcapacidades de … bueno … analizar URL. 🙂

Luego tomamos el nombre de host y lo separamos en un array basado en donde caen los periodos, entonces test.world.hello.myname se convertiría:

array("test", "world", "hello", "myname");

Después de eso, tomamos el número de elementos en el array (4).

Luego, le restamos 2 para obtener el penúltimo string (el nombre de host, o example, en tu ejemplo)

Luego, le restamos 1 para obtener el último string (porque array keys empezar en 0), también conocido como TLD

Luego combinamos esas dos partes con un punto, y tienes tu nombre de host base.

No es posible obtener el nombre de dominio sin usar una lista de TLD para comparar, ya que existen muchos casos con completamente la misma estructura y longitud:

  1. www.db.de (subdominio) versus bbc.co.uk (dominio)
  2. big.uk.com (SLD) frente a www.uk.com (TLD)

La lista de sufijos públicos de Mozilla debería ser la mejor opción, ya que la utilizan todos los navegadores principales:
https://publicsuffix.org/list/public_suffix_list.dat

Siéntete libre de usar mi función:

function tld_list($cache_dir=null) 
    // we use "/tmp" if $cache_dir is not set
    $cache_dir = isset($cache_dir) ? $cache_dir : sys_get_temp_dir();
    $lock_dir = $cache_dir . '/public_suffix_list_lock/';
    $list_dir = $cache_dir . '/public_suffix_list/';
    // refresh list all 30 days
    if (file_exists($list_dir) && @filemtime($list_dir) + 2592000 > time()) 
        return $list_dir;
    
    // use exclusive lock to avoid race conditions
    if (!file_exists($lock_dir) && @mkdir($lock_dir)) 
        // read from source
        $list = @fopen('https://publicsuffix.org/list/public_suffix_list.dat', 'r');
        if ($list) 
            // the list is older than 30 days so delete everything first
            if (file_exists($list_dir)) 
                foreach (glob($list_dir . '*') as $filename) 
                    unlink($filename);
                
                rmdir($list_dir);
            
            // now set list directory with new timestamp
            mkdir($list_dir);
            // read line-by-line to avoid high memory usage
            while ($line = fgets($list)) 
            fclose($list);
        
        @rmdir($lock_dir);
    
    // repair locks (should never happen)
    if (file_exists($lock_dir) && mt_rand(0, 100) == 0 && @filemtime($lock_dir) + 86400 < time()) 
        @rmdir($lock_dir);
    
    return $list_dir;

function get_domain($url=null) 

Lo que hace especial:

  • acepta todas las entradas como URL, nombres de host o dominios con o sin esquema
  • la lista se descarga fila por fila para evitar un uso elevado de memoria
  • crea un nuevo archivo por TLD en una carpeta de caché, por lo que get_domain() solo necesita revisar file_exists() si existe, no necesita incluir una base de datos enorme en cada solicitud como lo hace TLDExtract.
  • la lista se actualizará automáticamente cada 30 días

Prueba:

$urls = array(
    'http://www.example.com',// example.com
    'http://subdomain.example.com',// example.com
    'http://www.example.uk.com',// example.uk.com
    'http://www.example.co.uk',// example.co.uk
    'http://www.example.com.ac',// example.com.ac
    'http://example.com.ac',// example.com.ac
    'http://www.example.accident-prevention.aero',// example.accident-prevention.aero
    'http://www.example.sub.ar',// sub.ar
    'http://www.congresodelalengua3.ar',// congresodelalengua3.ar
    'http://congresodelalengua3.ar',// congresodelalengua3.ar
    'http://www.example.pvt.k12.ma.us',// example.pvt.k12.ma.us
    'http://www.example.lib.wy.us',// example.lib.wy.us
    'com',// empty
    '.com',// empty
    'http://big.uk.com',// big.uk.com
    'uk.com',// empty
    'www.uk.com',// www.uk.com
    '.uk.com',// empty
    'stackoverflow.com',// stackoverflow.com
    '.foobarfoo',// empty
    '',// empty
    false,// empty
    ' ',// empty
    1,// empty
    'a',// empty    
);

Versión reciente con explicaciones (alemán):
http://www.programmierer-forum.de/domainnamen-ermitteln-t244185.htm

Mi solución en https://gist.github.com/pocesar/5366899

y las pruebas están aquí http://codepad.viper-7.com/GAh1tP

Funciona con cualquier TLD y patrones de subdominio horribles (hasta 3 subdominios).

Hay una prueba incluida con muchos nombres de dominio.

No pegaré la función aquí debido a la extraña sangría para el código en StackOverflow (podría tener bloques de código cercados como github)

Reseñas y valoraciones

Recuerda que puedes dar recomendación a este post si si solucionó tu problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *