it-swarm.com.de

Wie validiere ich den Domainnamen in PHP?

Ist es ohne regulären Ausdruck möglich?

Ich möchte zum Beispiel prüfen, ob eine Zeichenfolge eine gültige Domäne ist:

domain-name
abcd
example

Sind gültige Domains. Diese sind natürlich ungültig:

[email protected]
ab$%cd

Und so weiter. Grundsätzlich sollte es also mit einem alphanumerischen Zeichen beginnen, dann können mehr Alnum-Zeichen und auch ein Bindestrich vorhanden sein. Und es muss auch mit einem Alnum-Charakter enden.

Wenn es nicht möglich ist, können Sie mir ein Regex-Muster vorschlagen, um dies zu tun?

BEARBEITEN:

Warum funktioniert das nicht? Verwende ich falsches preg_match?

$domain = '@djkal';
$regexp = '/^[a-zA-Z0-9][a-zA-Z0-9\-\_]+[a-zA-Z0-9]$/';
if (false === preg_match($regexp, $domain)) {
    throw new Exception('Domain invalid');
}
28
Richard Knop
<?php
function is_valid_domain_name($domain_name)
{
    return (preg_match("/^([a-z\d](-*[a-z\d])*)(\.([a-z\d](-*[a-z\d])*))*$/i", $domain_name) //valid chars check
            && preg_match("/^.{1,253}$/", $domain_name) //overall length check
            && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name)   ); //length of each label
}
?>

Testfälle:

is_valid_domain_name? [a]                       Y
is_valid_domain_name? [0]                       Y
is_valid_domain_name? [a.b]                     Y
is_valid_domain_name? [localhost]               Y
is_valid_domain_name? [google.com]              Y
is_valid_domain_name? [news.google.co.uk]       Y
is_valid_domain_name? [xn--fsqu00a.xn--0zwm56d] Y
is_valid_domain_name? [goo gle.com]             N
is_valid_domain_name? [google..com]             N
is_valid_domain_name? [google.com ]             N
is_valid_domain_name? [google-.com]             N
is_valid_domain_name? [.google.com]             N
is_valid_domain_name? [<script]                 N
is_valid_domain_name? [alert(]                  N
is_valid_domain_name? [.]                       N
is_valid_domain_name? [..]                      N
is_valid_domain_name? [ ]                       N
is_valid_domain_name? [-]                       N
is_valid_domain_name? []                        N
125
velcrow

Damit prüfen Sie nicht nur, ob die Domain ein gültiges Format hat, sondern auch, ob sie aktiv ist// eine IP-Adresse zugewiesen hat.

$domain = "stackoverflow.com";

if(filter_var(gethostbyname($domain), FILTER_VALIDATE_IP))
{
    return TRUE;
}

Beachten Sie, dass für diese Methode die DNS-Einträge aktiv sein müssen. Wenn Sie also eine Domänenzeichenfolge überprüfen möchten, ohne sich im DNS befinden zu müssen, verwenden Sie die von velcrow oben angegebene Methode für reguläre Ausdrücke.

Diese Funktion ist nicht dazu gedacht, eine URL-Zeichenfolge zu überprüfen, für die FILTER_VALIDATE_URL verwendet wird. Wir verwenden FILTER_VALIDATE_URL nicht für eine Domäne, da eine Domänenzeichenfolge keine gültige URL ist.

54
RoboTamer

Zunächst sollten Sie klären, ob Sie Folgendes meinen:

  1. individuelle Domainnamen-Labels
  2. gesamte Domain-Namen (d. h. mehrere durch Punkte getrennte Bezeichnungen)
  3. Hostnamen

Der Grund für die Unterscheidung ist, dass ein Etikett technisch gesehen beliebige Zeichen enthalten kann, einschließlich NUL, _@_ und '_._ ' Figuren. DNS ist 8-Bit-fähig und es ist durchaus möglich, dass eine Zonendatei den Eintrag "an\0odd\[email protected]" enthält. Es wird natürlich nicht empfohlen, nicht zuletzt, weil die Leute Schwierigkeiten haben würden, einen Punkt in einem Etikett von diesen Trennetiketten zu unterscheiden, aber es ist legal.

Für URLs ist jedoch ein Hostname erforderlich, und diese werden verwaltet von RFCs 952 und 1123. Gültige Host- Namen sind eine Teilmenge der Domain Namen. Insbesondere sind nur Buchstaben, Ziffern und Bindestriche zulässig. Außerdem dürfen das erste und das letzte Zeichen kein Bindestrich sein. RFC 952 erlaubte keine Nummer für das erste Zeichen, aber RFC 1123 lockerte das anschließend.

Daher:

  • a - gültig
  • 0 - gültig
  • a- - ungültig
  • a-b - gültig
  • xn--dasdkhfsd - gültig (Punycode-Codierung einer IDN)

Ich glaube nicht, dass es möglich ist, das Beispiel _a-_ mit einem einzigen einfachen regulären Ausdruck ungültig zu machen. Am besten kann ich mir ein einzelnes Host Etikett einfallen lassen :

_if (preg_match('/^[a-z\d][a-z\d-]{0,62}$/i', $label) &&
   !preg_match('/-$/', $label))
{
    # label is legal within a hostname
}
_

Um die Sache noch weiter zu komplizieren, verwenden einige Domainnameneinträge (normalerweise SRV records) Labels, denen ein Unterstrich vorangestellt ist, z. __sip._udp.example.com_. Dies sind keine Hostnamen, sondern legale Domainnamen.

9
Alnitak

verwenden Sie checkdnsrrhttp://php.net/manual/de/function.checkdnsrr.php

$domain = "stackoverflow.com";

checkdnsrr($domain , "A");

//returns true if has a dns A record, false otherwise
8
jacktrade

Ich denke, sobald Sie den Domainnamen isoliert haben, zum Beispiel mit Hilfe von Erklans Idee:

 $ myUrl = "http://www.domain.com/link.php";
$myParsedURL = parse_url ($ myUrl); 
 $ myDomainName = $ myParsedURL ['Host']; 

du könntest benutzen :

if (false === filter_var ($ myDomainName, FILTER_VALIDATE_URL)) {
 // Test fehlgeschlagen 

}

PHP5s Filterfunktionen sind für einen solchen Zweck gedacht, hätte ich gedacht.

Ihre Frage wird nicht streng beantwortet, da Regex nicht verwendet wird.

6
Cups

PHP 7

// Validate a domain name
var_dump(filter_var('mandrill._domainkey.mailchimp.com', FILTER_VALIDATE_DOMAIN));
# string(33) "mandrill._domainkey.mailchimp.com"

// Validate an hostname (here, the underscore is invalid)
var_dump(filter_var('mandrill._domainkey.mailchimp.com', FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME));
# bool(false)

Es ist hier nicht dokumentiert: http://www.php.net/filter.filters.validate und eine Fehleranfrage befindet sich hier: https://bugs.php.net/bug.php?id=72013

5
Rob

Hier ist ein anderer Weg ohne Regex.

$myUrl = "http://www.domain.com/link.php";
$myParsedURL = parse_url($myUrl);
$myDomainName= $myParsedURL['Host'];
$ipAddress = gethostbyname($myDomainName);
if($ipAddress == $myDomainName)
{
   echo "There is no url";
}
else
{
   echo "url found";
}
4
Erkan BALABAN

Reguläre Ausdrücke sind die effektivste Methode, um nach einer Domänenüberprüfung zu suchen. Wenn Sie nicht bereit sind, keinen regulären Ausdruck zu verwenden (der IMO ist dumm), können Sie jeden Teil einer Domäne aufteilen:

  • www/Subdomain
  • domänenname
  • .Erweiterung

Sie müssten dann jedes Zeichen in einer Art Schleife überprüfen, um festzustellen, ob es mit einer gültigen Domäne übereinstimmt.

Wie gesagt, es ist viel effektiver, einen regulären Ausdruck zu verwenden.

3
James Brooks

Ihr regulärer Ausdruck ist in Ordnung, aber Sie verwenden preg_match nicht richtig. Es gibt eine int (0 oder 1) zurück, kein Boolean. Schreiben Sie einfach if(!preg_match($regex, $string)) { ... }

2

Wenn Sie prüfen möchten, ob ein bestimmter Domänenname oder eine bestimmte IP-Adresse vorhanden ist, können Sie auch checkdnsrr verwenden.
Hier ist der doc http://php.net/manual/de/function.checkdnsrr.php

1
verdy

Die richtige Antwort ist, dass Sie es nicht tun ... Sie lassen ein von einem Gerät getestetes Werkzeug die Arbeit für Sie erledigen:

// return '' if Host invalid --
private function setHostname($Host = '')
{
    $ret = (!empty($Host)) ? $Host : '';
    if(filter_var('http://'.$ret.'/', FILTER_VALIDATE_URL) === false) {
        $ret = '';
    }
    return $ret;
}

lesen Sie weiter: https://www.w3schools.com/php/filter_validate_url.asp

1
Mike Q

Wenn Sie keine regulären Ausdrücke verwenden möchten, können Sie Folgendes versuchen:

$str = 'domain-name';

if (ctype_alnum(str_replace('-', '', $str)) && $str[0] != '-' && $str[strlen($str) - 1] != '-') {
    echo "Valid domain\n";
} else {
    echo "Invalid domain\n";
}

aber wie gesagt ist regexp das beste Werkzeug dafür.

1
Matteo Riva

Eine gültige Domain ist für mich etwas, was ich registrieren kann, oder zumindest etwas, das aussieht, als könnte ich es registrieren. Dies ist der Grund, warum ich dies gerne von "localhost" -Namen trennen möchte.

Und schließlich interessierte ich mich für die Hauptfrage, ob das Vermeiden von Regex schneller wäre und dies ist mein Ergebnis:

<?php
function filter_hostname($name, $domain_only=false) {
    // entire hostname has a maximum of 253 ASCII characters
    if (!($len = strlen($name)) || $len > 253
    // .example.org and localhost- are not allowed
    || $name[0] == '.' || $name[0] == '-' || $name[ $len - 1 ] == '.' || $name[ $len - 1 ] == '-'
    // a.de is the shortest possible domain name and needs one dot
    || ($domain_only && ($len < 4 || strpos($name, '.') === false))
    // several combinations are not allowed
    || strpos($name, '..') !== false
    || strpos($name, '.-') !== false
    || strpos($name, '-.') !== false
    // only letters, numbers, dot and hypen are allowed
/*
    // a little bit slower
    || !ctype_alnum(str_replace(array('-', '.'), '', $name))
*/
    || preg_match('/[^a-z\d.-]/i', $name)
    ) {
        return false;
    }
    // each label may contain up to 63 characters
    $offset = 0;
    while (($pos = strpos($name, '.', $offset)) !== false) {
        if ($pos - $offset > 63) {
            return false;
        }
        $offset = $pos + 1;
    }
    return $name;
}
?>

Benchmark-Ergebnisse im Vergleich zu velcrows Funktion und 10000 Iterationen ( vollständige Ergebnisse enthält viele Codevarianten. Es war interessant, die schnellsten zu finden.):

filter_hostname($domain);// $domains: 0.43556308746338 $real_world: 0.33749794960022
is_valid_domain_name($domain);// $domains: 0.81832790374756 $real_world: 0.32248711585999

$real_world enthielt keine extrem langen Domänennamen, um bessere Ergebnisse zu erzielen. Und jetzt kann ich Ihre Frage beantworten: Mit ctype_alnum() wäre es möglich, sie ohne Regex zu realisieren, aber da preg_match() schneller war, würde ich das vorziehen.

Wenn Ihnen die Tatsache, dass "local.Host" ein gültiger Domänenname ist, nicht gefällt, verwenden Sie diese Funktion . Stattdessen wird diese Option gegen eine öffentliche TLD-Liste gesetzt. Vielleicht findet jemand die Zeit, beides zu kombinieren.

1
mgutt

Wenn Sie Shell-Befehle ausführen können, können Sie anhand der folgenden Methode am besten feststellen, ob eine Domain registriert ist.

Diese Funktion gibt false zurück, wenn der Domainname nicht registriert ist. Anderenfalls wird der Domainname zurückgegeben.

function get_domain_name($domain) { 
    //Step 1 - Return false if any Shell sensitive chars or space/tab were found
    if(escapeshellcmd($domain)!=$domain || count(explode(".", $domain))<2 || preg_match("/[\s\t]/", $domain)) {
            return false;
    }

    //Step 2 - Get the root domain in-case of subdomain
    $domain = (count(explode(".", $domain))>2 ? strtolower(explode(".", $domain)[count(explode(".", $domain))-2].".".explode(".", $domain)[count(explode(".", $domain))-1]) : strtolower($domain));

    //Step 3 - Run Shell command 'Dig' to get SOA servers for the domain extension
    $ns = Shell_exec(escapeshellcmd("Dig +short SOA ".escapeshellarg(explode(".", $domain)[count(explode(".", $domain))-1]))); 

    //Step 4 - Return false if invalid extension (returns NULL), or take the first server address out of output
    if($ns===NULL) {
            return false;
    }
    $ns = (((preg_split('/\s+/', $ns)[0])[strlen(preg_split('/\s+/', $ns)[0])-1]==".") ? substr(preg_split('/\s+/', $ns)[0], 0, strlen(preg_split('/\s+/', $ns)[0])-1) : preg_split('/\s+/', $ns)[0]);

    //Step 5 - Run another Dig using the obtained address for our domain, and return false if returned NULL else return the domain name. This assumes an authoritative NS is assigned when a domain is registered, can be improved to filter more accurately.
    $ans = Shell_exec(escapeshellcmd("Dig +noall +authority ".escapeshellarg("@".$ns)." ".escapeshellarg($domain))); 
    return (($ans===NULL) ? false : ((strpos($ans, $ns)>-1) ? false : $domain));
}

Vorteile

  1. Funktioniert auf jeder Domain, während PHP-DNS-Funktionen auf einigen Domains fehlschlagen können. (meine .pro Domain schlug auf PHP DNS fehl)
  2. Funktioniert auf neuen Domains ohne DNS-Einträge (wie A)
  3. Unicode freundlich

Nachteile

  1. Wahrscheinlich Verwendung der Shell-Ausführung
0
Ajay Singh

Ich weiß, dass dies eine alte Frage ist, aber es war die erste Antwort auf eine Google-Suche und scheint daher relevant zu sein. Ich hatte kürzlich das gleiche Problem. Die Lösung in meinem Fall war, einfach die Public Suffix List zu verwenden:

https://publicsuffix.org/learn/

Die vorgeschlagenen sprachspezifischen Bibliotheken sollten alle eine einfache Überprüfung des Domänenformats sowie der Gültigkeit von Domänen auf oberster Ebene ermöglichen.

0
jeffers102
<?php

if(is_valid_domain('https://www.google.com')==1){
  echo 'Valid';
}else{
   echo 'InValid';
}

 function is_valid_domain($url){

    $validation = FALSE;
    /*Parse URL*/    
    $urlparts = parse_url(filter_var($url, FILTER_SANITIZE_URL));

    /*Check Host exist else path assign to Host*/    
    if(!isset($urlparts['Host'])){
        $urlparts['Host'] = $urlparts['path'];
    }

    if($urlparts['Host']!=''){
        /*Add scheme if not found*/        if (!isset($urlparts['scheme'])){
        $urlparts['scheme'] = 'http';
        }

        /*Validation*/        
    if(checkdnsrr($urlparts['Host'], 'A') && in_array($urlparts['scheme'],array('http','https')) && ip2long($urlparts['Host']) === FALSE){ 
        $urlparts['Host'] = preg_replace('/^www\./', '', $urlparts['Host']);
        $url = $urlparts['scheme'].'://'.$urlparts['Host']. "/";            

            if (filter_var($url, FILTER_VALIDATE_URL) !== false && @get_headers($url)) {
                $validation = TRUE;
            }
        }
    }

    return $validation;

}
?>
0