read query parser parsear parse_str parse http_build_query hacer como array php dns

query - php build url



Ir donde PHP parse_url() no lo hace-Analizando solo el dominio (8)

El parse_url () de PHP tiene un campo de host, que incluye el host completo. Estoy buscando la forma más confiable (y menos costosa) de devolver solo el dominio y el TLD.

Dados los ejemplos:

Estoy buscando solo google.com o google.co.uk . He contemplado una tabla de TLD / sufijos válidos y solo estoy permitiendo esos y una palabra. ¿Lo harías de otra manera? ¿Alguien sabe de un REGEX válido pre-enlatado para este tipo de cosas?


Por supuesto, depende de su caso de uso específico, pero en general no usaría una tabla de búsqueda de TLD. Aparecen nuevos TLD y, por lo general, no desea mantenerlos en ningún lado. Solo pregúntame con qué frecuencia mi [email protected] ha sido rechazado por falta de visión.

¿Supongo que podría ayudar mejor si supiera por qué no quieres el www? ¿Lo necesitas para correos electrónicos? Puede consultar registros MX en tales casos para verificar que (eventualmente) acepte correos.

También puede encontrar ayuda con las funciones de PHP relacionadas con los registros DNS para obtener más información al respecto, consulte http://php.net/dns_get_record, por ejemplo.



Solo una prueba, suponiendo que los tld permitidos se memoricen en un hash. El código puede acortarse mucho.

<?php $urlCompoments=parse_url($theUrl); $chunk=explode(''.'',$urlComponents[''host'']); $tldIndex = count($chunk-1); // assume last chunk is tld $maxTldLen = 2; // assuming a tld can be in the form .com or .co.uk $cursor=1; $found=false; while(($cursor<=$maxTldLen) or $found) { $tls = implode(''.'',array_slice($chunk, -$cursor)); $found=isset($tldSuffixesAllowed[$tld]); $cursor++; } if ($found){ $tld=implode(''.'',array_slice($chunk, -$cursor)); } else { // domain not recognized, do wathever you want } ?>


¿Qué tal algo así?

function getDomain($url) { $pieces = parse_url($url); $domain = isset($pieces[''host'']) ? $pieces[''host''] : ''''; if (preg_match(''/(?P<domain>[a-z0-9][a-z0-9/-]{1,63}/.[a-z/.]{2,6})$/i'', $domain, $regs)) { return $regs[''domain'']; } return false; }

parse_url el nombre de dominio utilizando el parse_url clásico y luego buscará un dominio válido sin ningún subdominio (www es un subdominio). No funcionará en cosas como ''localhost''. Devolverá falso si no coincide con nada.

// Editar:

Pruébalo con:

echo getDomain(''http://www.google.com/test.html'') . ''<br/>''; echo getDomain(''https://news.google.co.uk/?id=12345'') . ''<br/>''; echo getDomain(''http://my.subdomain.google.com/directory1/page.php?id=abc'') . ''<br/>''; echo getDomain(''https://testing.multiple.subdomain.google.co.uk/'') . ''<br/>''; echo getDomain(''http://nothingelsethan.com'') . ''<br/>'';

Y debería regresar:

google.com google.co.uk google.com google.co.uk nothingelsethan.com

Por supuesto, no devolverá nada si no pasa por parse_url , así que asegúrese de que sea una URL bien formada.

// Adición:

Alnitak tiene razón. La solución presentada anteriormente funcionará en la mayoría de los casos, pero no necesariamente todos, y debe mantenerse para asegurarse, por ejemplo, de que no sean nuevos TLD con .morethan6characters y más. La única forma confiable de extraer el dominio es usar una lista mantenida como http://publicsuffix.org/ . Es más doloroso al principio pero más fácil y más robusto a largo plazo. Debe asegurarse de comprender los pros y los contras de cada método y cómo se ajusta a su proyecto.


Hay una solución realmente fácil para esto:

function get_domain($url) { $pieces = parse_url($url); return array_pop(explode(''.'', $pieces[''host''], 2)); }

Seguramente esto funcionará?


También hay un muy buen puerto del módulo tldextract de Python http://w-shadow.com/blog/2012/08/28/tldextract - esto va más allá de parse_url y te permite sacar el dominio / tld, sin el subdominio .

Desde el sitio web del módulo:

$components = tldextract(''http://www.bbc.co.uk''); echo $components->subdomain; // www echo $components->domain; // bbc echo $components->tld; // co.uk


Necesita un paquete que use la Lista de sufijos públicos , solo de esta manera puede extraer correctamente dominios con TLD de dos o tres niveles (co.uk, a.bg, b.bg, etc.) y subdominios multinivel. Regex, parse_url () o las funciones de cadena nunca producirán un resultado absolutamente correcto.

Recomiendo usar TLD Extract . Aquí ejemplo de código:

$extract = new LayerShifter/TLDExtract/Extract(); $result = $extract->parse(''http://www.google.co.uk/foo''); $result->getSubdomain(); // will return (string) ''www'' $result->getHostname(); // will return (string) ''google'' $result->getSuffix(); // will return (string) ''co.uk'' $result->getRegistrableDomain(); // will return (string) ''google.co.uk''


Actualmente, la única forma "correcta" de hacer esto es usar una lista como la que se mantiene en http://publicsuffix.org/

Por cierto, esta pregunta también es más o menos un duplicado de:

Hay esfuerzos de estandarización en IETF mirando los métodos DNS para declarar si un nodo particular en el árbol DNS se usa para registros "públicos", pero están en sus primeras etapas de desarrollo. Todos los navegadores no IE populares usan la lista publicsuffix.org.