19 Stimmen

Wie erhält man den Basis-Domainnamen aus einer URL mit PHP?

Ich muss den Domänennamen aus einer URL abrufen. Die folgenden Beispiele sollten alle zurückgeben google.com :

google.com
images.google.com
new.images.google.com
www.google.com

In ähnlicher Weise sollten die folgenden URLs alle Folgendes zurückgeben google.co.uk .

google.co.uk
images.google.co.uk
new.images.google.co.uk
http://www.google.co.uk

Ich zögere bei der Verwendung von regulären Ausdrücken, weil etwas wie domain.com/google.com könnte falsche Ergebnisse liefern.

Wie kann ich die Top-Level-Domain mit PHP abrufen? Dies muss auf allen Plattformen und Hosts funktionieren.

19voto

xil3 Punkte 16042

Sie könnten dies tun:

$urlData = parse_url($url);

$host = $urlData['host'];

** Aktualisierung **

Der beste Weg, den ich mir vorstellen kann, ist eine Zuordnung aller TLDs, die Sie behandeln wollen, da bestimmte TLDs schwierig sein können (co.uk).

// you can add more to it if you want
$urlMap = array('com', 'co.uk');

$host = "";
$url = "http://www.google.co.uk";

$urlData = parse_url($url);
$hostData = explode('.', $urlData['host']);
$hostData = array_reverse($hostData);

if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) {
  $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0];
} elseif(array_search($hostData[0], $urlMap) !== FALSE) {
  $host = $hostData[1] . '.' . $hostData[0];
}

echo $host;

7voto

aequalsb Punkte 3345

Top-Level-Domains und Second-Level-Domains dürfen 2 Zeichen lang sein, aber eine registrierte Subdomain muss mindestens 3 Zeichen lang sein.

EDIT: aufgrund des Kommentars von pjv habe ich erfahren, dass australische Domänennamen eine Ausnahme sind, weil sie 5 TLDs als SLDs zulassen (com,net,org,asn,id) Beispiel: somedomain.com.au. ich vermute, dass com.au ein national kontrollierter Domänenname ist, der "geteilt" wird. technisch gesehen wäre also "com.au" immer noch die "Basisdomäne", aber das ist nicht sinnvoll.

EDIT: Es gibt 47.952 mögliche Domänennamen mit drei Buchstaben (Muster: [a-zA-Z0-9][a-zA-Z0-9-][a-zA-Z0-9] oder 36 * 37 * 36). Kombiniert mit nur 8 der gebräuchlichsten TLDS (com, org usw.) ergeben sich 383.616 Möglichkeiten - ohne die gesamte Bandbreite der TLDs zu berücksichtigen. 1-Buchstaben- und 2-Buchstaben-Domänennamen gibt es zwar noch, sie sind aber nicht mehr gültig.

in google.com - "google" ist eine Unterdomäne von "com"

in google.co.uk -- "google" ist eine Unterdomäne von "co", die wiederum eine Unterdomäne von "uk" ist, oder eigentlich eine Domäne zweiter Stufe, da "co" auch eine gültige Domäne erster Stufe ist

in www.google.com -- "www" ist eine Unterdomäne von "google", die wiederum eine Unterdomäne von "com" ist

"co.uk" ist KEIN gültiger Host, da es keinen gültigen Domänennamen gibt.

Ausgehend von dieser Annahme wird diese Funktion in fast allen Fällen die richtige "basedomain" zurückgeben, ohne dass eine "url map" erforderlich ist.

Wenn Sie einer der seltenen Fälle sind, können Sie dies vielleicht ändern, um bestimmte Bedürfnisse zu erfüllen...

EDIT: Sie müssen den Domain-String als URL mit dem entsprechenden Protokoll (http://, ftp://, etc.) übergeben oder parse_url() wird sie nicht als gültige URL betrachtet (es sei denn, Sie möchten den Code ändern, damit er sich anders verhält)

function basedomain( $str = '' )
{
    // $str must be passed WITH protocol. ex: http://domain.com
    $url = @parse_url( $str );
    if ( empty( $url['host'] ) ) return;
    $parts = explode( '.', $url['host'] );
    $slice = ( strlen( reset( array_slice( $parts, -2, 1 ) ) ) == 2 ) && ( count( $parts ) > 2 ) ? 3 : 2;
    return implode( '.', array_slice( $parts, ( 0 - $slice ), $slice ) );
}

Wenn Sie genau sein müssen, verwenden Sie fopen o curl um diese URL zu öffnen: http://data.iana.org/TLD/tlds-alpha-by-domain.txt

dann die Zeilen in ein Array einlesen und dieses zum Vergleich der Domänenteile verwenden

EDIT: um australische Domains zu berücksichtigen:

function au_basedomain( $str = '' )
{
    // $str must be passed WITH protocol. ex: http://domain.com
    $url = @parse_url( $str );
    if ( empty( $url['host'] ) ) return;
    $parts = explode( '.', $url['host'] );
    $slice = ( strlen( reset( array_slice( $parts, -2, 1 ) ) ) == 2 ) && ( count( $parts ) > 2 ) ? 3 : 2;
    if ( preg_match( '/\.(com|net|asn|org|id)\.au$/i', $url['host'] ) ) $slice = 3;
    return implode( '.', array_slice( $parts, ( 0 - $slice ), $slice ) );
}

WICHTIGE ZUSÄTZLICHE HINWEISE: Ich verwende diese Funktion nicht zur Validierung von Domains. Es handelt sich um generischen Code, den ich nur verwende, um die Basisdomäne für den Server, auf dem sie läuft, aus der globalen $_SERVER['SERVER_NAME'] zur Verwendung in verschiedenen internen Skripten. Da ich bisher nur an Websites in den USA gearbeitet habe, bin ich nie auf die australische Variante gestoßen, nach der pjv gefragt hat. Es ist praktisch für den internen Gebrauch, aber es ist weit entfernt von einem vollständigen Domain-Validierungsprozess. Wenn Sie versuchen, es auf diese Weise zu verwenden, empfehle ich, dies nicht zu tun, da es zu viele Möglichkeiten gibt, ungültige Domains zu finden.

5voto

Klaas Sangers Punkte 1522

Versuchen Sie es mit: http://php.net/manual/en/function.parse-url.php . So etwas sollte funktionieren:

$urlParts = parse_url($yourUrl);
$hostParts = explode('.', $urlParts['host']);
$hostParts = array_reverse($hostParts);
$host = $hostParts[1] . '.' . $hostParts[0];

2voto

Mischen mit xil3 Antwort das ist ich bekam zu überprüfen, localhost sowie ip, so dass Sie auch in Entwicklungsumgebung arbeiten können.
Sie müssen noch festlegen, welche TLDs Sie verwenden möchten. Ansonsten funktioniert alles einwandfrei.

<?php
function getTopLevelDomain($url){
    $urlData = parse_url($url);
    $urlHost = isset($urlData['host']) ? $urlData['host'] : '';
    $isIP = (bool)ip2long($urlHost);
    if($isIP){ /** To check if it's ip then return same ip */
        return $urlHost;
    }
    /** Add/Edit you TLDs here */
    $urlMap = array('com', 'com.pk', 'co.uk');

    $host = "";
    $hostData = explode('.', $urlHost);
    if(isset($hostData[1])){ /** To check "localhost" because it'll be without any TLDs */
        $hostData = array_reverse($hostData);

        if(array_search($hostData[1] . '.' . $hostData[0], $urlMap) !== FALSE) {
            $host = $hostData[2] . '.' . $hostData[1] . '.' . $hostData[0];
        } elseif(array_search($hostData[0], $urlMap) !== FALSE) {
            $host = $hostData[1] . '.' . $hostData[0];
        }
        return $host;
    }
    return ((isset($hostData[0]) && $hostData[0] != '') ? $hostData[0] : 'error no domain'); /* You can change this error in future */
}
?>

Sie können es wie folgt verwenden

$string = 'http://googl.com.pk';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://googl.com.pk:23';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://googl.com';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://googl.com:23';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://adad.asdasd.googl.com.pk';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://adad.asdasd.googl.com.pk:23';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://adad.asdasd.googl.com';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://adad.asdasd.googl.com:23';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://192.168.0.101:23';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://192.168.0.101';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'http://localhost';
echo getTopLevelDomain( $string ) . '<br>';

$string = 'https;//';
echo getTopLevelDomain( $string ) . '<br>';

$string = '';
echo getTopLevelDomain( $string ) . '<br>';

Sie erhalten das Ergebnis als String wie folgt

googl.com.pk
googl.com.pk
googl.com
googl.com
googl.com.pk
googl.com.pk
googl.com
googl.com
192.168.0.101
192.168.0.101
localhost
error no domain
error no domain

1voto

Doctor Eval Punkte 2986

Ich bin kein PHP-Entwickler und ich weiß, dass dies nicht die vollständige Lösung ist, aber ich denke, das allgemeine Problem besteht darin, alle möglichen Namen der öffentlichen Domäne zu identifizieren.

Glücklicherweise gibt es eine Liste öffentlicher Domänen, die unter https://publicsuffix.org/list/ . Die Liste ist in zwei Abschnitte unterteilt. Der erste Abschnitt enthält Namen, die der Öffentlichkeit zugänglich sind, darunter viele der in diesen Kommentaren aufgeführten Namen, wie z. B. .com y .com.au . Die Namen der öffentlichen Bereiche werden mit ===BEGIN ICANN DOMAINS=== y ===END ICANN DOMAINS=== .

Wenn Sie nur die ICANN DOMAINS-Liste laden, können Sie die Top-Level-Domainnamen identifizieren. Aber es bräuchte einen PHP-Entwickler, um zu erklären, wie man das effizient macht :)

Wenn Sie die gesamte Liste laden, können Sie auch Informationen über private Subdomains erhalten, wie z. B. die unter github.io .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X