Я пытаюсь получить хост от URL с помощью parse_url. Но в некоторых запросах я получаю пустые результаты. Вот моя функция:
function clean_url($urls){
$good_url=array();
for ($i=0;$i<count($urls);$i++){
$url=parse_url($urls[$i]);
//$temp_string=str_replace("http://", "", $urls[$i]);
//$temp_string=str_replace("https://", "", $urls[$i]);
//$temp_string=substr($temp_string, 0,stripos($temp_string,"/"));
array_push($good_url, $url['host']);
}
return $good_url;
}
Входной массив:
Array (
[0] => https://en.wikipedia.org/wiki/Data
[1] => data.gov.ua/
[2] => e-data.gov.ua/
[3] => e-data.gov.ua/transaction
[4] => https://api.jquery.com/data/
[5] => https://api.jquery.com/jquery.data/
[6] => searchdatamanagement.techtarget.com/definition/data
[7] => www.businessdictionary.com/definition/data.html
[8] => https://data.world/
[9] => https://en.oxforddictionaries.com/definition/data
)
Массив результатов с пустыми результатами
Array (
[0] => en.wikipedia.org
[1] =>
[2] =>
[3] =>
[4] => api.jquery.com
[5] => api.jquery.com
[6] =>
[7] =>
[8] => data<
[9] => en.oxforddictionaries.com
)
Некоторые из тех $urls
которые анализируются, не имеют схем, которые вызывают parse_url
распознавать хосты как пути.
Например, разбор URL data.gov.ua/
возвращается data.gov.ua/
как путь. Добавление схемы, например https
на этот URL, так что это https://data.gov.ua/
позволит parse_url
узнавать data.gov.ua/
как хозяин.
Я выполнил ваш скрипт и получил ошибку php:
Примечание: неопределенный индекс: хост
Таким образом, переменная $ url [‘host’] не существует … Если в этом случае я получу var_dump, будет возвращено содержимое:
array (size=3)
'scheme' => string 'https' (length=5)
'host' => string 'en.wikipedia.org' (length=16)
'path' => string '/wiki/Data' (length=10)
array (size=1)
'path' => string 'data.gov.ua/' (length=12)
( ! ) Notice: Undefined index: hostarray (size=1)
'path' => string 'e-data.gov.ua/' (length=14)
( ! ) Notice: Undefined index: host
Как видите, URL интерпретируются как путь.
Выходы:
$urls[] = 'data.gov.ua/';
Ошибка. Неверный URL$urls[] = '//data.gov.ua/';
Действительно.$urls[] = 'http://data.gov.ua/';
Действительно.Советы: Используйте //
если вы не знаете, http это или https.
Кстати, вы можете упростить ваш код: p
function clean_url(array $urls) {
$good_url = [];
foreach( $urls as $url ) {
// add a chech on the start of the url.
$parse = parse_url($url);
if( isset($url['host']) )
array_push($good_url, $url['host']);
else
$good_url[] = 'Invalid Url'; // for example, or triger error.
}
return $good_url;
}
Увидеть foreach
а также isset
Общий формат URL:
scheme://hostname:port/path?query#fragment
Каждая часть URL является необязательной и использует разделители между ними, чтобы определить, какие части были предоставлены или опущены.
Имя хоста является частью URL после //
префикс. Во многих ваших URL отсутствует этот префикс, поэтому у них нет имени хоста.
Например, parse_url('data.gov.ua/')
возвращает:
Array
(
[path] => data.gov.ua/
)
Чтобы получить то, что вы хотите, это должно быть parse_url('//data.gov.ua/')
:
Array
(
[host] => data.gov.ua
[path] => /
)
Это часто сбивает с толку программистов, потому что браузеры очень прощают ввод неполных URL в поле местоположения, у них есть эвристика, чтобы попытаться решить, является ли что-то именем хоста или путем. Но API, как parse_url()
более строги по этому поводу.
Я сделал эту простую функцию, которая дает мне URL (для имени) и полный URL (для ссылки)
public static function parseUrl($target_url)
{
$url = "";
$url_full = "";
if (!empty($target_url)) {
$parser = @parse_url($target_url);
if (!empty($parser['host'])) {
$url = $parser['host'];
if (!empty($parser['scheme'])) {
$url_full = $parser['scheme'] . "://" . $parser['host'];
} else {
$url_full = "//" . $parser['host'];
}
} else {
if (!empty($parser['path'])) {
return self::parseUrl("//".$parser['path']);
}
}
}
return array('url' => $url, 'url_full' => $url_full);
}
что хорошо сочетается с примером
Array
(
[url] => en.wikipedia.org
[url_full] => https://en.wikipedia.org
)
Array
(
[url] => data.gov.ua
[url_full] => //data.gov.ua
)
Array
(
[url] => e-data.gov.ua
[url_full] => //e-data.gov.ua
)
Array
(
[url] => e-data.gov.ua
[url_full] => //e-data.gov.ua
)
Array
(
[url] => api.jquery.com
[url_full] => https://api.jquery.com
)
Array
(
[url] => api.jquery.com
[url_full] => https://api.jquery.com
)
Array
(
[url] => searchdatamanagement.techtarget.com
[url_full] => //searchdatamanagement.techtarget.com
)
Array
(
[url] => www.businessdictionary.com
[url_full] => //www.businessdictionary.com
)
Array
(
[url] => data.world
[url_full] => https://data.world
)
Array
(
[url] => en.oxforddictionaries.com
[url_full] => https://en.oxforddictionaries.com
)
Таким образом, вы можете использовать тогда:
<a href="{$url['url_full']}" target="_blank">{$url['url']}</a>
Некоторое время назад я разработал решение аналогичной проблемы.
Я сделал некоторые изменения в своем исходном коде, чтобы соответствовать вашей спецификации.
Это функционально, но не очень элегантно.
function clean_url($urls)
{
$good_url=array();
for ($i=0;$i<count($urls);$i++){
$domain=$urls[$i];
$domain = str_replace("www.","",$domain);
$domain = str_replace("https://","",$domain);
$domain = str_replace("http://","",$domain);
$domain=explode("/", $domain);
array_push($good_url, $domain[0]);
}
return $good_url;
}
$urls=array(
"0" => "https://en.wikipedia.org/wiki/Data" ,
"1" => "data.gov.ua/" ,
"2" => "e-data.gov.ua/",
"3" => "e-data.gov.ua/transaction",
"4" => "https://api.jquery.com/data/",
"5" => "https://api.jquery.com/jquery.data/" ,
"6" => "searchdatamanagement.techtarget.com/definition/data" ,
"7" => "www.businessdictionary.com/definition/data.html" ,
"8" => "https://data.world/",
"9" => "https://en.oxforddictionaries.com/definition/data");
echo "<pre>";
print_r(clean_url($urls));
echo "</pre>";
С наилучшими пожеланиями,
Это была неправильная схема http. Я добавил http: // ко всем URL-адресам, и это работает