Der beste Weg, um zu überprüfen, ob eine URL gültig ist

148

Ich möchte PHP verwenden, um zu überprüfen, ob die in der $myoutputVariable gespeicherte Zeichenfolge eine gültige Link-Syntax enthält oder nur ein normaler Text ist. Die Funktion oder Lösung, nach der ich suche, sollte alle Linkformate erkennen, einschließlich derjenigen mit GET-Parametern.

Eine auf vielen Websites vorgeschlagene Lösung zur tatsächlichen Abfrage von Zeichenfolgen (mithilfe von CURL oder file_get_contents()Funktion) ist in meinem Fall nicht möglich, und ich möchte sie vermeiden.

Ich dachte über reguläre Ausdrücke oder eine andere Lösung nach.

Ryan
quelle
Die Verwendung von CURL oder das Abrufen von HTTP-Inhalten kann langsam sein. Wenn Sie etwas schnelleres und fast ebenso zuverlässiges möchten, sollten Sie gethostbyaddr () für den Hostnamen verwenden. Wenn es in eine IP aufgelöst wird, hat es wahrscheinlich eine Website. Dies hängt natürlich von Ihren Bedürfnissen ab.
TravisO

Antworten:

300

Sie können einen nativen Filtervalidator verwenden

filter_var($url, FILTER_VALIDATE_URL);

Überprüft den Wert als URL (gemäß » http://www.faqs.org/rfcs/rfc2396 ), optional mit den erforderlichen Komponenten. Beachten Sie, dass eine gültige URL möglicherweise nicht das HTTP-Protokoll http: // angibt. Daher ist möglicherweise eine weitere Überprüfung erforderlich, um festzustellen, ob die URL ein erwartetes Protokoll verwendet, z. B. ssh: // oder mailto:. Beachten Sie, dass die Funktion nur ASCII-URLs findet, die gültig sind. Internationalisierte Domain-Namen (die keine ASCII-Zeichen enthalten) schlagen fehl.

Beispiel:

if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
    die('Not a valid URL');
}
Gordon
quelle
9
@ Raveren erwartetes Verhalten, da dies gültige URLs sind.
Gordon
8
Beachten Sie, dass FILTER_VALIDATE_URLdas Protokoll einer URL nicht überprüft wird. Also ssh://, ftp://usw. wird vergehen.
Seph
3
@SephVelut erwartetes Verhalten, da dies gültige URLs sind.
Gordon
1
Es erlaubt URLs wie ttp: //amazon.com
Elia Weiss
3
@ JoshHabdas, ich denke du verpasst den Punkt. Der PHP-Code macht genau das, was er behauptet zu tun. Aber es kann deine Gedanken nicht lesen. Es gibt einen großen Unterschied zwischen ungültig und unerwünscht. Unerwünscht ist sehr subjektiv, weshalb es dem Programmierer überlassen bleibt, dieses Detail zu erarbeiten. Möglicherweise stellen Sie auch fest, dass der Code die URL überprüft, jedoch nicht beweist, dass sie vorhanden ist. Es ist nicht PHPs Schuld, dass ein Benutzer "amazon", "amozon" falsch eingegeben hat, was validieren würde, aber immer noch unerwünscht ist.
JBH
20

Hier ist das beste Tutorial, das ich dort gefunden habe:

http://www.w3schools.com/php/filter_validate_url.asp

<?php
$url = "http://www.qbaki.com";

// Remove all illegal characters from a url
$url = filter_var($url, FILTER_SANITIZE_URL);

// Validate url
if (filter_var($url, FILTER_VALIDATE_URL) !== false) {
echo("$url is a valid URL");
} else {
echo("$url is not a valid URL");
}
?>

Mögliche Flaggen:

FILTER_FLAG_SCHEME_REQUIRED - URL must be RFC compliant (like http://example)
FILTER_FLAG_HOST_REQUIRED - URL must include host name (like http://www.example.com)
FILTER_FLAG_PATH_REQUIRED - URL must have a path after the domain name (like www.example.com/example1/)
FILTER_FLAG_QUERY_REQUIRED - URL must have a query string (like "example.php?name=Peter&age=37")
Erich García
quelle
1
Nur ein Trottel: !filter_var(...) === false==> filter_var(...) === trueoder einfach filter_var(...). :)
Domenico De Felice
@ ErichGarcía Dieser Code überprüft nicht, ob es sich um eine gültige HTTP / S-URL handelt, wie es das OP verlangt. Dies wird Dinge wie ssh: //, ftp: // usw. übergeben. Dies prüft nur, ob es sich um eine syntaktisch gültige URL gemäß RFC 2396 handelt
Twigg
Verwenden Sie nicht FILTER_VALIDATE_URL. Es ist chaotisch und unzuverlässig. ZB gilt es ttps://www.youtube.comals gültig
Jeffz
12

Die Verwendung von filter_var () schlägt für URLs mit Nicht-ASCII-Zeichen fehl, z . B. ( http://pt.wikipedia.org/wiki/Guimarães ). Die folgende Funktion codiert alle Nicht-ASCII-Zeichen (z. B. http://pt.wikipedia.org/wiki/Guimar%C3%A3es ), bevor filter_var () aufgerufen wird.

Hoffe das hilft jemandem.

<?php

function validate_url($url) {
    $path = parse_url($url, PHP_URL_PATH);
    $encoded_path = array_map('urlencode', explode('/', $path));
    $url = str_replace($path, implode('/', $encoded_path), $url);

    return filter_var($url, FILTER_VALIDATE_URL) ? true : false;
}

// example
if(!validate_url("http://somedomain.com/some/path/file1.jpg")) {
    echo "NOT A URL";
}
else {
    echo "IS A URL";
}
Huey Ly
quelle
Das ist es. Endlich kam 2017 jemand zurück
Kyle KIM
Funktioniert für mich (die anderen nicht BTW) :)
Jono
Dies ist die EINZIGE Lösung, die für mich funktioniert hat. Vielen Dank!
Silas
10
function is_url($uri){
    if(preg_match( '/^(http|https):\\/\\/[a-z0-9_]+([\\-\\.]{1}[a-z_0-9]+)*\\.[_a-z]{2,5}'.'((:[0-9]{1,5})?\\/.*)?$/i' ,$uri)){
      return $uri;
    }
    else{
        return false;
    }
}
mghhgm
quelle
3

Persönlich möchte ich hier reguläre Ausdrücke verwenden. Der folgende Code hat bei mir perfekt funktioniert.

$baseUrl     = url('/'); // for my case https://www.xrepeater.com
$posted_url  = "home";
// Test with one by one
/*$posted_url  = "/home";
$posted_url  = "xrepeater.com";
$posted_url  = "www.xrepeater.com";
$posted_url  = "http://www.xrepeater.com";
$posted_url  = "https://www.xrepeater.com";
$posted_url  = "https://xrepeater.com/services";
$posted_url  = "xrepeater.dev/home/test";
$posted_url  = "home/test";*/

$regularExpression  = "((https?|ftp)\:\/\/)?"; // SCHEME Check
$regularExpression .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?"; // User and Pass Check
$regularExpression .= "([a-z0-9-.]*)\.([a-z]{2,3})"; // Host or IP Check
$regularExpression .= "(\:[0-9]{2,5})?"; // Port Check
$regularExpression .= "(\/([a-z0-9+\$_-]\.?)+)*\/?"; // Path Check
$regularExpression .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?"; // GET Query String Check
$regularExpression .= "(#[a-z_.-][a-z0-9+\$_.-]*)?"; // Anchor Check

if(preg_match("/^$regularExpression$/i", $posted_url)) { 
    if(preg_match("@^http|https://@i",$posted_url)) {
        $final_url = preg_replace("@(http://)+@i",'http://',$posted_url);
        // return "*** - ***Match : ".$final_url;
    }
    else { 
          $final_url = 'http://'.$posted_url;
          // return "*** / ***Match : ".$final_url;
         }
    }
else {
     if (substr($posted_url, 0, 1) === '/') { 
         // return "*** / ***Not Match :".$final_url."<br>".$baseUrl.$posted_url;
         $final_url = $baseUrl.$posted_url;
     }
     else { 
         // return "*** - ***Not Match :".$posted_url."<br>".$baseUrl."/".$posted_url;
         $final_url = $baseUrl."/".$final_url; }
}
Md. Noor-A-Alam Siddique
quelle
1
Dies ist die beste Antwort, um die URL der Website zu überprüfen. Mit wenigen Änderungen funktioniert dies perfekt. Vielen Dank
Amir Hossein Karimi
3

Bei Problemen mit filter_var (), die http: // benötigen, verwende ich:

$is_url = filter_var($filename, FILTER_VALIDATE_URL) || array_key_exists('scheme', parse_url($filename));

Herbst Leonard
quelle
Verwenden Sie nicht FILTER_VALIDATE_URL. Es ist chaotisch und unzuverlässig. ZB gilt es ttps://www.youtube.comals gültig
Jeffz
2

Sie können diese Funktion verwenden, sie gibt jedoch false zurück, wenn die Website offline ist.

  function isValidUrl($url) {
    $url = parse_url($url);
    if (!isset($url["host"])) return false;
    return !(gethostbyname($url["host"]) == $url["host"]);
}
Hasan Veli Soyalan
quelle
2

Eigentlich ... filter_var ($ url, FILTER_VALIDATE_URL); funktioniert nicht sehr gut. Wenn Sie eine echte URL eingeben, funktioniert dies, es wird jedoch nur nach http: // gesucht. Wenn Sie also etwas wie " http: // weirtgcyaurbatc " eingeben , wird weiterhin angezeigt , dass es echt ist.

Hayden Frobenius
quelle
Für die Absicht validiert FILTER_VALIDATE_URL ttps://www.youtube.comals gültig
Jeffz
1

Eine andere Möglichkeit, um zu überprüfen, ob die angegebene URL gültig ist, besteht darin, zu versuchen, darauf zuzugreifen. Die folgende Funktion ruft die Header von der angegebenen URL ab. Dadurch wird sichergestellt, dass die URL gültig ist UND der Webserver aktiv ist:

function is_url($url){
        $response = array();
        //Check if URL is empty
        if(!empty($url)) {
            $response = get_headers($url);
        }
        return (bool)in_array("HTTP/1.1 200 OK", $response, true);
/*Array
(
    [0] => HTTP/1.1 200 OK 
    [Date] => Sat, 29 May 2004 12:28:14 GMT
    [Server] => Apache/1.3.27 (Unix)  (Red-Hat/Linux)
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT
    [ETag] => "3f80f-1b6-3e1cb03b"
    [Accept-Ranges] => bytes
    [Content-Length] => 438
    [Connection] => close
    [Content-Type] => text/html
)*/ 
    }   
Bud Damyanov
quelle
Gute Idee. Dies schlägt fehl, wenn der Server HTTP / 1.0 oder HTTP / 2.0 verwendet oder eine Umleitung zurückgibt.
Iblamefish
Ja, es ist ein Ausgangspunkt, weitere Verbesserungen können leicht vorgenommen werden.
Bud Damyanov
0

Kam über diesen Artikel aus dem Jahr 2012. Es berücksichtigt Variablen, die nur einfache URLs sein können oder nicht .

Der Autor des Artikels, David Müeller , bietet diese Funktion, die er sagt, "... könnte sich lohnen", zusammen mit einigen Beispielen filter_varund ihren Mängeln.

/**
 * Modified version of `filter_var`.
 *
 * @param  mixed $url Could be a URL or possibly much more.
 * @return bool
 */
function validate_url( $url ) {
    $url = trim( $url );

    return (
        ( strpos( $url, 'http://' ) === 0 || strpos( $url, 'https://' ) === 0 ) &&
        filter_var(
            $url,
            FILTER_VALIDATE_URL,
            FILTER_FLAG_SCHEME_REQUIRED || FILTER_FLAG_HOST_REQUIRED
        ) !== false
    );
}
DaveyJake
quelle
0

Wenn jemand daran interessiert ist, die cURL zur Validierung zu verwenden. Sie können den folgenden Code verwenden.

<?php 
public function validationUrl($Url){
        if ($Url == NULL){
            return $false;
        }
        $ch = curl_init($Url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $data = curl_exec($ch);
        $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return ($httpcode >= 200 && $httpcode < 300) ? true : false; 
    }
VishalParkash
quelle