115 votes

Fonction PHP pour obtenir le sous-domaine d'une URL

Existe-t-il une fonction en PHP pour obtenir le nom du sous-domaine ?

Dans l'exemple suivant, je voudrais obtenir la partie "en" de l'URL :

en.example.com

6 votes

Avez-vous une URL sous forme de chaîne stockée dans une variable ou d'où vient cette URL ? Quel est le contexte ? Veuillez préciser.

0 votes

Tu ne pourrais pas utiliser une expression rationnelle qui ferait quelque chose comme (^|://)(.*)\. et de capturer le .* ? Je suis plutôt nul en php et en regex, mais ceci me vient à l'esprit.

0 votes

Que doit-il recevoir en en.foo.bar.example.com o en.example.co.uk ?

138voto

Michael Deal Points 490

Voici une solution en une ligne :

array_shift((explode('.', $_SERVER['HTTP_HOST'])));

Ou en utilisant votre exemple :

array_shift((explode('.', 'en.example.com')));

EDIT : Correction de "seules les variables doivent être passées par référence" en ajoutant des doubles parenthèses.

EDIT 2 : A partir de PHP 5.4 que vous pouvez simplement faire :

explode('.', 'en.example.com')[0];

18 votes

Seules les variables doivent être transmises par référence.

8 votes

Ne pouvez-vous pas simplement faire explode(...)[0] au lieu d'utiliser shift de nos jours ? Je n'ai pas PHPé depuis plusieurs années

0 votes

Erreur : Strict Standards: Only variables should be passed by reference.

67voto

Mike Lewis Points 29305

Utilise le parse_url fonction.

$url = 'http://en.example.com';

$parsedUrl = parse_url($url);

$host = explode('.', $parsedUrl['host']);

$subdomain = $host[0];
echo $subdomain;

Pour les sous-domaines multiples

$url = 'http://usa.en.example.com';

$parsedUrl = parse_url($url);

$host = explode('.', $parsedUrl['host']);

$subdomains = array_slice($host, 0, count($host) - 2 );
print_r($subdomains);

0 votes

@Mike Lewis - Cela résout-il le problème des sous-domaines multiples, tels que usa.en.example.com ? Je me demande simplement (ma propre réponse ne le fait pas, d'ailleurs).

0 votes

@Jared, je viens d'ajouter une solution pour détecter les sous-domaines multiples.

1 votes

@Mike - Cela fonctionnera-t-il avec tx.usa.fr.example.com ? (ou science.news.bbc.co.uk ) ? (btw, ce n'est pas un lien qui fonctionne, juste un exemple, bien que news.bbc.co.uk fonctionne)

33voto

mazon Points 149

Vous pouvez le faire en obtenant d'abord le nom de domaine (par exemple, sub.example.com => example.co.uk), puis en utilisant strstr pour obtenir les sous-domaines.

$testArray = array(
    'sub1.sub2.example.co.uk',
    'sub1.example.com',
    'example.com',
    'sub1.sub2.sub3.example.co.uk',
    'sub1.sub2.sub3.example.com',
    'sub1.sub2.example.com'
);

foreach($testArray as $k => $v)
{
    echo $k." => ".extract_subdomains($v)."\n";
}

function extract_domain($domain)
{
    if(preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i", $domain, $matches))
    {
        return $matches['domain'];
    } else {
        return $domain;
    }
}

function extract_subdomains($domain)
{
    $subdomains = $domain;
    $domain = extract_domain($subdomains);

    $subdomains = rtrim(strstr($subdomains, $domain, true), '.');

    return $subdomains;
}

Sorties :

0 => sub1.sub2
1 => sub1
2 =>
3 => sub1.sub2.sub3
4 => sub1.sub2.sub3
5 => sub1.sub2

2 votes

Cela semble être la meilleure solution car elle permet également de prendre en compte les domaines sans sous-domaine, plutôt que de retranscrire le nom de domaine comme le sous-domaine étant la partie avant le premier point. Très utile pour vérifier l'existence d'un sous-domaine.

0 votes

J'avais besoin d'obtenir le domaine de "base" (sans le sous-domaine), et je faisais ma propre solution en explosant l'hôte et en récupérant les derniers éléments du tableau avec un for mais je devais vérifier leur longueur (pour détecter s'ils faisaient partie du domaine comme le "co.uk"). En fait, votre solution est bien plus simple que ce que je faisais. Les Regex sauvent des vies, merci !

1 votes

Génial cela fonctionne si bien pour tous les types de domaines et sous-domaines sympa.

13voto

JMW Points 959

http://php.net/parse_url

<?php
  $url = 'http://user:password@sub.hostname.tld/path?argument=value#anchor';
  $array=parse_url($url);
  $array['host']=explode('.', $array['host']);

  echo $array['host'][0]; // returns 'en'
?>

5voto

Kamafeather Points 179

Simplement...

    preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $url, $match);

Lis juste $match[1]

Exemple de travail

Il fonctionne parfaitement avec cette liste d'urls

$url = array(
    'http://www.domain.com', // www
    'http://domain.com', // --nothing--
    'https://domain.com', // --nothing--
    'www.domain.com', // www
    'domain.com', // --nothing--
    'www.domain.com/some/path', // www
    'http://sub.domain.com/domain.com', // sub
    'опубликованному.значения.ua', // опубликованному ;)
    'значения.ua', // --nothing--
    'http://sub-domain.domain.net/domain.net', // sub-domain
    'sub-domain.third-Level_DomaIN.domain.uk.co/domain.net' // sub-domain
);

foreach ($url as $u) {
    preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $u, $match);
    var_dump($match);
}

2 votes

PS - Je n'ai aucune idée de ce qui est écrit dans le texte russe. J'ai juste pris quelques mots occasionnels de ru.wikipedia.org ;)

0 votes

N'est-ce pas ukrainien ? .ua est l'indicatif de pays pour l'Ukraine.

0 votes

Non. Juste des informations mitigées. Mais je ne suis pas sûr, je ne suis pas assez bon pour les distinguer ;)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X