Cách tốt nhất để kiểm tra xem URL có hợp lệ không


149

Tôi muốn sử dụng PHP để kiểm tra, nếu chuỗi được lưu trữ trong $myoutputbiến có chứa cú pháp liên kết hợp lệ hay đó chỉ là một văn bản bình thường. Hàm hoặc giải pháp mà tôi đang tìm kiếm sẽ nhận ra tất cả các định dạng liên kết bao gồm các định dạng có tham số GET.

Một giải pháp, được đề xuất trên nhiều trang web, để thực sự truy vấn chuỗi (sử dụng file_get_contents()hàm CURL hoặc hàm) là không thể trong trường hợp của tôi và tôi muốn tránh nó.

Tôi nghĩ về các biểu thức thông thường hoặc giải pháp khác.


Sử dụng CURL hoặc nhận nội dung HTTP có thể chậm, nếu bạn muốn thứ gì đó nhanh hơn và gần như đáng tin cậy hơn, hãy cân nhắc sử dụng gethostbyaddr () trên tên máy chủ. Nếu nó phân giải thành một IP, thì nó có thể có một trang web. Tất nhiên điều này phụ thuộc vào nhu cầu của bạn.
TravisO

Câu trả lời:


301

Bạn có thể sử dụng Trình xác thực bộ lọc riêng

filter_var($url, FILTER_VALIDATE_URL);

Xác thực giá trị dưới dạng URL (theo » http://www.faqs.org/rfcs/rfc2394 ), tùy chọn với các thành phần bắt buộc. Coi chừng một URL hợp lệ có thể không chỉ định giao thức HTTP http: // vì vậy có thể cần xác thực thêm để xác định URL sử dụng giao thức dự kiến, ví dụ: ssh: // hoặc mailto :. Lưu ý rằng chức năng sẽ chỉ tìm thấy các URL ASCII là hợp lệ; tên miền quốc tế hóa (chứa các ký tự không phải ASCII) sẽ thất bại.

Thí dụ:

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

9
@Raveren hành vi dự kiến ​​vì đây là các URL hợp lệ.
Gordon

8
Xin lưu ý rằng FILTER_VALIDATE_URLsẽ không xác nhận giao thức của một url. Vì vậy ssh://, ftp://vv sẽ vượt qua.
Seph

3
@SephVelut hành vi dự kiến ​​vì đây là các URL hợp lệ.
Gordon

1
nó cho phép các url như ttp: //amazon.com
Elia Weiss

4
@JoshHabdas, tôi nghĩ bạn đang thiếu điểm. Mã PHP thực hiện chính xác những gì nó tuyên bố sẽ làm. Nhưng nó không thể đọc được suy nghĩ của bạn. Có một sự khác biệt rất lớn giữa không hợp lệ và không mong muốn .. Không mong muốn là rất chủ quan, đó là lý do tại sao nó để cho lập trình viên tìm ra chi tiết đó. Bạn cũng có thể lưu ý mã xác thực URL, nhưng không chứng minh được nó tồn tại. Không phải lỗi của PHP khi người dùng nhập nhầm "amazon", "amozon", sẽ xác nhận, nhưng vẫn không mong muốn.
JBH

20

Đây là hướng dẫn tốt nhất tôi tìm thấy ở đó:

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

Cờ có thể:

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
Chỉ là một nit: !filter_var(...) === false==> filter_var(...) === truehoặc chỉ filter_var(...). :)
Domenico De Felice

@ ErichGarcía mã này không kiểm tra xem đó có phải là URL HTTP / S hợp lệ giống như OP yêu cầu không. Điều này sẽ vượt qua những thứ như ssh: //, ftp: // vv. Điều này chỉ kiểm tra xem URL của nó có hợp lệ về mặt cú pháp theo RFC 2396
twigg

Không sử dụng FILTER_VALIDATE_URL. Nó lộn xộn và không đáng tin cậy. Ví dụ: nó ttps://www.youtube.comhợp lệ là hợp lệ
Jeffz

12

Sử dụng bộ lọc_var () sẽ thất bại đối với các url có ký tự không phải mã ascii, ví dụ ( http://pt.wikipedia.org/wiki/Guimarães ). Hàm sau mã hóa tất cả các ký tự không phải mã ascii (ví dụ: http://pt.wikipedia.org/wiki/Guimar%C3%A3es ) trước khi gọi bộ lọc_var ().

Hy vọng điều này sẽ giúp được ai đó.

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

Đây là nó. Cuối cùng, ai đó đã trở lại vào năm 2017
Kyle KIM

Làm việc cho tôi (những người khác không BTW) :)
Jono

Đây là giải pháp DUY NHẤT làm việc cho tôi. Cảm ơn!
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

Cá nhân tôi muốn sử dụng biểu thức thường xuyên ở đây. Mã dưới đây hoàn toàn làm việc cho tôi.

$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
Đây là câu trả lời tốt nhất để xác thực URL trang web. Với một vài thay đổi, công việc này hoàn hảo. Cảm ơn
Amir hossein Karimi

3

Đưa ra các vấn đề với bộ lọc_var () cần http: //, tôi sử dụng:

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


Không sử dụng FILTER_VALIDATE_URL. Nó lộn xộn và không đáng tin cậy. Ví dụ: nó ttps://www.youtube.comhợp lệ là hợp lệ
Jeffz

2

Bạn có thể sử dụng chức năng này, nhưng nó sẽ trả về false nếu trang web ngoại tuyến.

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

2

Trên thực tế ... filter_var ($ url, FILTER_VALIDATE_URL); không hoạt động tốt Khi bạn nhập một url thực, nó hoạt động nhưng nó chỉ kiểm tra http: // vì vậy nếu bạn nhập một cái gì đó như " http: // weirtgcyaurbatc ", nó vẫn sẽ nói là thật.


Đối với intance FILTER_VALIDATE_URL ttps://www.youtube.comhợp lệ là hợp lệ
Jeffz

1

Một cách khác để kiểm tra xem URL đã cho có hợp lệ hay không là thử truy cập vào URL, chức năng bên dưới sẽ tìm nạp các tiêu đề từ URL đã cho, điều này sẽ đảm bảo rằng URL hợp lệ máy chủ web vẫn còn hoạt động:

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

Ý kiến ​​hay. Điều này sẽ thất bại nếu máy chủ đang sử dụng HTTP / 1.0 hoặc HTTP / 2.0 hoặc trả về chuyển hướng.
cá iblamefish

Vâng, đó là một điểm khởi đầu, cải tiến hơn nữa có thể được thực hiện dễ dàng.
Bud Damyanov

1

Đã xem qua bài viết này từ năm 2012. Nó đưa vào các biến tài khoản có thể hoặc không chỉ là các URL đơn giản.

Tác giả của bài báo, David Müeller , cung cấp chức năng này mà ông nói, "... có thể đáng giá [sic]", cùng với một số ví dụ về filter_varvà những thiếu sót của nó.

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

nếu bất cứ ai quan tâm đến việc sử dụng cURL để xác nhận. Bạn có thể sử dụng mã sau đây.

<?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; 
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.