Разбор домена с URL в PHP
Мне нужно создать функцию, которая анализирует домен из 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
.
Ответы
Ответ 1
Отъезд parse_url()
:
$url = 'http://google.com/dhasjkdas/sadsdds/sdda/sdads.html';
$parse = parse_url($url);
echo $parse['host']; // prints 'google.com'
parse_url
не обрабатывает действительно сильно искаженные URL-адреса очень хорошо, но это нормально, если вы обычно ожидаете приличных URL-адресов.
Ответ 2
$domain = str_ireplace('www.', '', parse_url($url, PHP_URL_HOST));
Это вернет google.com
для http://google.com/... и http://www.google.com/...
Ответ 3
От http://us3.php.net/manual/en/function.parse-url.php#93983
по какой-то нечетной причине, parse_url возвращает хост (пример example.com) как путь, когда схема не предусмотрена в входной адрес. Поэтому я быстро написал для получения реального хоста:
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
Ответ 4
Код, предназначенный для работы на 100%, по-видимому, не сократил его для меня, я немного исправил этот пример, но нашел код, который не помогал, и проблемы с ним. поэтому я изменил его на несколько функций (чтобы сохранить запрос на список из mozilla все время и удалить систему cahce). Это было протестировано против набора из 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: exmaple.com
echo domain('www.example.uk.com') //outputs: exmaple.uk.com
echo domain('www.example.fr') //outputs: exmaple.fr
Я знаю, что должен был превратить это в класс, но не успел.
Ответ 5
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
Ответ 6
Если вы хотите извлечь хост из строки http://google.com/dhasjkdas/sadsdds/sdda/sdads.html
, использование parse_url() является приемлемым решением для вас.
Но если вы хотите извлечь домен или его части, вам нужен пакет, который использует Public Suffix List. Да, вы можете использовать строковые функции arround parse_url(), но иногда это приводит к некорректным результатам.
Я рекомендую TLDExtract для разбора домена, вот пример кода, который показывает diff:
$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'
Ответ 7
Вот код, который я сделал, что 100% находит только имя домена, так как он требует учетных записей mozilla sub tlds. Единственное, что вам нужно проверить, это то, как вы делаете кеш этого файла, поэтому вы не запрашиваете 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];
}
Ответ 8
Вы можете передать 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'
Ответ 9
$domain = parse_url($url, PHP_URL_HOST);
echo implode('.', array_slice(explode('.', $domain), -2, 2))
Ответ 10
Я обнаружил, что решение @philfreo (ссылка на php.net) довольно хорошо, чтобы получить прекрасный результат, но в некоторых случаях он показывает сообщение "уведомление" и "Строгие стандарты". Здесь фиксированная версия этого кода.
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
Ответ 11
parse_url не работал у меня. Он только вернул путь. Переход на основы с помощью php5.3 +:
$url = str_replace('http://', '', strtolower( $s->website));
if (strpos($url, '/')) $url = strstr($url, '/', true);
Ответ 12
Я отредактировал для вас:
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.
Ответ 13
Отъезд parse_url()
Ответ 14
Здесь мой искатель основан на приведенных выше ответах.
- Выполнение класса (мне нравится Obj:)
- он использует
Curl
, поэтому мы можем использовать HTTP-аутентификацию
- это только ссылка на обход, которая относится к начальному домену URL.
- он печатает код ответа HTTP-заголовка (полезно для проверки проблем на сайте).
КЛАСС КЛАССА
class crawler
{
protected $_url;
protected $_depth;
protected $_host;
public function __construct($url, $depth = 5)
{
$this->_url = $url;
$this->_depth = $depth;
$parse = parse_url($url);
$this->_host = $parse['host'];
}
public function run()
{
$this->crawl_page($this->_url, $this->_depth = 5);
}
public function crawl_page($url, $depth = 5)
{
static $seen = array();
if (isset($seen[$url]) || $depth === 0) {
return;
}
$seen[$url] = true;
list($content, $httpcode) = $this->getContent($url);
$dom = new DOMDocument('1.0');
@$dom->loadHTML($content);
$this->processAnchors($dom, $url, $depth);
ob_end_flush();
echo "CODE::$httpcode, URL::$url <br>";
ob_start();
flush();
// echo "URL:", $url, PHP_EOL, "CONTENT:", PHP_EOL, $dom->saveHTML(), PHP_EOL, PHP_EOL;
}
public function processAnchors($dom, $url, $depth)
{
$anchors = $dom->getElementsByTagName('a');
foreach ($anchors as $element) {
$href = $element->getAttribute('href');
if (0 !== strpos($href, 'http')) {
$path = '/' . ltrim($href, '/');
if (extension_loaded('http')) {
$href = http_build_url($url, array('path' => $path));
} else {
$parts = parse_url($url);
$href = $parts['scheme'] . '://';
if (isset($parts['user']) && isset($parts['pass'])) {
$href .= $parts['user'] . ':' . $parts['pass'] . '@';
}
$href .= $parts['host'];
if (isset($parts['port'])) {
$href .= ':' . $parts['port'];
}
$href .= $path;
}
}
// Crawl only link that belongs to the start domain
if (strpos($href, $this->_host) !== false)
$this->crawl_page($href, $depth - 1);
}
}
public function getContent($url)
{
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
/* Get the HTML or whatever is linked in $url. */
$response = curl_exec($handle);
/* Check for 404 (file not found). */
$httpCode = curl_getinfo($handle, CURLINFO_HTTP_CODE);
if ($httpCode == 404) {
/* Handle 404 here. */
}
curl_close($handle);
return array($response, $httpCode);
}
}
// USAGE
$startURL = 'http://YOUR_START_ULR';
$depth = 2;
$crawler = new crawler($startURL, $depth);
$crawler->run();
Ответ 15
Я добавляю этот ответ позже, так как это ответ, который больше всего появляется в 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));
}
Ответ 16
Это будет работать очень хорошо, если входной 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
Ответ 17
Объединяя ответы worldofjr и Alix Axel в одну маленькую функцию, которая будет обрабатывать большинство случаев использования:
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
Ответ 18
Просто используйте, как показано ниже...
<?php
echo $_SERVER['SERVER_NAME'];
?>