Analyse du domaine à partir de L'URL en PHP
J'ai besoin de construire une fonction qui analyse le domaine à partir d'une URL.
Donc, avec
http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
Ou
http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html
Il devrait retourner google.com
Avec
http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html
Il devrait retourner google.co.uk
.
18 réponses
Découvrez parse_url()
:
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'google.com'
parse_url
ne gère pas très bien les URL vraiment mal mutilées, mais c'est bien si vous vous attendez généralement à des URL décentes.
$domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
Ce serait le retour de la google.com
pour les deux http://google.com/... et http://www.google.com/...
À Partir de http://us3.php.net/manual/en/function.parse-url.php#93983
Pour une raison étrange, parse_url renvoie l'hôte (ex. example.com) comme le chemin quand aucun schéma n'est fourni dans l'url d'entrée. Donc j'ai écrit un rapide fonction pour obtenir le vrai hôte:
function getHost($Address) {
$parseUrl = parse_url(trim($Address));
return trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2)));
}
getHost("example.com"); // Gives example.com
getHost("http://example.com"); // Gives example.com
getHost("www.example.com"); // Gives www.example.com
getHost("http://example.com/xyz"); // Gives example.com
Le code qui devait fonctionner à 100% ne semblait pas le couper pour moi, j'ai patché un peu l'exemple mais j'ai trouvé du code qui n'aidait pas et des problèmes avec. donc, je l'ai changé en quelques fonctions (pour enregistrer demander la liste de Mozilla tout le temps, et supprimer le système de cache). Cela a été testé contre un ensemble de 1000 URL et semblait fonctionner.
function domain($url)
{
global $subtlds;
$slds = "";
$url = strtolower($url);
$host = parse_url('http://'.$url,PHP_URL_HOST);
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
foreach($subtlds as $sub){
if (preg_match('/\.'.preg_quote($sub).'$/', $host, $xyz)){
preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches);
}
}
return @$matches[0];
}
function get_tlds() {
$address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
$content = file($address);
foreach ($content as $num => $line) {
$line = trim($line);
if($line == '') continue;
if(@substr($line[0], 0, 2) == '/') continue;
$line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
if($line == '') continue; //$line = '.'.$line;
if(@$line[0] == '.') $line = substr($line, 1);
if(!strstr($line, '.')) continue;
$subtlds[] = $line;
//echo "{$num}: '{$line}'"; echo "<br>";
}
$subtlds = array_merge(array(
'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk',
'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au'
), $subtlds);
$subtlds = array_unique($subtlds);
return $subtlds;
}
Ensuite, utilisez-le comme
$subtlds = get_tlds();
echo domain('www.example.com') //outputs: example.com
echo domain('www.example.uk.com') //outputs: example.uk.com
echo domain('www.example.fr') //outputs: example.fr
Je sais que j'aurais dû en faire une classe, mais je n'ai pas eu le temps.
function get_domain($url = SITE_URL)
{
preg_match("/[a-z0-9\-]{1,63}\.[a-z\.]{2,6}$/", parse_url($url, PHP_URL_HOST), $_domain_tld);
return $_domain_tld[0];
}
get_domain('http://www.cdl.gr'); //cdl.gr
get_domain('http://cdl.gr'); //cdl.gr
get_domain('http://www2.cdl.gr'); //cdl.gr
Si vous voulez extraire l'hôte de la chaîne http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
, l'utilisation de parse_url() est une solution acceptable pour vous.
Mais si vous voulez extraire le domaine ou ses parties, vous avez besoin d'un package utilisant Liste de suffixe Public . Oui, vous pouvez utiliser des fonctions de chaîne autour de parse_url (), mais cela produira parfois des résultats incorrects.
Je recommande TLDExtract pour l'analyse de domaine, voici un exemple de code qui montre diff:
$extract = new LayerShifter\TLDExtract\Extract();
# For 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
parse_url($url, PHP_URL_HOST); // will return google.com
$result = $extract->parse($url);
$result->getFullHost(); // will return 'google.com'
$result->getRegistrableDomain(); // will return 'google.com'
$result->getSuffix(); // will return 'com'
# For 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html'
$url = 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html';
parse_url($url, PHP_URL_HOST); // will return 'search.google.com'
$result = $extract->parse($url);
$result->getFullHost(); // will return 'search.google.com'
$result->getRegistrableDomain(); // will return 'google.com'
Voici le code que j'ai fait que 100% ne trouve que le nom de domaine, car il prend en compte les sous-tlds de mozilla. La seule chose que vous devez vérifier est de savoir comment vous faites le cache de ce fichier, de sorte que vous n'interrogez pas mozilla à chaque fois.
Pour une raison étrange, des domaines comme co.uk ne sont pas dans la liste, vous devez donc faire un piratage et les ajouter manuellement. Ce n'est pas la solution la plus propre mais j'espère que cela aide quelqu'un.
//=====================================================
static function domain($url)
{
$slds = "";
$url = strtolower($url);
$address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
if(!$subtlds = @kohana::cache('subtlds', null, 60))
{
$content = file($address);
foreach($content as $num => $line)
{
$line = trim($line);
if($line == '') continue;
if(@substr($line[0], 0, 2) == '/') continue;
$line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
if($line == '') continue; //$line = '.'.$line;
if(@$line[0] == '.') $line = substr($line, 1);
if(!strstr($line, '.')) continue;
$subtlds[] = $line;
//echo "{$num}: '{$line}'"; echo "<br>";
}
$subtlds = array_merge(Array(
'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk',
'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au',
),$subtlds);
$subtlds = array_unique($subtlds);
//echo var_dump($subtlds);
@kohana::cache('subtlds', $subtlds);
}
preg_match('/^(http:[\/]{2,})?([^\/]+)/i', $url, $matches);
//preg_match("/^(http:\/\/|https:\/\/|)[a-zA-Z-]([^\/]+)/i", $url, $matches);
$host = @$matches[2];
//echo var_dump($matches);
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
foreach($subtlds as $sub)
{
if (preg_match("/{$sub}$/", $host, $xyz))
preg_match("/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/", $host, $matches);
}
return @$matches[0];
}
Vous pouvez passer PHP_URL_HOST dans la fonction parse_url en tant que second paramètre
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$host = parse_url($url, PHP_URL_HOST);
print $host; // prints 'google.com'
$domain = parse_url($url, PHP_URL_HOST);
echo implode('.', array_slice(explode('.', $domain), -2, 2))
J'ai trouvé la solution de @ philfreo (référencée à partir de php.net) est assez bien pour obtenir un bon résultat, mais dans certains cas, il montre le message "notice" et "Strict Standards" de php. Voici une version fixe de ce code.
function getHost($url) {
$parseUrl = parse_url(trim($url));
if(isset($parseUrl['host']))
{
$host = $parseUrl['host'];
}
else
{
$path = explode('/', $parseUrl['path']);
$host = $path[0];
}
return trim($host);
}
echo getHost("http://example.com/anything.html"); // example.com
echo getHost("http://www.example.net/directory/post.php"); // www.example.net
echo getHost("https://example.co.uk"); // example.co.uk
echo getHost("www.example.net"); // example.net
echo getHost("subdomain.example.net/anything"); // subdomain.example.net
echo getHost("example.net"); // example.net
Parse_url n'a pas fonctionné pour moi. Il a seulement retourné le chemin. Passer aux bases en utilisant php5. 3+:
$url = str_replace('http://', '', strtolower( $s->website));
if (strpos($url, '/')) $url = strstr($url, '/', true);
J'ai édité pour vous:
function getHost($Address) {
$parseUrl = parse_url(trim($Address));
$host = trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2)));
$parts = explode( '.', $host );
$num_parts = count($parts);
if ($parts[0] == "www") {
for ($i=1; $i < $num_parts; $i++) {
$h .= $parts[$i] . '.';
}
}else {
for ($i=0; $i < $num_parts; $i++) {
$h .= $parts[$i] . '.';
}
}
return substr($h,0,-1);
}
Toutes les URL de type (www.domaine.ltd, sub1.subn.domaine.ltd se traduira par: domaine.Ltd.
Voici mon crawler basé sur les réponses ci-dessus.
- implémentation de classe (J'aime Obj:)
- , il utilise
Curl
on peut utiliser http auth est nécessaire - c'est seulement le lien d'analyse qui appartient au domaine d'url de début
- il imprime le code de réponse de l'en-tête http (utile pour vérifier les problèmes sur un site )
CODE DE CLASSE D'ANALYSE
class crawler
{
protected $_url;
protected $_depth;
protected $_host;
public function __construct($url, $depth = 5)
{
$this->_url = $url;
$this->_depth = $depth;
$parse = parse_url($url);
$this->_host = $parse['host'];
}
public function run()
{
$this->crawl_page($this->_url, $this->_depth = 5);
}
public function crawl_page($url, $depth = 5)
{
static $seen = array();
if (isset($seen[$url]) || $depth === 0) {
return;
}
$seen[$url] = true;
list($content, $httpcode) = $this->getContent($url);
$dom = new DOMDocument('1.0');
@$dom->loadHTML($content);
$this->processAnchors($dom, $url, $depth);
ob_end_flush();
echo "CODE::$httpcode, URL::$url <br>";
ob_start();
flush();
// echo "URL:", $url, PHP_EOL, "CONTENT:", PHP_EOL, $dom->saveHTML(), PHP_EOL, PHP_EOL;
}
public function processAnchors($dom, $url, $depth)
{
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $element) {
$href = $element->getAttribute('href');
if (0 !== strpos($href, 'http')) {
$path = '/' . ltrim($href, '/');
if (extension_loaded('http')) {
$href = http_build_url($url, array('path' => $path));
} else {
$parts = parse_url($url);
$href = $parts['scheme'] . '://';
if (isset($parts['user']) && isset($parts['pass'])) {
$href .= $parts['user'] . ':' . $parts['pass'] . '@';
}
$href .= $parts['host'];
if (isset($parts['port'])) {
$href .= ':' . $parts['port'];
}
$href .= $path;
}
}
// Crawl only link that belongs to the start domain
if (strpos($href, $this->_host) !== false)
$this->crawl_page($href, $depth - 1);
}
}
public function getContent($url)
{
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
/* Get the HTML or whatever is linked in $url. */
$response = curl_exec($handle);
/* Check for 404 (file not found). */
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if ($httpCode == 404) {
/* Handle 404 here. */
}
curl_close($handle);
return array($response, $httpCode);
}
}
// USAGE
$startURL = 'http://YOUR_START_ULR';
$depth = 2;
$crawler = new crawler($startURL, $depth);
$crawler->run();
J'ajoute cette réponse en retard puisque c'est la réponse qui apparaît le plus sur Google...
Vous pouvez utiliser PHP pour...
$url = "www.google.co.uk";
$host = parse_url($url, PHP_URL_HOST);
// $host == "www.google.co.uk"
Pour saisir le host, mais pas la domaine privé pour que l'hôte se réfère. (Exemple www.google.co.uk
est l'hôte, mais google.co.uk
est le domaine privé)
Pour saisir le domaine privé, vous devez connaître la liste des suffixes publics auxquels peut enregistrer un domaine privé. Cette liste est organisée par Mozilla à https://publicsuffix.org/
Le code ci-dessous fonctionne lorsqu'un tableau de suffixes publics a déjà été créé. Appelez simplement
$domain = get_private_domain("www.google.co.uk");
Avec le code restant...
// find some way to parse the above list of public suffix
// then add them to a PHP array
$suffix = [... all valid public suffix ...];
function get_public_suffix($host) {
$parts = split("\.", $host);
while (count($parts) > 0) {
if (is_public_suffix(join(".", $parts)))
return join(".", $parts);
array_shift($parts);
}
return false;
}
function is_public_suffix($host) {
global $suffix;
return isset($suffix[$host]);
}
function get_private_domain($host) {
$public = get_public_suffix($host);
$public_parts = split("\.", $public);
$all_parts = split("\.", $host);
$private = [];
for ($x = 0; $x < count($public_parts); ++$x)
$private[] = array_pop($all_parts);
if (count($all_parts) > 0)
$private[] = array_pop($all_parts);
return join(".", array_reverse($private));
}
Cela fonctionnera généralement très bien si l'URL d'entrée N'est pas un pourriel total. Il supprime le sous-domaine.
$host = parse_url( $Row->url, PHP_URL_HOST );
$parts = explode( '.', $host );
$parts = array_reverse( $parts );
$domain = $parts[1].'.'.$parts[0];
Exemple
Entrée: http://www2.website.com:8080/some/file/structure?some=parameters
Sortie: website.com
Combinant les réponses de worldofjr et Alix Axel dans une petite fonction qui va gérer la plupart des cas d'utilisation:
function get_url_hostname($url) {
$parse = parse_url($url);
return str_ireplace('www.', '', $parse['host']);
}
get_url_hostname('http://www.google.com/example/path/file.html'); // google.com
Il suffit d'utiliser comme suit ...
<?php
echo $_SERVER['SERVER_NAME'];
?>