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.


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');
}

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")

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";
}

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;
    }
}

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; }
}

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));


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"]);
}


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
)*/ 
    }   

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
    );
}

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; 
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.