Есть ли функция в PHP для получения имени субдомена?
В следующем примере я хотел бы получить "en" часть URL-адреса:
en.example.com
Есть ли функция в PHP для получения имени субдомена?
В следующем примере я хотел бы получить "en" часть URL-адреса:
en.example.com
Здесь однострочное решение:
array_shift((explode('.', $_SERVER['HTTP_HOST'])));
Или используя ваш пример:
array_shift((explode('.', 'en.example.com')));
EDIT: Исправлено: "только переменные должны передаваться по ссылке" путем добавления двойной скобки.
EDIT 2: Начиная с PHP 5.4 вы можете просто:
explode('.', 'en.example.com')[0];
Использует функцию parse_url.
$url = 'http://en.example.com';
$parsedUrl = parse_url($url);
$host = explode('.', $parsedUrl['host']);
$subdomain = $host[0];
echo $subdomain;
Для нескольких поддоменов
$url = 'http://usa.en.example.com';
$parsedUrl = parse_url($url);
$host = explode('.', $parsedUrl['host']);
$subdomains = array_slice($host, 0, count($host) - 2 );
print_r($subdomains);
Вы можете сделать это, сначала получив доменное имя (например, sub.example.com = > example.co.uk), а затем используйте strstr для получения поддоменов.
$testArray = array(
'sub1.sub2.example.co.uk',
'sub1.example.com',
'example.com',
'sub1.sub2.sub3.example.co.uk',
'sub1.sub2.sub3.example.com',
'sub1.sub2.example.com'
);
foreach($testArray as $k => $v)
{
echo $k." => ".extract_subdomains($v)."\n";
}
function extract_domain($domain)
{
if(preg_match("/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i", $domain, $matches))
{
return $matches['domain'];
} else {
return $domain;
}
}
function extract_subdomains($domain)
{
$subdomains = $domain;
$domain = extract_domain($subdomains);
$subdomains = rtrim(strstr($subdomains, $domain, true), '.');
return $subdomains;
}
Выходы:
0 => sub1.sub2
1 => sub1
2 =>
3 => sub1.sub2.sub3
4 => sub1.sub2.sub3
5 => sub1.sub2
<?php
$url = 'http://user:[email protected]/path?argument=value#anchor';
$array=parse_url($url);
$array['host']=explode('.', $array['host']);
echo $array['host'][0]; // returns 'en'
?>
Поскольку единственным надежным источником суффиксов домена являются регистраторы доменов, вы не можете найти субдомен без их ведома. Список со всеми суффиксами домена представлен в https://publicsuffix.org. Этот сайт также ссылается на библиотеку PHP: https://github.com/jeremykendall/php-domain-parser.
Ниже приведен пример. Я также добавил образец для en.test.co.uk, который является доменом с несколькими суффиксами (co.uk).
<?php
require_once 'vendor/autoload.php';
$pslManager = new Pdp\PublicSuffixListManager();
$parser = new Pdp\Parser($pslManager->getList());
$host = 'http://en.example.com';
$url = $parser->parseUrl($host);
echo $url->host->subdomain;
$host = 'http://en.test.co.uk';
$url = $parser->parseUrl($host);
echo $url->host->subdomain;
Самое простое и быстрое решение.
$sSubDomain = str_replace('.example.com','',$_SERVER['HTTP_HOST']);
$REFERRER = $_SERVER['HTTP_REFERER']; // Or other method to get a URL for decomposition
$domain = substr($REFERRER, strpos($REFERRER, '://')+3);
$domain = substr($domain, 0, strpos($domain, '/'));
// This line will return 'en' of 'en.example.com'
$subdomain = substr($domain, 0, strpos($domain, '.'));
preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $url, $match);
Просто прочитайте $match [1]
Он отлично работает с этим списком URL
$url = array(
'http://www.domain.com', // www
'http://domain.com', // --nothing--
'https://domain.com', // --nothing--
'www.domain.com', // www
'domain.com', // --nothing--
'www.domain.com/some/path', // www
'http://sub.domain.com/domain.com', // sub
'опубликованному.значения.ua', // опубликованному ;)
'значения.ua', // --nothing--
'http://sub-domain.domain.net/domain.net', // sub-domain
'sub-domain.third-Level_DomaIN.domain.uk.co/domain.net' // sub-domain
);
foreach ($url as $u) {
preg_match('/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/i', $u, $match);
var_dump($match);
}
Я нашел лучшее и короткое решение
array_shift(explode(".",$_SERVER['HTTP_HOST']));
Для тех, кто получает "Ошибка: строгие стандарты: только переменные должны передаваться по ссылке". Используйте следующее:
$env = (explode(".",$_SERVER['HTTP_HOST']));
$env = array_shift($env);
$domain = 'sub.dev.example.com';
$tmp = explode('.', $domain); // split into parts
$subdomain = current($tmp);
print($subdomain); // prints "sub"
Как видно из предыдущего вопроса: Как получить первый субдомен с PHP?
На самом деле не существует 100% -ного динамического решения - я просто пытался понять это, а также из-за разных расширений домена (DTL) эта задача была бы действительно сложной, не анализируя все эти расширения и не проверяя их каждый раз:
.com vs .co.uk vs org.uk
Самым надежным вариантом является определение константы (или записи базы данных и т.д.), которая сохраняет фактическое имя домена и удаляет его из $_SERVER['SERVER_NAME']
с помощью substr()
defined("DOMAIN")
|| define("DOMAIN", 'mymaindomain.co.uk');
function getSubDomain() {
if (empty($_SERVER['SERVER_NAME'])) {
return null;
}
$subDomain = substr($_SERVER['SERVER_NAME'], 0, -(strlen(DOMAIN)));
if (empty($subDomain)) {
return null;
}
return rtrim($subDomain, '.');
}
Теперь, если вы используете эту функцию под http://test.mymaindomain.co.uk
, она даст вам test
или если у вас есть несколько уровней поддоменов http://another.test.mymaindomain.co.uk
, вы получите another.test
- если, конечно, вы не обновите DOMAIN
.
Надеюсь, это поможет.
Просто
reset(explode(".", $_SERVER['HTTP_HOST']))
это мое решение, оно работает с наиболее распространенными доменами, вы можете подобрать массив расширений по мере необходимости:
$SubDomain = explode ('.', explode ('| ext |', str_replace (array ('. com', '.net', '.org'), '| ext |', $_ SERVER [' HTTP_HOST '])) [0]);
PHP 7.0: Использование функции разнесения и создание списка всех результатов.
list($subdomain,$host) = explode('.', $_SERVER["SERVER_NAME"]);
Пример: sub.domain.com
echo $subdomain;
Результат: саб
echo $host;
Результат: домен
// For www.abc.en.example.com
$host_Array = explode(".",$_SERVER['HTTP_HOST']); // Get HOST as array www, abc, en, example, com
array_pop($host_Array); array_pop($host_Array); // Remove com and exmaple
array_shift($host_Array); // Remove www (Optional)
echo implode($host_Array, "."); // Combine array abc.en
Я знаю, что я очень опаздываю в игру, но здесь идет.
То, что я сделал, это взять серверную переменную HTTP_HOST ($_SERVER['HTTP_HOST']
) и количество букв в домене (так что для example.com
это будет 11).
Затем я использовал функцию substr
для получения поддомена. Я сделал
$numberOfLettersInSubdomain = strlen($_SERVER['HTTP_HOST'])-12
$subdomain = substr($_SERVER['HTTP_HOST'], $numberOfLettersInSubdomain);
Я вырезаю подстроку на 12 вместо 11, потому что подстроки начинаются с 1 для второго параметра. Итак, теперь, если вы введете test.example.com, значение $subdomain
будет test
.
Это лучше, чем использование explode
, потому что если поддомен имеет в нем .
, это не отключит его.
если вы используете drupal 7
это поможет вам:
global $base_path;
global $base_root;
$fulldomain = parse_url($base_root);
$splitdomain = explode(".", $fulldomain['host']);
$subdomain = $splitdomain[0];
$host = $_SERVER['HTTP_HOST'];
preg_match("/[^\.\/]+\.[^\.\/]+$/", $host, $matches);
$domain = $matches[0];
$url = explode($domain, $host);
$subdomain = str_replace('.', '', $url[0]);
echo 'subdomain: '.$subdomain.'<br />';
echo 'domain: '.$domain.'<br />';
Из PHP 5.3 вы можете использовать strstr() с параметром true
echo strstr($_SERVER["HTTP_HOST"], '.', true); //prints en
function get_subdomain($url=""){
if($url==""){
$url = $_SERVER['HTTP_HOST'];
}
$parsedUrl = parse_url($url);
$host = explode('.', $parsedUrl['path']);
$subdomains = array_slice($host, 0, count($host) - 2 );
return implode(".", $subdomains);
}
Попробуйте это...
$domain = 'en.example.com';
$tmp = explode('.', $domain);
$subdomain = current($tmp);
echo($subdomain); // echo "en"
Использование регулярных выражений, строковых функций, parse_url() или их комбинаций это не реальное решение. Просто проверьте любые предлагаемые решения с доменом test.en.example.co.uk
, никакого правильного результата не будет.
Правильное решение - это пакет использования, который анализирует домен с Public Suffix List. Я рекомендую TLDExtract, вот пример кода:
$extract = new LayerShifter\TLDExtract\Extract();
$result = $extract->parse('test.en.example.co.uk');
$result->getSubdomain(); // will return (string) 'test.en'
$result->getSubdomains(); // will return (array) ['test', 'en']
$result->getHostname(); // will return (string) 'example'
$result->getSuffix(); // will return (string) 'co.uk'
вы также можете использовать это
echo substr($_SERVER['HTTP_HOST'], 0, strrpos($_SERVER['HTTP_HOST'], '.', -5));
Я делаю что-то вроде этого
$url = https://en.example.com
$splitedBySlash = explode('/', $url);
$splitedByDot = explode('.', $splitedBySlash[2]);
$subdomain = $splitedByDot[0];
Мы используем эту функцию для обработки нескольких поддоменов, а несколько tld также обрабатывают ip и localhost
function analyse_host($_host)
{
$my_host = explode('.', $_host);
$my_result = ['subdomain' => null, 'root' => null, 'tld' => null];
// if host is ip, only set as root
if(filter_var($_host, FILTER_VALIDATE_IP))
{
// something like 127.0.0.5
$my_result['root'] = $_host;
}
elseif(count($my_host) === 1)
{
// something like localhost
$my_result['root'] = $_host;
}
elseif(count($my_host) === 2)
{
// like jibres.com
$my_result['root'] = $my_host[0];
$my_result['tld'] = $my_host[1];
}
elseif(count($my_host) >= 3)
{
// some conditons like
// ermile.ac.ir
// ermile.jibres.com
// ermile.jibres.ac.ir
// a.ermile.jibres.ac.ir
// get last one as tld
$my_result['tld'] = end($my_host);
array_pop($my_host);
// check last one after remove is probably tld or not
$known_tld = ['com', 'org', 'net', 'gov', 'co', 'ac', 'id', 'sch', 'biz'];
$probably_tld = end($my_host);
if(in_array($probably_tld, $known_tld))
{
$my_result['tld'] = $probably_tld. '.'. $my_result['tld'];
array_pop($my_host);
}
$my_result['root'] = end($my_host);
array_pop($my_host);
// all remain is subdomain
if(count($my_host) > 0)
{
$my_result['subdomain'] = implode('.', $my_host);
}
}
return $my_result;
}
Предположим, текущий URL = sub.example.com
$host = array_reverse(explode('.', $_SERVER['SERVER_NAME'])); if (count($host) >= 3){ echo "Main domain is = ".$host[1].".".$host[0]." & subdomain is = ".$host[2]; // Main domain is = example.com & subdomain is = sub } else { echo "Main domain is = ".$host[1].".".$host[0]." & subdomain not found"; // "Main domain is = example.com & subdomain not found"; }
Если вы хотите только то, что приходит до первого периода:
list($sub) = explode('.', 'en.example.com', 2);