URLが有効かどうかを確認する最良の方法


149

PHPを使用して、$myoutput変数に格納された文字列に有効なリンク構文が含まれているか、それとも通常のテキストであるかを確認したいと思います。私が探している関数またはソリューションは、GETパラメーターを含むリンク形式を含むすべてのリンク形式を認識する必要があります。

多くのサイトで提案されている、CURLまたはfile_get_contents()関数を使用して実際に文字列をクエリするソリューションは、私の場合は不可能であり、回避したいと思います。

正規表現や別の解決策について考えました。


CURLを使用したり、HTTPコンテンツの取得に時間がかかる場合があります。より高速で信頼性の高いものが必要な場合は、ホスト名にgethostbyaddr()を使用することを検討してください。IPに解決される場合は、おそらくWebサイトがあります。もちろん、これはあなたのニーズに依存します。
TravisO 2010年

回答:


301

ネイティブのフィルターバリデーターを使用できます

filter_var($url, FILTER_VALIDATE_URL);

オプションで必要なコンポーネントを使用して、値をURLとして検証します(» http://www.faqs.org/rfcs/rfc2396に従って)。有効なURLではHTTPプロトコルhttp://が指定されていない可能性があるため、URLが期待されるプロトコル(ssh://やmailto:など)を使用していることを確認するには、さらに検証が必要になる場合があります。この関数は、有効なASCII URLのみを検出することに注意してください。国際化ドメイン名(非ASCII文字を含む)は失敗します。

例:

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

9
@Raverenは有効なURLであるため、予想される動作です。
Gordon、

8
FILTER_VALIDATE_URLはURLのプロトコルを検証しないことに注意してください。なのでssh://ftp://等は通過します。
SEPH

3
@SephVelutは有効なURLであるため、予想される動作です。
ゴードン

1
ttp://amazon.comのようなURLを許可
Elia Weiss

4
@JoshHabdas、私はあなたが要点を逃していると思います。PHPコードは、その主張どおりに動作します。しかし、それはあなたの心を読むことができません。無効と不要との間には大きな違いがあります。不要なものは非常に主観的であるため、プログラマーがその詳細を検討する必要があります。コードがURLを検証するが、それが存在することを証明しないことにも注意してください。ユーザーが「amazon」、「amozon」を誤って入力したのはPHPのせいではありません。
JBH 2018年

20

ここに私がそこに見つけた最高のチュートリアルがあります:

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

可能なフラグ:

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
単なるnit:!filter_var(...) === false==> filter_var(...) === trueまたはfilter_var(...)。:)
Domenico De Felice

@ErichGarcíaこのコードは、OPが要求するような有効なHTTP / S URLであることを確認しません。これは、ssh://、ftp://などのようなものを渡します。これは、RFC 2396に従って構文的に有効なURLであるかどうかをチェックするだけです
twigg

FILTER_VALIDATE_URLは使用しないでください。乱雑で信頼性が低いです。たとえば、有効であると検証さttps://www.youtube.comれます
ジェフズ

12

filter_var()を使用すると、ASCII以外の文字が含まれるURL(たとえば、http://pt.wikipedia.org/wiki/Guimarães)で失敗します。次の関数は、filter_var()を呼び出す前に、すべての非ASCII文字(http://pt.wikipedia.org/wiki/Guimar%C3%A3esなど)をエンコードします。

これが誰かを助けることを願っています。

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

これだよ。最後に誰かが2017年に戻ってきた
カイルKIM

私のために働く(他の人はBTWではありません):)
Jono

これは私のために働いた唯一の解決策です。ありがとう!
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

個人的にはここで正規表現を使いたいと思います。怒鳴るコードは完全に私のために働いた。

$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
これは、WebサイトのURLを検証するための最良の答えです。わずかな変更で、これは完全に機能します。ありがとう
アミールホセインカリミ

3

filter_var()でhttp://が必要な問題を考えると、次のように使用します。

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


FILTER_VALIDATE_URLは使用しないでください。乱雑で信頼性が低いです。たとえば、有効であると検証さttps://www.youtube.comれます
ジェフズ

2

この関数は使用できますが、Webサイトがオフラインの場合はfalseを返します。

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

2

実際... filter_var($ url、FILTER_VALIDATE_URL); うまく機能しません。実際のURLを入力すると機能しますが、http://のみをチェックするため、「http:// weirtgcyaurbatc」のように入力しても、実際のURLであると表示されます。


インスタンスの場合、FILTER_VALIDATE_URLは有効であると検証さttps://www.youtube.comれます
Jeffz

1

指定されたURLが有効であるかどうかを確認する別の方法は、それ、指定されたURLからヘッダを取得する関数の下に、これはURLが有効であることが保証されますアクセスしようとしている、Webサーバが生きています:

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

良いアイデア。サーバーがHTTP / 1.0またはHTTP / 2.0を使用している場合、またはリダイレクトを返す場合、これは失敗します。
イブラメフィッシュ2017

はい、それは出発点であり、さらなる改善は簡単に行うことができます。
Bud Damyanov 2017

1

2012年からこの記事に出くわしました。単なるURLである場合とそうでない場合がある変数が考慮されます。

記事の作成者であるDavidMüellerは、彼が言うこの機能を「いくつかの例filter_varとその欠点とともに」「提供する価値がある」と述べています。

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

検証にcURLを使用することに関心がある場合。次のコードを使用できます。

<?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; 
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.