Avez-vous une URL sous forme de chaîne stockée dans une variable ou d'où provient cette URL? Quel est le contexte? Veuillez préciser.
Felix Kling
Ne pourriez-vous pas utiliser une expression régulière qui a fait quelque chose comme (^|://)(.*)\.et capturer le .*? Je suis plutôt nul en php et en regex, mais cela me vient à l'esprit.
corsiKa
Que devrait-il entrer en.foo.bar.example.comou en.example.co.uk?
@Mike Lewis - Cela résout-il le problème de plusieurs sous-domaines, tels que usa.en.example.com? Je me demande juste (ma propre réponse ne le fait pas, d'ailleurs).
Jared Farrish
@Jared, vient d'ajouter une solution pour détecter plusieurs sous-domaines.
Mike Lewis
1
@Mike - Cela fonctionnera-t-il avec tx.usa.en.example.com? (ou science.news.bbc.co.uk )? (btw, ce n'est pas un lien fonctionnel, juste un exemple, bien que news.bbc.co.uk fonctionne)
Jared Farrish
4
Cela fonctionne pour tout ce qui a un seul TLD «mot» comme net, com, biz, etc. Cependant, lorsqu'il s'agit de co.uk, par exemple, ce n'est pas le cas. Comme on le voit ici, c'est en fait un problème plus difficile à résoudre.
Mike Lewis
2
cela échoue également s'il n'y a pas du tout de sous-domaine.
raveren
32
Vous pouvez le faire en obtenant d'abord le nom de domaine (par exemple, sub.example.com => exemple.co.uk), puis en utilisant strstr pour obtenir les sous-domaines.
Cela semble la meilleure solution car elle permet également des domaines sans sous-domaine, plutôt que de retruner le nom de domaine en tant que sous-domaine étant la partie avant le premier point. Très utile pour vérifier l'existence d'un sous-domaine.
Karl MW
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 obtenant les derniers éléments du tableau avec une forboucle, mais j'ai dû 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. Regex sauve des vies, merci!
Yoone
1
Génial ... cela fonctionne si bien pour tous les types de domaines et sous-domaines ... sympa.
jon
2
alors que cette solution est très propre et peut travailler dans presque tous les cas, sachez que les domaines noms pourraient avoir plus de 6 caractères, comme pvt.k12.ma.us, health.vnou même k12.ak.us. En outre, les noms de domaine peuvent utiliser un jeu de caractères chinois ou russe afin que la partie regex [a-z\.]{2,6}ne les corresponde pas. Consultez ici pour avoir des exemples de noms de domaines: publicsuffix.org/list
Comme la seule source fiable pour les suffixes de domaine sont les bureaux d'enregistrement de domaine, vous ne pouvez pas trouver le sous-domaine à leur insu. Il existe une liste de tous les suffixes de domaine sur https://publicsuffix.org . Ce site renvoie également à une bibliothèque PHP: https://github.com/jeremykendall/php-domain-parser .
Veuillez trouver un exemple ci-dessous. J'ai également ajouté l'exemple pour en.test.co.uk qui est un domaine avec un suffixe multiple (co.uk).
PS - Je n'ai aucune idée de ce que c'est écrit dans le texte russe. Je viens de prendre quelques mots occasionnels de ru.wikipedia.org ;)
Kamafeather
N'est-ce pas ukrainien? .uaest l'indicatif pays de l'Ukraine.
nalply
Nan. Juste des informations mitigées. Mais je ne suis pas sûr, je ne suis pas assez bon pour les distinguer;)
Kamafeather
3
En ce qui concerne le russe, une traduction google du russe vers l'anglais revient en tant que "valeurs publiées" (au cas où quelqu'un serait curieux comme moi)
Jeremy Harris
@Kamafeather cela a l'air à l'épreuve des balles. Un moyen d'obtenir la $match[1]pièce? $match[0]semble inutile.
Andres SK
3
$REFERRER = $_SERVER['HTTP_REFERER'];// Or other method to get a URL for decomposition
$domain = substr($REFERRER, strpos($REFERRER,'://')+3);
$domain = substr($domain,0, strpos($domain,'/'));// This line will return 'en' of 'en.example.com'
$subdomain = substr($domain,0, strpos($domain,'.'));
Il existe de meilleures façons de détecter automatiquement l'hôte actuel (comme $_SERVER['HTTP_HOST']), puis de s'appuyer sur un en-tête de référence pouvant être falsifié, en supposant que c'est l'idée générale derrière la réponse.
Matthieu
Oui, j'utilisais un vieux morceau de code. L'exemple reste cependant valable. Ce n'est pas la racine de la question.
Jared Farrish
Juste pour ajouter à ces commentaires ci-dessus, se fier à $ _SERVER ['HTTP_HOST'] peut ne pas être efficace, car il est possible qu'il ne soit pas défini.
gmslzr
2
PHP 7.0: Utilisation de la fonction d'explosion et création d'une liste de tous les résultats.
Il n'y a pas vraiment de solution 100% dynamique - je viens d'essayer de le comprendre également et en raison des différentes extensions de domaine (DTL), cette tâche serait vraiment difficile sans analyser toutes ces extensions et les vérifier à chaque fois:
.com vs .co.uk vs org.uk
L'option la plus fiable est de définir une constante (ou une entrée de base de données, etc.) qui stocke le nom de domaine réel et le supprime de l' $_SERVER['SERVER_NAME']utilisationsubstr()
Maintenant, si vous utilisez cette fonction, http://test.mymaindomain.co.ukcela vous donnera testou si vous avez plusieurs niveaux de sous-domaine, http://another.test.mymaindomain.co.ukvous obtiendrez another.test- à moins bien sûr que vous ne mettiez à jour leDOMAIN .
En utilisant des expressions régulières, des fonctions de chaîne, parse_url () ou leurs combinaisons, ce n'est pas une vraie solution. Testez simplement l'une des solutions proposées avec domaintest.en.example.co.uk , il n'y aura pas de résultat correct.
La solution correcte est d'utiliser un package qui analyse le domaine avec la liste de suffixes publics . Je recommande TLDExtract , voici un exemple de code:
$extract =newLayerShifter\TLDExtract\Extract();
$result = $extract->parse('test.en.example.co.uk');
$result->getSubdomain();// will return (string) 'test.en'
$result->getSubdomains();// will return (array) ['test', 'en']
$result->getHostname();// will return (string) 'example'
$result->getSuffix();// will return (string) 'co.uk'
// For www.abc.en.example.com
$host_Array = explode(".",$_SERVER['HTTP_HOST']);// Get HOST as array www, abc, en, example, com
array_pop($host_Array); array_pop($host_Array);// Remove com and exmaple
array_shift($host_Array);// Remove www (Optional)
echo implode($host_Array,".");// Combine array abc.en
Je sais que je suis vraiment en retard au match, mais voilà.
Ce que j'ai fait, c'est de prendre la variable de serveur HTTP_HOST ( $_SERVER['HTTP_HOST']) et le nombre de lettres dans le domaine (donc pour example.comce serait 11).
Ensuite, j'ai utilisé la substrfonction pour obtenir le sous-domaine. J'ai fait
J'ai coupé la sous-chaîne à 12 au lieu de 11 car les sous-chaînes commencent à 1 pour le deuxième paramètre. Alors maintenant, si vous entrez test.example.com, la valeur de $subdomainserait test.
C'est mieux que d'utiliser explodecar si le sous-domaine contient un ., cela ne le coupera pas.
Cela ne fonctionnera que s'il n'y a pas wwwde chaîne au début. Une approche un peu trop triviale.
FooBar
Cela simplifie les choses pour les autres développeurs de l'équipe, je préfère l'utiliser plutôt que des exp reg avancé. Si vous voulez couper www, utilisez trim ($ s, 'www'); ou ajustez-le simplement à votre logique métier ...
tasmaniski
1
Par souci d'exhaustivité, wwwest en fait un sous-domaine. Il est juste communément associé au nom de domaine lui-même pour des raisons historiques.
Nous utilisons cette fonction pour gérer plusieurs sous - domaines et plusieurs tld gèrent également ip et localhost
function analyse_host($_host){
$my_host = explode('.', $_host);
$my_result =['subdomain'=>null,'root'=>null,'tld'=>null];// if host is ip, only set as rootif(filter_var($_host, FILTER_VALIDATE_IP)){// something like 127.0.0.5
$my_result['root']= $_host;}
elseif(count($my_host)===1){// something like localhost
$my_result['root']= $_host;}
elseif(count($my_host)===2){// like jibres.com
$my_result['root']= $my_host[0];
$my_result['tld']= $my_host[1];}
elseif(count($my_host)>=3){// some conditons like// ermile.ac.ir// ermile.jibres.com// ermile.jibres.ac.ir// a.ermile.jibres.ac.ir// get last one as tld
$my_result['tld']=end($my_host);
array_pop($my_host);// check last one after remove is probably tld or not
$known_tld =['com','org','net','gov','co','ac','id','sch','biz'];
$probably_tld =end($my_host);if(in_array($probably_tld, $known_tld)){
$my_result['tld']= $probably_tld.'.'. $my_result['tld'];
array_pop($my_host);}
$my_result['root']=end($my_host);
array_pop($my_host);// all remain is subdomainif(count($my_host)>0){
$my_result['subdomain']= implode('.', $my_host);}}return $my_result;}
$ host = array_reverse (exploser ('.', $ _SERVER ['SERVER_NAME']));
if (count ($ hôte)> = 3) {
echo "Le domaine principal est =". $ host [1]. ".". $ host [0]. "& subdomain is =". $ host [2];
// Le domaine principal est = exemple.com & le sous-domaine est = sous
} autre {
echo "Le domaine principal est =". $ host [1]. ".". $ host [0]. "& subdomain not found";
// "Le domaine principal est = exemple.com & sous-domaine introuvable";
}
Et s'il y avait un gestionnaire de protocole au début, tel que http: //, https: //, ftp: //, etc ...? ;)
Jared Farrish
@Jared, il n'y a pas de protocole dans la chaîne qu'il cherche à analyser ... Mais s'il y en avait, j'utiliserais parse_url()pour extraire l'hôte.
Matthieu
Nous avons donc proposé deux approches qui seront appropriées dans différents contextes.
Jared Farrish
Surtout, je suis juste content que quelqu'un n'ait pas (encore) publié de réponse regex. Sans oublier que la dernière ligne de ma réponse accomplit également la même chose que la vôtre.
(^|://)(.*)\.
et capturer le.*
? Je suis plutôt nul en php et en regex, mais cela me vient à l'esprit.en.foo.bar.example.com
ouen.example.co.uk
?Réponses:
Voici une solution en une ligne:
Ou en utilisant votre exemple:
EDIT: Correction de "seules les variables doivent être passées par référence" en ajoutant une double parenthèse.
EDIT 2 : À partir de PHP 5.4, vous pouvez simplement faire:
la source
explode(...)[0]
au lieu d'utiliser shift de nos jours? Je n'ai pas fait de PHP depuis plusieurs années ..Strict Standards: Only variables should be passed by reference.
www.en.example.com
et reviendrait donc enwww
tant que sous-domaine.Utilise la fonction parse_url .
Pour plusieurs sous-domaines
la source
Vous pouvez le faire en obtenant d'abord le nom de domaine (par exemple, sub.example.com => exemple.co.uk), puis en utilisant strstr pour obtenir les sous-domaines.
Les sorties:
la source
for
boucle, mais j'ai dû 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. Regex sauve des vies, merci!pvt.k12.ma.us
,health.vn
ou mêmek12.ak.us
. En outre, les noms de domaine peuvent utiliser un jeu de caractères chinois ou russe afin que la partie regex[a-z\.]{2,6}
ne les corresponde pas. Consultez ici pour avoir des exemples de noms de domaines: publicsuffix.org/listhttp://php.net/parse_url
la source
Comme la seule source fiable pour les suffixes de domaine sont les bureaux d'enregistrement de domaine, vous ne pouvez pas trouver le sous-domaine à leur insu. Il existe une liste de tous les suffixes de domaine sur https://publicsuffix.org . Ce site renvoie également à une bibliothèque PHP: https://github.com/jeremykendall/php-domain-parser .
Veuillez trouver un exemple ci-dessous. J'ai également ajouté l'exemple pour en.test.co.uk qui est un domaine avec un suffixe multiple (co.uk).
la source
Solution la plus simple et la plus rapide.
la source
Simplement...
Il suffit de lire $ match [1]
Exemple de travail
Cela fonctionne parfaitement avec cette liste d'urls
la source
.ua
est l'indicatif pays de l'Ukraine.$match[1]
pièce?$match[0]
semble inutile.la source
$_SERVER['HTTP_HOST']
), puis de s'appuyer sur un en-tête de référence pouvant être falsifié, en supposant que c'est l'idée générale derrière la réponse.PHP 7.0: Utilisation de la fonction d'explosion et création d'une liste de tous les résultats.
Exemple: sub.domain.com
Résultat: sous
Résultat: domaine
la source
.co.uk
- votre extrait ne fonctionnera pas avec ces TLDCe que j'ai trouvé la meilleure solution courte est
la source
Pour ceux qui obtiennent "Erreur: normes strictes: seules les variables doivent être transmises par référence". Utilisez comme ceci:
$env = (explode(".",$_SERVER['HTTP_HOST'])); $env = array_shift($env);
la source
Comme vu dans une question précédente: Comment obtenir le premier sous-domaine avec PHP?
la source
Il n'y a pas vraiment de solution 100% dynamique - je viens d'essayer de le comprendre également et en raison des différentes extensions de domaine (DTL), cette tâche serait vraiment difficile sans analyser toutes ces extensions et les vérifier à chaque fois:
.com vs .co.uk vs org.uk
L'option la plus fiable est de définir une constante (ou une entrée de base de données, etc.) qui stocke le nom de domaine réel et le supprime de l'
$_SERVER['SERVER_NAME']
utilisationsubstr()
Maintenant, si vous utilisez cette fonction,
http://test.mymaindomain.co.uk
cela vous donneratest
ou si vous avez plusieurs niveaux de sous-domaine,http://another.test.mymaindomain.co.uk
vous obtiendrezanother.test
- à moins bien sûr que vous ne mettiez à jour leDOMAIN
.J'espère que ça aide.
la source
Simplement
reset(explode(".", $_SERVER['HTTP_HOST']))
la source
En utilisant des expressions régulières, des fonctions de chaîne, parse_url () ou leurs combinaisons, ce n'est pas une vraie solution. Testez simplement l'une des solutions proposées avec domain
test.en.example.co.uk
, il n'y aura pas de résultat correct.La solution correcte est d'utiliser un package qui analyse le domaine avec la liste de suffixes publics . Je recommande TLDExtract , voici un exemple de code:
la source
c'est ma solution, cela fonctionne avec les domaines les plus courants, vous pouvez adapter le tableau d'extensions selon vos besoins:
la source
la source
Je sais que je suis vraiment en retard au match, mais voilà.
Ce que j'ai fait, c'est de prendre la variable de serveur HTTP_HOST (
$_SERVER['HTTP_HOST']
) et le nombre de lettres dans le domaine (donc pourexample.com
ce serait 11).Ensuite, j'ai utilisé la
substr
fonction pour obtenir le sous-domaine. J'ai faitJ'ai coupé la sous-chaîne à 12 au lieu de 11 car les sous-chaînes commencent à 1 pour le deuxième paramètre. Alors maintenant, si vous entrez test.example.com, la valeur de
$subdomain
seraittest
.C'est mieux que d'utiliser
explode
car si le sous-domaine contient un.
, cela ne le coupera pas.la source
si vous utilisez drupal 7
cela vous aidera:
la source
la source
Depuis PHP 5.3, vous pouvez utiliser strstr () avec le paramètre true
la source
www
de chaîne au début. Une approche un peu trop triviale.www
est en fait un sous-domaine. Il est juste communément associé au nom de domaine lui-même pour des raisons historiques.Essaye ça...
la source
la source
$host = explode('.', isset($parsedUrl['path']) ? $parsedUrl['path'] : $parsedUrl['host']);
vous pouvez aussi l'utiliser
la source
Je fais quelque chose comme ça
la source
Nous utilisons cette fonction pour gérer plusieurs sous - domaines et plusieurs tld gèrent également ip et localhost
la source
Supposons que l'url actuelle = sub.example.com
la source
Si vous ne voulez que ce qui précède les premières règles:
la source
parse_url()
pour extraire l'hôte.