[英]PHP regex for url validation, filter_var is too permisive
首先,根據我的要求定義“URL”。
唯一允許的協議是http://
和https://
然后是像stackoverflow.com
這樣的強制域名
然后可選地其余的url組件( path
, query
, hash
,...)
根據我的要求,參考一個有效和無效網址列表
amazon.com/Computers-Internet-Books/b/ref=bhp_bb0309A_comint2?ie=UTF8&node=5&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=browse&pf_rd_r=0AH7GM29WF81Q72VPFDH&pf_rd_t=101&pf_rd_p=1273387142&pf_rd_i=283155
http://test-site.com (filter_var拒絕這個!!!我有破折號的域名)
valid
網址) 為了完整性,這里是我的PHP版本: 5.3.2-1ubuntu4.2
作為起點你可以使用這個, 它適用於JS ,但很容易將它轉換為PHP preg_match
。
/^(https?\://)?(www\.)?([a-z0-9]([a-z0-9]|(\-[a-z0-9]))*\.)+[a-z]+$/i
對於PHP應該工作這一個:
$reg = '@^(https?\://)?(www\.)?([a-z0-9]([a-z0-9]|(\-[a-z0-9]))*\.)+[a-z]+$@i';
這個正則表達式無論如何只驗證域部分 ,但你可以處理這個或者在第一個斜杠'/'
(在"://"
)拆分URL並分別驗證域部分和其余部分。
順便說一句:它也會驗證"http://www.domain.com.com"
但這不是錯誤,因為子域名網址可能是: "http://www.subdomain.domain.com"
,它是有效的! 並且幾乎沒有辦法(或者至少沒有操作簡單的方法)使用正則表達式驗證正確的域tld,因為你必須在內核中寫入所有可能的域tlds ONE by ONE,如下所示:
/^(https?\://)?(www\.)?([a-z0-9]([a-z0-9]|(\-[a-z0-9]))*\.)+(com|it|net|uk|de)$/i
(例如,最后一個將僅驗證以.com / .net / .de / .it / .co.uk結尾的域)。 新的tld 總是出來 ,所以你必須調整你的正則表達式每一個新的tld出來,這是一個痛苦的脖子!
您可以使用parse_url
將地址分解為其組件。 雖然它顯然不是為驗證URL而構建的,但分析生成的組件並將它們與您的要求相匹配至少是一個開始。
它可能會有所不同,但在大多數情況下,您並不需要檢查任何URL的有效性。
如果這是一個至關重要的信息,並且您信任您的用戶足以讓他通過URL提供,您可以信任他足以提供有效的URL。
如果它不是重要信息,那么您只需檢查XSS嘗試並顯示用戶想要的URL。
如果您沒有檢測到“http://”,可以手動添加“http://”以避免導航問題。
我知道,我不會給你一個替代解決方案,但也許解決性能和有效性問題的最佳方法就是避免不必要的檢查。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.