Cara terbaik untuk memeriksa apakah URL itu valid

149

Saya ingin menggunakan PHP untuk memeriksa, apakah string yang disimpan dalam $myoutputvariabel berisi sintaks tautan yang valid atau hanya teks biasa. Fungsi atau solusi, yang saya cari, harus mengenali semua format tautan termasuk yang dengan parameter GET.

Solusi, disarankan di banyak situs, untuk benar-benar query string (menggunakan CURL atau file_get_contents()fungsi) tidak mungkin dalam kasus saya dan saya ingin menghindarinya.

Saya memikirkan ekspresi reguler atau solusi lain.

Ryan
sumber
Menggunakan CURL atau mendapatkan konten HTTPnya mungkin lambat, jika Anda menginginkan sesuatu yang lebih cepat dan hampir dapat diandalkan, pertimbangkan untuk menggunakan gethostbyaddr () pada nama host. Jika itu memutuskan untuk IP, maka mungkin memiliki situs web. Tentu ini tergantung kebutuhan Anda.
TravisO

Jawaban:

301

Anda dapat menggunakan Validator Filter asli

filter_var($url, FILTER_VALIDATE_URL);

Memvalidasi nilai sebagai URL (menurut » http://www.faqs.org/rfcs/rfc2396 ), secara opsional dengan komponen yang diperlukan. Hati-hati URL yang valid mungkin tidak menentukan protokol HTTP http: // jadi validasi lebih lanjut mungkin diperlukan untuk menentukan URL menggunakan protokol yang diharapkan, misalnya ssh: // atau mailto :. Perhatikan bahwa fungsi hanya akan menemukan URL ASCII yang valid; nama domain internasional (mengandung karakter non-ASCII) akan gagal.

Contoh:

if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) {
    die('Not a valid URL');
}
Gordon
sumber
9
@Raveren perilaku yang diharapkan karena ini adalah URL yang valid.
Gordon
8
Sadarilah bahwa FILTER_VALIDATE_URLtidak akan memvalidasi protokol suatu url. Jadi ssh://, ftp://dll akan berlalu.
Seph
3
@SephVelut perilaku yang diharapkan karena ini adalah URL yang valid.
Gordon
1
itu memungkinkan url seperti ttp: //amazon.com
Elia Weiss
4
@ JoshHabdas, saya pikir Anda tidak mengerti intinya. Kode PHP melakukan persis seperti yang diklaimnya. Tapi itu tidak bisa membaca pikiran Anda. Ada perbedaan besar antara tidak valid dan tidak diinginkan .. Tidak diinginkan sangat subyektif, oleh karena itu diserahkan kepada programmer untuk mengerjakan detail itu. Anda mungkin juga mencatat kode memvalidasi URL, tetapi tidak membuktikannya ada. Bukan kesalahan PHP bahwa pengguna salah mengetik "amazon," "amozon," yang akan memvalidasi, tetapi masih tidak diinginkan.
JBH
20

Ini adalah tutorial terbaik yang saya temukan di sana:

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

Kemungkinan bendera:

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
sumber
1
Hanya satu nit: !filter_var(...) === false==> filter_var(...) === trueatau adil filter_var(...). :)
Domenico De Felice
@ ErichGarcía kode ini tidak memeriksa apakah itu HTTP / S URL yang valid seperti yang diminta OP. Ini akan meneruskan hal-hal seperti ssh: //, ftp: // dll ini hanya memeriksa apakah URL yang secara sintaksis valid menurut RFC 2396
twigg
Jangan gunakan FILTER_VALIDATE_URL. Itu berantakan dan tidak bisa diandalkan. Misalnya itu valid ttps://www.youtube.comsebagai valid
Jeffz
12

Menggunakan filter_var () akan gagal untuk url dengan karakter non-ascii, misalnya ( http://pt.wikipedia.org/wiki/Guimarães ). Fungsi berikut menyandikan semua karakter non-ascii (mis. Http://pt.wikipedia.org/wiki/Guimar%C3%A3es ) sebelum memanggil filter_var ().

Semoga ini bisa membantu seseorang.

<?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
sumber
Ini dia. Akhirnya seseorang kembali pada tahun 2017
Kyle KIM
Bekerja untuk saya (yang lain tidak BTW) :)
Jono
Ini adalah solusi HANYA yang bekerja untuk saya. Terima kasih!
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
sumber
3

Secara pribadi saya ingin menggunakan ekspresi reguler di sini. Kode di bawah berfungsi dengan baik untuk saya.

$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; }
}
Siddique Noor-A-Alam
sumber
1
Ini adalah jawaban terbaik untuk memvalidasi URL situs web. Dengan beberapa perubahan ini berfungsi dengan sempurna. Terima kasih
Amir hossein Karimi
3

Mengingat masalah dengan filter_var () yang membutuhkan http: //, saya menggunakan:

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

Autumn Leonard
sumber
Jangan gunakan FILTER_VALIDATE_URL. Itu berantakan dan tidak bisa diandalkan. Misalnya itu valid ttps://www.youtube.comsebagai valid
Jeffz
2

Anda dapat menggunakan fungsi ini, tetapi akan mengembalikan false jika situs web offline.

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

Sebenarnya ... filter_var ($ url, FILTER_VALIDATE_URL); tidak bekerja dengan baik. Ketika Anda mengetikkan url asli, itu berfungsi tetapi, ia hanya memeriksa http: // jadi jika Anda mengetikkan sesuatu seperti " http: // weirtgcyaurbatc ", ia masih akan mengatakan itu nyata.

Hayden Frobenius
sumber
Untuk intensi FILTER_VALIDATE_URL divalidasi ttps://www.youtube.comsebagai valid
Jeffz
1

Cara lain untuk memeriksa apakah URL yang diberikan valid adalah dengan mencoba mengaksesnya, fungsi di bawah ini akan mengambil header dari URL yang diberikan, ini akan memastikan bahwa URL itu valid DAN server web hidup:

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
sumber
Ide bagus. Ini akan gagal jika server menggunakan HTTP / 1.0 atau HTTP / 2.0, atau mengembalikan pengalihan.
iblamefish
Ya, ini adalah titik awal, perbaikan lebih lanjut dapat dilakukan dengan mudah.
Bud Damyanov
1

Datang di artikel ini dari 2012. Ini memperhitungkan variabel akun yang mungkin atau mungkin bukan sekadar URL biasa.

Penulis artikel tersebut, David Müeller , menyediakan fungsi ini yang ia katakan, "... bisa jadi berharga," bersama dengan beberapa contoh filter_vardan kekurangannya.

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

jika ada yang tertarik untuk menggunakan cURL untuk validasi. Anda dapat menggunakan kode berikut.

<?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
sumber