2010-01-13 8 views
98

Je veux utiliser PHP pour vérifier si la chaîne stockée dans la variable $myoutput contient une syntaxe de lien valide ou s'il s'agit simplement d'un texte normal. La fonction ou la solution que je recherche devrait reconnaître tous les formats de liens, y compris ceux avec des paramètres GET.La meilleure façon de vérifier si une URL est valide

Une solution, suggérée sur de nombreux sites, pour réellement interroger la chaîne (en utilisant la fonction CURL ou file_get_contents()) n'est pas possible dans mon cas et je voudrais l'éviter. Je pensais aux expressions régulières ou à une autre solution.

+0

Utilisation CURL ou d'obtenir c'est HTTP contenu peut être lent, si vous voulez quelque chose de plus rapide et presque fiable, pensez à utiliser gethostbyaddr() sur le nom d'hôte.S'il se résout à une IP, alors il a probablement un site Web. Bien sûr, cela dépend de vos besoins. – TravisO

Répondre

198

Vous pouvez utiliser un Filter Validator natif

filter_var($url, FILTER_VALIDATE_URL); 

valeur URL est validée (selon »http://www.faqs.org/rfcs/rfc2396), éventuellement avec des composants nécessaires. Attention, une URL valide ne peut pas spécifier le protocole HTTP http: //, donc une validation supplémentaire peut être nécessaire pour déterminer si l'URL utilise un protocole attendu, par ex. ssh: // ou mailto :. Notez que la fonction ne trouvera que les URL ASCII pour être valide; les noms de domaine internationalisés (contenant des caractères non-ASCII) échoueront.

Exemple:

if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) { 
    die('Not a valid URL'); 
} 
+7

il permet également d'urls comme 'http: // example' (thik' localhost' est une url) – raveren

+5

@Raveren comportement attendu puisque ce sont des URL valides. – Gordon

+6

Sachez que 'FILTER_VALIDATE_URL' ne validera pas le protocole d'une URL. Donc 'ssh: //', 'ftp: //' etc passera. – Seph

4
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; 
    } 
} 
+2

Qu'en est-il de: 'http: // 192.168.1.12' ou' http: // 192.168.1.12/some-page'? – Haudegen

2

Vous pouvez utiliser cette fonction, mais son retournera false si le site hors ligne.

function isValidUrl($url) { 
    $url = parse_url($url); 
    if (!isset($url["host"])) return false; 
    return !(gethostbyname($url["host"]) == $url["host"]); 
} 
6

Voici le meilleur tutoriel j'ai trouvé là-bas:

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

drapeaux possibles:

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

Une autre façon de vérifier si l'URL donnée est valide est de essayer d'y accéder, la fonction ci-dessous va chercher les en-têtes à partir de l'URL donnée, ce qui assurera que URL est le serveur Web valide ET est vivant:

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

Bonne idée. Cela échouera si le serveur utilise HTTP/1.0 ou HTTP/2.0 ou renvoie une redirection. – iblamefish

+0

Oui, c'est un point de départ, d'autres améliorations peuvent être faites facilement. – bodi0

5

En utilisant filter_var() échouera pour urls avec les caractères non-ascii, par exemple(). La fonction suivante code tous les caractères non-ascii (par exemple, http://pt.wikipedia.org/wiki/Guimar%C3%A3es) avant d'appeler filter_var().

Espérons que cela aide quelqu'un.

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

Personnellement, je voudrais utiliser l'expression régulière ici. Le code ci-dessous a parfaitement fonctionné pour moi.

$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+!*(),;?&=\$_.-]+)[email protected])?"; // 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://)[email protected]",'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

questions Administré avec filter_var() besoin http: //, j'utilise:

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

Questions connexes