Мне нужно создать функцию, которая анализирует домен по URL-адресу.
Итак, с
http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
или же
http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html
он должен вернуть google.com
с
http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html
он должен вернуть google.co.uk.
@LightnessRacesinOrbit Это немного больше, чем просто «заглядывать в руководство». parse_url() PHP возвращает хозяин, а не домен.
@ w3dk: Это все равно было бы фантастической отправной точкой, если бы этот вопрос касался этого ограничения parse_url, а не расплывчатого «что я могу сделать».
@LightnessRacesinOrbit ваша защита неискренняя, учитывая вашу репутацию - проще говоря, вы можете признать, что не прочитали вопрос полностью
@AndyJones: Я прекрасно прочитал вопрос, спасибо
@LightnessRacesinOrbit Тогда каков ответ? Все еще ищу способ получить -domain-, а не -host-.
@AutumnLeonard: домен является хоста.
@LightnessRacesinOrbit Не обязательно. support.suso.com/supki/…






$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'google.com'
parse_url не очень хорошо обрабатывает действительно сильно искаженные URL-адреса, но это нормально, если вы обычно ожидаете приличных URL-адресов.
Единственное, чего не делает parse_url (), - это только возвращать домен. Если вы добавите www.google.com или www.google.co.uk, он также вернет хост. Есть предложения по этому поводу?
@Crad, stackoverflow.com/questions/8272805/…
parse_url(), возможно, неправильно проанализирует URL-адреса с доменом, который содержит дефисы. Не удалось найти точных доказательств, но проверьте эта ошибка. FILTER_VALIDATE_URL внутренне использует parse_url().
Или просто: print parse_url($url, PHP_URL_HOST)), если массив $parse вам ни для чего не нужен.
Не обрабатывает domain.eu, который является вполне допустимым доменом.
@tftd - это потому, что parse_url ожидает передачи url, но domain.eu - это только часть имени домена / имени хоста URL-адреса. «parse_url анализирует URL-адрес и возвращает ассоциативный массив, содержащий любой из различных компонентов URL-адреса, которые присутствуют. Эта функция - не предназначено для проверки для данного URL-адреса ...»
От http://us3.php.net/manual/en/function.parse-url.php#93983
for some odd reason, parse_url returns the host (ex. example.com) as the path when no scheme is provided in the input url. So I've written a quick function to get the real host:
function getHost($Address) {
$parseUrl = parse_url(trim($Address));
return trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2)));
}
getHost("example.com"); // Gives example.com
getHost("http://example.com"); // Gives example.com
getHost("www.example.com"); // Gives www.example.com
getHost("http://example.com/xyz"); // Gives example.com
Не забудьте процитировать свои строки, например host и path.
Если я использую example.com, php отображает уведомление: Message: Undefined index: host Есть идеи, как это исправить?
К сожалению, субдомен все еще включен в этот подход, см. Ваш пример №3.
@ Zim3r Измените первую часть троицы на !empty($parseUrl['host']).
LOL, если у него нет схемы, это не URL-адрес.
В вопросе упоминается, что www. также следует удалить, поэтому этот ответ неверен
$domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
Это вернет google.com для http://google.com/ ... и http://www.google.com/ ...
потому что он все равно вернет сервер, если вы введете "server.google.com" или "www3.google.com" ...
Не все субдомены являются www, crawl-66-249-66-1.googlebot.com, myblog.blogspot.com - вот несколько примеров.
Вот код, который я сделал, что 100% находит только доменное имя, так как для учета требуются под-TLD Mozilla. Единственное, что вам нужно проверить, это то, как вы делаете кеш этого файла, чтобы вы не запрашивали Mozilla каждый раз.
По какой-то странной причине доменов, таких как co.uk, нет в списке, поэтому вам придется немного взломать и добавить их вручную. Это не самое чистое решение, но я надеюсь, что это кому-то поможет.
//=====================================================
static function domain($url)
{
$slds = "";
$url = strtolower($url);
$address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
if (!$subtlds = @kohana::cache('subtlds', null, 60))
{
$content = file($address);
foreach($content as $num => $line)
{
$line = trim($line);
if ($line == '') continue;
if (@substr($line[0], 0, 2) == '/') continue;
$line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
if ($line == '') continue; //$line = '.'.$line;
if (@$line[0] == '.') $line = substr($line, 1);
if (!strstr($line, '.')) continue;
$subtlds[] = $line;
//echo "{$num}: '{$line}'"; echo "<br>";
}
$subtlds = array_merge(Array(
'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk',
'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au',
),$subtlds);
$subtlds = array_unique($subtlds);
//echo var_dump($subtlds);
@kohana::cache('subtlds', $subtlds);
}
preg_match('/^(http:[/]{2,})?([^/]+)/i', $url, $matches);
//preg_match("/^(http://|https://|)[a-zA-Z-]([^/]+)/i", $url, $matches);
$host = @$matches[2];
//echo var_dump($matches);
preg_match("/[^\./]+\.[^\./]+$/", $host, $matches);
foreach($subtlds as $sub)
{
if (preg_match("/{$sub}$/", $host, $xyz))
preg_match("/[^\./]+\.[^\./]+\.[^\./]+$/", $host, $matches);
}
return @$matches[0];
}
Причина, по которой домен co.uk не был в списке, заключалась в том, что это был список TLD, а не доменов. CcTLD сильно изменился с тех пор, как был написан этот ответ. Примечательно: «Новые регистрации непосредственно под .uk были приняты Nominet с 10 июня 2014 г., 08:00 BST, однако существует период резервирования для существующих клиентов, у которых уже есть .co.uk, .org.uk, .me.uk. , .net.uk, .ltd.uk или .plc.uk, чтобы заявить права на соответствующий домен .uk, который работает до 07:59 BST на 10 июн 2019 ". (Источник)
Код, который должен был работать на 100%, похоже, не помог мне, я немного исправил пример, но нашел код, который не помогал, и проблемы с ним. поэтому я изменил его на несколько функций (чтобы постоянно запрашивать список из Mozilla и удалить систему кеширования). Это было протестировано на наборе из 1000 URL-адресов и, похоже, сработало.
function domain($url)
{
global $subtlds;
$slds = "";
$url = strtolower($url);
$host = parse_url('http://'.$url,PHP_URL_HOST);
preg_match("/[^\./]+\.[^\./]+$/", $host, $matches);
foreach($subtlds as $sub){
if (preg_match('/\.'.preg_quote($sub).'$/', $host, $xyz)){
preg_match("/[^\./]+\.[^\./]+\.[^\./]+$/", $host, $matches);
}
}
return @$matches[0];
}
function get_tlds() {
$address = 'http://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1';
$content = file($address);
foreach ($content as $num => $line) {
$line = trim($line);
if ($line == '') continue;
if (@substr($line[0], 0, 2) == '/') continue;
$line = @preg_replace("/[^a-zA-Z0-9\.]/", '', $line);
if ($line == '') continue; //$line = '.'.$line;
if (@$line[0] == '.') $line = substr($line, 1);
if (!strstr($line, '.')) continue;
$subtlds[] = $line;
//echo "{$num}: '{$line}'"; echo "<br>";
}
$subtlds = array_merge(array(
'co.uk', 'me.uk', 'net.uk', 'org.uk', 'sch.uk', 'ac.uk',
'gov.uk', 'nhs.uk', 'police.uk', 'mod.uk', 'asn.au', 'com.au',
'net.au', 'id.au', 'org.au', 'edu.au', 'gov.au', 'csiro.au'
), $subtlds);
$subtlds = array_unique($subtlds);
return $subtlds;
}
Тогда используйте это как
$subtlds = get_tlds();
echo domain('www.example.com') //outputs: example.com
echo domain('www.example.uk.com') //outputs: example.uk.com
echo domain('www.example.fr') //outputs: example.fr
Я знаю, что мне следовало превратить это в урок, но не было времени.
parse_url у меня не работал. Это только вернуло путь. Переход к основам с использованием php5.3 +:
$url = str_replace('http://', '', strtolower( $s->website));
if (strpos($url, '/')) $url = strstr($url, '/', true);
Как правило, это будет работать очень хорошо, если входной URL-адрес не является сплошным мусором. Удаляет поддомен.
$host = parse_url( $Row->url, PHP_URL_HOST );
$parts = explode( '.', $host );
$parts = array_reverse( $parts );
$domain = $parts[1].'.'.$parts[0];
Пример
Вход: http://www2.website.com:8080/some/file/structure?some=parameters
Выход: website.com
Вы можете передать PHP_URL_HOST в функцию parse_url в качестве второго параметра
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$host = parse_url($url, PHP_URL_HOST);
print $host; // prints 'google.com'
По сути, это то же самое, что и ответ выше, однако вопрос требует домен, который не обязательно совпадает с хозяин.
см. комментарий выше о схеме: по какой-то нечетной причине parse_url возвращает хост (например, example.com) в качестве пути, если во входном URL-адресе нет схемы. Итак, я написал быструю функцию для получения настоящего хоста:
Я отредактировал для вас:
function getHost($Address) {
$parseUrl = parse_url(trim($Address));
$host = trim($parseUrl['host'] ? $parseUrl['host'] : array_shift(explode('/', $parseUrl['path'], 2)));
$parts = explode( '.', $host );
$num_parts = count($parts);
if ($parts[0] == "www") {
for ($i=1; $i < $num_parts; $i++) {
$h .= $parts[$i] . '.';
}
}else {
for ($i=0; $i < $num_parts; $i++) {
$h .= $parts[$i] . '.';
}
}
return substr($h,0,-1);
}
URL всех типов (www.domain.ltd, sub1.subn.domain.ltd приведет к: domain.ltd.
$domain = parse_url($url, PHP_URL_HOST);
echo implode('.', array_slice(explode('.', $domain), -2, 2))
не работает для google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html
function get_domain($url = SITE_URL)
{
preg_match("/[a-z0-9\-]{1,63}\.[a-z\.]{2,6}$/", parse_url($url, PHP_URL_HOST), $_domain_tld);
return $_domain_tld[0];
}
get_domain('http://www.cdl.gr'); //cdl.gr
get_domain('http://cdl.gr'); //cdl.gr
get_domain('http://www2.cdl.gr'); //cdl.gr
У меня тоже ничего не работает: example.com // Неправильно: пустая строка example.com // Правильно: example.com www.example.com // Неправильно: пустая строка example.com/xyz // Правильно: example.com
Это отличный ответ, и он заслуживает большего уважения. Просто добавьте эту строку в качестве первой в функции, и она также решит проблемы MangeshSathe и jenlampton: if ((substr ($ url, 0, strlen ('http: //')) <> 'http: //' ) && (substr ($ url, 0, strlen ('https: //')) <> 'https: //')) $ url = 'http: //'.$url;
Просто используйте, как показано ниже ...
<?php
echo $_SERVER['SERVER_NAME'];
?>
Предполагается, что сервер - это URL-адрес, с которого вы хотите получить домен. Это не так.
Объединение ответов worldofjr и Аликс Аксель в одну небольшую функцию, которая будет обрабатывать большинство вариантов использования:
function get_url_hostname($url) {
$parse = parse_url($url);
return str_ireplace('www.', '', $parse['host']);
}
get_url_hostname('http://www.google.com/example/path/file.html'); // google.com
это ограниченное решение
Если вы хотите извлечь хост из строки http://google.com/dhasjkdas/sadsdds/sdda/sdads.html, использование parse_url () является для вас приемлемым решением.
Но если вы хотите извлечь домен или его части, вам понадобится пакет, использующий Список общедоступных суффиксов. Да, вы можете использовать строковые функции arround parse_url (), но иногда это дает неверные результаты.
Я рекомендую TLDExtract для разбора домена, вот пример кода, который показывает разницу:
$extract = new LayerShifter\TLDExtract\Extract();
# For 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
parse_url($url, PHP_URL_HOST); // will return google.com
$result = $extract->parse($url);
$result->getFullHost(); // will return 'google.com'
$result->getRegistrableDomain(); // will return 'google.com'
$result->getSuffix(); // will return 'com'
# For 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html'
$url = 'http://search.google.com/dhasjkdas/sadsdds/sdda/sdads.html';
parse_url($url, PHP_URL_HOST); // will return 'search.google.com'
$result = $extract->parse($url);
$result->getFullHost(); // will return 'search.google.com'
$result->getRegistrableDomain(); // will return 'google.com'
Большое спасибо за это предложение. Я ненавижу добавлять еще одну библиотеку для того, что появляется было простой задачей, но потом я увидел эту цитату в их readme, примененную ко мне: «Все ошибаются. Разделение на '.' и использование последних двух элементов имеет большое значение, только если вы думаете о простых, например, доменах .com. Подумайте, например, о разборе forum.bbc.co.uk: наивный метод разделения, приведенный выше, даст вам «co» в качестве домена и «uk» в качестве TLD вместо "bbc" и "co.uk" соответственно ".
Результат разбиения точек на наши любимые домены .co.uk - это не то, что мы хотим, но на самом деле это правильный результат: co - это второй уровень, а uk - верхний уровень. Веб-мастера часто этого не осознают.
Я добавляю этот ответ поздно, так как это ответ, который чаще всего всплывает в Google ...
Вы можете использовать PHP для ...
$url = "www.google.co.uk";
$host = parse_url($url, PHP_URL_HOST);
// $host == "www.google.co.uk"
чтобы захватить хозяин, но не частный домен, на который ссылается хост. (Пример www.google.co.uk - это хост, а google.co.uk - частный домен)
Чтобы получить частный домен, вам необходимо знать список общедоступных суффиксов, для которых может регистрирует частный домен. Этот список курирует Mozilla по адресу https://publicsuffix.org/.
Приведенный ниже код работает, когда уже создан массив общедоступных суффиксов. Просто позвоните
$domain = get_private_domain("www.google.co.uk");
с оставшимся кодом ...
// find some way to parse the above list of public suffix
// then add them to a PHP array
$suffix = [... all valid public suffix ...];
function get_public_suffix($host) {
$parts = split("\.", $host);
while (count($parts) > 0) {
if (is_public_suffix(join(".", $parts)))
return join(".", $parts);
array_shift($parts);
}
return false;
}
function is_public_suffix($host) {
global $suffix;
return isset($suffix[$host]);
}
function get_private_domain($host) {
$public = get_public_suffix($host);
$public_parts = split("\.", $public);
$all_parts = split("\.", $host);
$private = [];
for ($x = 0; $x < count($public_parts); ++$x)
$private[] = array_pop($all_parts);
if (count($all_parts) > 0)
$private[] = array_pop($all_parts);
return join(".", array_reverse($private));
}
Согласно моему тестированию, parse_url нуждается в правильно сформированном URL-адресе. Если вы просто укажете «www.someDomain.com/path», он вернет null. Таким образом, он ожидает наличия протоколов (например, http или https).
Я обнаружил, что решение @ philfreo (указанное на php.net) довольно хорошо для получения хорошего результата, но в некоторых случаях оно показывает сообщение php «уведомление» и «строгие стандарты». Вот исправленная версия этого кода.
function getHost($url) {
$parseUrl = parse_url(trim($url));
if (isset($parseUrl['host']))
{
$host = $parseUrl['host'];
}
else
{
$path = explode('/', $parseUrl['path']);
$host = $path[0];
}
return trim($host);
}
echo getHost("http://example.com/anything.html"); // example.com
echo getHost("http://www.example.net/directory/post.php"); // www.example.net
echo getHost("https://example.co.uk"); // example.co.uk
echo getHost("www.example.net"); // example.net
echo getHost("subdomain.example.net/anything"); // subdomain.example.net
echo getHost("example.net"); // example.net
Пожалуйста, подумайте о замене принятого решения следующим:
parse_url () всегда будет включать любые поддомены, поэтому эта функция не очень хорошо разбирает доменные имена. Вот некоторые примеры:
$url = 'http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'www.google.com'
echo parse_url('https://subdomain.example.com/foo/bar', PHP_URL_HOST);
// Output: subdomain.example.com
echo parse_url('https://subdomain.example.co.uk/foo/bar', PHP_URL_HOST);
// Output: subdomain.example.co.uk
Вместо этого вы можете рассмотреть это прагматичное решение. Он будет охватывать многие, но не все доменные имена - например, домены более низкого уровня, такие как 'sos.state.oh.us', не покрываются.
function getDomain($url) {
$host = parse_url($url, PHP_URL_HOST);
if (filter_var($host,FILTER_VALIDATE_IP)) {
// IP address returned as domain
return $host; //* or replace with null if you don't want an IP back
}
$domain_array = explode(".", str_replace('www.', '', $host));
$count = count($domain_array);
if ( $count>=3 && strlen($domain_array[$count-2])==2 ) {
// SLD (example.co.uk)
return implode('.', array_splice($domain_array, $count-3,3));
} else if ( $count>=2 ) {
// TLD (example.com)
return implode('.', array_splice($domain_array, $count-2,2));
}
}
// Your domains
echo getDomain('http://google.com/dhasjkdas/sadsdds/sdda/sdads.html'); // google.com
echo getDomain('http://www.google.com/dhasjkdas/sadsdds/sdda/sdads.html'); // google.com
echo getDomain('http://google.co.uk/dhasjkdas/sadsdds/sdda/sdads.html'); // google.co.uk
// TLD
echo getDomain('https://shop.example.com'); // example.com
echo getDomain('https://foo.bar.example.com'); // example.com
echo getDomain('https://www.example.com'); // example.com
echo getDomain('https://example.com'); // example.com
// SLD
echo getDomain('https://more.news.bbc.co.uk'); // bbc.co.uk
echo getDomain('https://www.bbc.co.uk'); // bbc.co.uk
echo getDomain('https://bbc.co.uk'); // bbc.co.uk
// IP
echo getDomain('https://1.2.3.45'); // 1.2.3.45
Наконец, Парсер домена PHP Джереми Кендалла позволяет вам анализировать доменное имя из URL-адреса. Парсер имени хоста URI лиги также выполнит эту работу.
Привет, это хорошо, но не работает с IP-адресами. Тем не менее, отличная работа.
function getTrimmedUrl($link)
{
$str = str_replace(["www.","https://","http://"],[''],$link);
$link = explode("/",$str);
return strtolower($link[0]);
}
см. этот: stackoverflow.com/questions/288810/get-the-subdomain-from-a- url /…