PHP HTTP_HOST извлечение поддомена, учитывая, что поддомен должен быть подстановочным знаком и содержать более одного '.'
Я пытаюсь извлечь поддомен из значения HTTP_HOST. Однако я столкнулся с проблемой, когда, если в поддомене есть более одной точки, он не может соответствовать должным образом. Учитывая, что это сценарий для запуска в нескольких разных доменах, и он может иметь неограниченное количество точек, а tld может состоять из 1 или 2 частей (и любой длины) - существует ли практический способ правильного сопоставления субдомена, домена и тдл во всех ситуациях?
Так, например, возьмите следующие значения HTTP_HOST и то, что требуется сопоставить.
- www.buggedcom.co.uk
- Поддомен: www
- Домен: buggedcom.co.uk
- TLD: co.uk
- www.buggedcom.com
- Поддомен: www
- Домен: buggedcom.com
- TLD: com
- test.buggedcom.co.uk
- Субдомен: тест
- Домен: buggedcom.co.uk
- TLD: co.uk
- test.buggedcom.com
- Субдомен: тест
- Домен: buggedcom.com
- TLD: com
- multi.sub.test.buggedcom.co.uk
- Субдомен: multi.sub.test
- Домен: buggedcom.co.uk
- TLD: co.uk
- multi.sub.test.buggedcom.com
- Субдомен: multi.sub.test
- Домен: buggedcom.com
- TLD: com
Я предполагаю, что единственный способ сделать это - загрузить список tlds, что позволяет, возможно, не очень-то и делать, так как это в начале скрипта и действительно требует такой тяжелой работы.
Ниже приведен текущий код.
define('HOST', isset($_SERVER['HTTP_HOST']) === true ? $_SERVER['HTTP_HOST'] : (isset($_SERVER['SERVER_ADDR']) === true ? $_SERVER['SERVER_ADDR'] : $_SERVER['SERVER_NAME']));
$domain_parts = explode('.', HOST);
$domain_parts_count = count($domain_parts);
if($domain_parts_count > 1)
{
$sub_parts = array_splice($domain_parts, 0, $domain_parts_count-3);
define('SUBDOMAIN', implode('.', $sub_parts));
unset($sub_parts);
}
else
{
define('SUBDOMAIN', '');
}
define('DOMAIN', implode('.', $domain_parts));
var_dump($domain_parts, SUBDOMAIN, DOMAIN);exit;
Просто подумал, может ли mod_rewrite добавить поддомен как параметр get?
4 ответа
Прежде всего я бы взорвался (и использовал бы первый индекс в массиве) на слэше, просто чтобы быть уверенным, что строка заканчивается TLD.
Тогда я бы вырезал его с помощью preg_replace. Этот rexexp соответствует домену +tld независимо от типа tld. Однако остерегайтесь, это может привести к проблемам с 2- и 3-буквенными доменами. Но это должно дать толчок в правильном направлении....
[a-zA-Z0-9]+\.(([a-zA-Z]{2,6})|([a-zA-Z]{2,3}\.[a-zA-Z]{2,3}))$
Изменить: как указано:.museum также возможно, поэтому отредактировал первый шаблон в части TLD....
И, конечно, TLD, как.UK может вести себя иначе, чем co.uk тьфу.. это не так просто...
Я думаю, что решение этой проблемы лучше обрабатывается теми, кто пытается сделать то же самое... в комментариях к документации PHP для функции parse_url есть куча лучших функций разбора URL, которые могут работать лучше: http://www.php.net/manual/en/function.parse-url.php
Не быть придирчивым, но с технической точки зрения .co.uk
это домен второго уровня.
.uk
является "Домен верхнего уровня кода страны" в этом случае, и .co
предназначен для "коммерческого использования", определенного Соединенным Королевством.
Это может не ответить на ваш вопрос, хотя.
В Википедии есть довольно полный список доменов верхнего уровня, так как вы можете видеть, что они содержат только 1 "точку", за которой следует 1 "строка".
С помощью preg_match вы можете извлечь части поддоменов и tld за один раз, например:
function get_domain_parts($domain) {
$parts = array();
$pattern = "/(.*)\.buggedcom\.(.*)/";
if (preg_match($pattern, $domain, $parts) == 1) {
return array($parts[1], $parts[2]);
} else {
return FALSE;
}
}
$result = get_domain_parts("multi.sub.test.buggedcom.co.uk");
if ($result) {
echo($result[0] . " and " . $result[1]); // multi.sub.test and co.uk
}