2014-02-19 61 views
0

我不想重新發明輪子,但我找不到任何可以完美實現這一點的圖書館。PHP自動更正網址

在我的腳本用戶可以保存的網址,我想如果他們給我名單,如:

google.com 
www.msn.com 
http://bing.com/ 
and so on... 

我希望能夠在「正確的格式」數據庫來保存。

我做的是我檢查它是否有協議,如果它不存在我添加它,然後驗證網址對RegExp。

對於PHP parse_url,任何包含協議的URL都是有效的,所以它沒有太多幫助。

你是如何做這件事的,你有一些想法,你想與我分享?

編輯:

我想篩選出來自用戶的輸入無效的URL(URL列表)。更重要的是,要嘗試自動更正無效的網址(例如不包含協議)。一個用戶輸入列表,它應該立即驗證(沒時間打開URL來檢查它們確實存在)。

從URL中提取部分會很好,例如parse_url,但parse_url的問題在於,它對無效的URL不起作用。我嘗試使用它來解析URL,以及缺少(並且必需)添加默認項的部分(例如無協議,添加http)。但「google.com」的parse_url不會返回「google.com」作爲主機名,而是路徑。

這看起來非常常見的問題給我,但我無法找到互聯網上可用的解決方案(發現了一些庫,將標準化URL,但他們不會修復URL,如果它是無效的)。

有一些「聰明」的解決方案,這一點,或者我應該用我目前的堅持:

  • 找到第一次出現://和驗證,如果它之前的文本是有效的協議,如果缺少添加協議
  • 發現下一次出現/和驗證是通過主機名正則表達式整個URL是有效的格式
  • 良好的措施驗證一次

我只是感覺,我會拒絕索姆e有效的URL,對我而言,最好有誤報,即假陰性。

+0

爲什麼'parse_url()'不足? – kba

+1

這種事情真的很難。你是否試圖確保它們是有效的,或只是他們「看起來」有效。例如,如果有人輸入http://subdomain.domain/你想用它做什麼?嚴格來說,這是一個無效的域名,因爲沒有tld?這種類型的問題可能會從徹頭徹尾的懶散黑客中擺脫出來,過度使用 - 你能否更詳細地解釋你想要在解決方案的哪個位置? – Trent

回答

2

我曾與parse_url作爲OP同樣的問題,這是我的快速和骯髒的解決方案來自動正確的URL(記住,在沒有辦法的代碼是完美的或覆蓋所有的情況下):

Results: 
http:/wwww.example.com/lorum.html => http://www.example.com/lorum.html 
gopher:/ww.example.com => gopher://www.example.com 
http:/www3.example.com/?q=asd&f=#asd =>http://www3.example.com/?q=asd&f=#asd 
asd://.example.com/folder/folder/ =>http://example.com/folder/folder/ 
.example.com/ => http://example.com/ 
example.com =>http://example.com 
subdomain.example.com => http://subdomain.example.com 
function url_parser($url) { 

// multiple /// messes up parse_url, replace 2+ with 2 
$url = preg_replace('/(\/{2,})/','//',$url); 

$parse_url = parse_url($url); 

if(empty($parse_url["scheme"])) { 
    $parse_url["scheme"] = "http"; 
} 
if(empty($parse_url["host"]) && !empty($parse_url["path"])) { 
    // Strip slash from the beginning of path 
    $parse_url["host"] = ltrim($parse_url["path"], '\/'); 
    $parse_url["path"] = ""; 
} 

$return_url = ""; 

// Check if scheme is correct 
if(!in_array($parse_url["scheme"], array("http", "https", "gopher"))) { 
    $return_url .= 'http'.'://'; 
} else { 
    $return_url .= $parse_url["scheme"].'://'; 
} 

// Check if the right amount of "www" is set. 
$explode_host = explode(".", $parse_url["host"]); 

// Remove empty entries 
$explode_host = array_filter($explode_host); 
// And reassign indexes 
$explode_host = array_values($explode_host); 

// Contains subdomain 
if(count($explode_host) > 2) { 
    // Check if subdomain only contains the letter w(then not any other subdomain). 
    if(substr_count($explode_host[0], 'w') == strlen($explode_host[0])) { 
     // Replace with "www" to avoid "ww" or "wwww", etc. 
     $explode_host[0] = "www"; 

    } 
} 
$return_url .= implode(".",$explode_host); 

if(!empty($parse_url["port"])) { 
    $return_url .= ":".$parse_url["port"]; 
} 
if(!empty($parse_url["path"])) { 
    $return_url .= $parse_url["path"]; 
} 
if(!empty($parse_url["query"])) { 
    $return_url .= '?'.$parse_url["query"]; 
} 
if(!empty($parse_url["fragment"])) { 
    $return_url .= '#'.$parse_url["fragment"]; 
} 


return $return_url; 
} 

echo url_parser('http:/wwww.example.com/lorum.html'); // http://www.example.com/lorum.html 
echo url_parser('gopher:/ww.example.com'); // gopher://www.example.com 
echo url_parser('http:/www3.example.com/?q=asd&f=#asd'); // http://www3.example.com/?q=asd&f=#asd 
echo url_parser('asd://.example.com/folder/folder/'); // http://example.com/folder/folder/ 
echo url_parser('.example.com/'); // http://example.com/ 
echo url_parser('example.com'); // http://example.com 
echo url_parser('subdomain.example.com'); // http://subdomain.example.com 
0

這不是100%的萬無一失,而是1班輪。

$URL = (((strpos($URL,'https://') === false) && (strpos($URL,'http://') === false))?'http://':'').$URL; 

編輯 有顯然與我最初的版本問題,如果主機名包含HTTP。

感謝特倫特

+0

主機名中帶有「http」的任何域都會失敗:) – Trent

+0

ftp://example.com/resource.ext也會失敗。 – ntatic

+0

我剛剛在「WriteCodeOnline.com」'example.com/resource.ext> http:// example.com/resource.ext','http://example.com/resource.ext> http:// example .com/resource.ext'是不是你要求的?該代碼沒有任何複雜性,它檢查字符串是以Http://還是https://開頭,如果不在那裏,則添加它。 –