วิธีที่ดีที่สุดในการตรวจสอบว่า URL นั้นถูกต้องหรือไม่


149

ฉันต้องการใช้ PHP เพื่อตรวจสอบว่าสตริงที่เก็บไว้ใน$myoutputตัวแปรมีไวยากรณ์ลิงค์ที่ถูกต้องหรือเป็นเพียงข้อความปกติ ฟังก์ชันหรือโซลูชันที่ฉันกำลังค้นหาควรรู้จักรูปแบบลิงก์ทั้งหมดรวมถึงรายการที่มีพารามิเตอร์ GET

วิธีแก้ปัญหาที่แนะนำในหลาย ๆ ไซต์เกี่ยวกับการสืบค้นสตริง (ใช้ CURL หรือfile_get_contents()ฟังก์ชั่น) เป็นไปไม่ได้ในกรณีของฉันและฉันต้องการหลีกเลี่ยง

ฉันนึกถึงนิพจน์ทั่วไปหรือวิธีแก้ไขปัญหาอื่น


การใช้ CURL หรือการรับเนื้อหา HTTP อาจช้าถ้าคุณต้องการบางสิ่งที่รวดเร็วและเชื่อถือได้มากขึ้นลองใช้ gethostbyaddr () บนชื่อโฮสต์ หากสามารถแก้ไขเป็น IP ได้แสดงว่ามีเว็บไซต์ หลักสูตรนี้ขึ้นอยู่กับความต้องการของคุณ
TravisO

คำตอบ:


301

คุณสามารถใช้ Native Validator Filter

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 ที่ถูกต้อง
กอร์ดอน

8
โปรดทราบว่าFILTER_VALIDATE_URLจะไม่ตรวจสอบโปรโตคอลของ URL ดังนั้นssh://, ftp://ฯลฯ จะผ่าน
Seph

3
@SephVelut พฤติกรรมที่คาดหวังเนื่องจากเป็น URL ที่ถูกต้อง
Gordon

1
มันอนุญาตให้ URL เช่น ttp: //amazon.com
Elia Weiss

4
@JoshHabdas ฉันคิดว่าคุณไม่มีจุด รหัส PHP ทำในสิ่งที่มันอ้างว่าทำ แต่มันไม่สามารถอ่านใจคุณได้ มีความแตกต่างอย่างมากระหว่างสิ่งที่ไม่ถูกต้องกับสิ่งที่ไม่พึงประสงค์ .. สิ่งที่ไม่เป็นที่ต้องการนั้นเป็นเรื่องส่วนตัวซึ่งเป็นสาเหตุที่ทำให้โปรแกรมเมอร์ต้องทำงานในรายละเอียดนั้น คุณอาจสังเกตว่ารหัสตรวจสอบความถูกต้องของ URL แต่ไม่ได้พิสูจน์ว่ามีอยู่ ไม่ใช่ความผิดของ PHP ที่ผู้ใช้พิมพ์ "amazon," "amozon" ซึ่งจะตรวจสอบความถูกต้อง แต่ยังไม่ต้องการ
JBH

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
เพียงนิด: !filter_var(...) === false==> หรือเพียงแค่filter_var(...) === true filter_var(...):)
Domenico De Felice

@ ErichGarcíaรหัสนี้ไม่ได้ตรวจสอบว่าเป็น HTTP / S URL ที่ถูกต้องเช่นเดียวกับ OP ถาม นี้จะผ่านสิ่งเช่น SSH: // ftp: // ฯลฯ นี้เฉพาะการตรวจสอบถ้ามัน URL ที่ถูกต้อง syntactically ตาม RFC 2396
Twigg

อย่าใช้ FILTER_VALIDATE_URL มันยุ่งและไม่น่าเชื่อถือ เช่นมันตรวจสอบttps://www.youtube.comว่าถูกต้อง
Jeffz

12

การใช้ filter_var () จะล้มเหลวสำหรับ URL ที่มีตัวอักษรที่ไม่ใช่ ASCII เช่น ( http://pt.wikipedia.org/wiki/Guimarães ) ฟังก์ชันต่อไปนี้เข้ารหัสตัวอักษรที่ไม่ใช่ ASCII ทั้งหมด (เช่นhttp://pt.wikipedia.org/wiki/Guimar%C3%A3es ) ก่อนที่จะเรียก filter_var ()

หวังว่านี่จะช่วยใครซักคน

<?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
Kyle KIM

ใช้งานได้สำหรับฉัน (คนอื่นไม่ใช้ BTW) :)
Jono

นี่เป็นทางออกเดียวที่ใช้ได้สำหรับฉัน ขอบคุณ!
สิลาส

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
นี่คือคำตอบที่ดีที่สุดในการตรวจสอบ URL เว็บไซต์ ด้วยการเปลี่ยนแปลงเล็กน้อยงานนี้สมบูรณ์แบบ ขอบคุณ
Amir hossein Karimi

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ว่าถูกต้อง
Jeffz

2

คุณสามารถใช้ฟังก์ชั่นนี้ แต่มันจะกลับเท็จถ้าเว็บไซต์ออฟไลน์

  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 " ก็จะยังคงบอกว่ามันเป็นของจริง


สำหรับ intance FILTER_VALIDATE_URL ตรวจสอบttps://www.youtube.comว่าใช้ได้
Jeffz

1

อีกวิธีในการตรวจสอบว่า URL ที่ระบุนั้นถูกต้องหรือไม่คือพยายามเข้าถึงด้านล่างฟังก์ชั่นจะดึงส่วนหัวจาก URL ที่กำหนดซึ่งจะทำให้แน่ใจว่า URL นั้นถูกต้องและเว็บเซิร์ฟเวอร์ยังมีชีวิตอยู่:

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 หรือส่งคืนการเปลี่ยนเส้นทาง
iblamefish

ใช่มันเป็นจุดเริ่มต้นการปรับปรุงเพิ่มเติมสามารถทำได้อย่างง่ายดาย
Bud Damyanov

1

มาจากบทความนี้ตั้งแต่ปี 2012 โดยจะพิจารณาตัวแปรบัญชีที่อาจเป็นหรือไม่ใช่ URL ธรรมดาก็ได้

David Müellerผู้เขียนบทความนำเสนอฟังก์ชั่นนี้ที่เขาพูดว่า "... น่าจะคุ้มค่ามาก [sic]" พร้อมกับตัวอย่างบางส่วน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.