Отримайте поточний домен


140

У мене на сервері є мій сайт

http://www.myserver.uk.com

Для цього у мене є два домени,

http://one.com

і

http://two.com

Я хотів би отримати з поточним доменом PHP, але якщо я використовую, $_SERVER['HTTP_HOST']це покажіть мені

myserver.uk.com

замість:

one.com or two.com

Як я можу отримати домен, а не ім’я сервера?

У мене PHP версії 5.2.


Ви можете отримати лише первинний URl. Який з них є первинним?
Код шпигуна

2
Як саме запити ваших двох доменів переадресовують на ваш сервер?
xiaofeng.li

1
@infgeoax, мабуть, кадр ...
CodeCaster

первинним є myserver.uk.com. тож як я можу отримати поточне доменне ім’я? Якщо я відкрию сайт з адресою one.com, я хотів би отримати one.com замість myserver.uk.com
Tony Evyght

@TonyEvyght, що в цьому полягає в infgeoax, і я намагаюся зробити це, ви повинні отримати ім'я хоста, з яким ви з'єднуєтесь $_SERVER['HTTP_HOST']. Якщо сайти one.comі two.com"переспрямовуються" за допомогою (i) кадру, сама сторінка все ще надходить з myserver.uk.com, тому ви не отримаєте реальний домен. Для чого джерело HTML one.com?
CodeCaster

Відповіді:


175

Спробуйте скористатися цим: $_SERVER['SERVER_NAME']

Або розібратися

$_SERVER['REQUEST_URI']

apache_request_headers ()


23
-1: Один лише з цією відповіддю, я не знаю точно, які різні пропозиції я дивлюся. Звичайно, це дає мені можливість продовжувати дивитись, але саме по собі це насправді не є гарною відповіддю ...
Джаспер

4
просто print_r (apache_request_headers ()) і ти все зрозумієш :)
onehalf

2
@SarahLewis HTTP_X_ORIGINAL_HOSTможе бути модифікований користувачем, і йому не можна довіряти. Це може не завжди бути проблемою, але слід пам’ятати про щось.
wp-overwatch.com

64

Найкраще було б використовувати

echo $_SERVER['HTTP_HOST'];

І це можна використовувати так:

if (strpos($_SERVER['HTTP_HOST'], 'banana.com') !== false) {
    echo "Yes this is indeed the banana.com domain";
}

Цей код нижче - це хороший спосіб побачити всі змінні в $ _SERVER в структурованому HTML-виведенні з виділеними ключовими словами, які зупиняються безпосередньо після виконання. Оскільки я інколи забуваю, яким саме користуватися - думаю, це може бути чудовим.

<?php
    // Change banana.com to the domain you were looking for..
    $wordToHighlight = "banana.com";
    $serverVarHighlighted = str_replace( $wordToHighlight, '<span style=\'background-color:#883399; color: #FFFFFF;\'>'. $wordToHighlight .'</span>',  $_SERVER );
    echo "<pre>";
    print_r($serverVarHighlighted);
    echo "</pre>";
    exit();
?>

39

Використання $_SERVER['HTTP_HOST']отримує мені (субдомен.) Maindomain.extension. Мені це здається найпростішим рішенням.

Якщо ви насправді 'перенаправляєте' через iFrame, ви можете додати параметр GET, який констатує домен.

<iframe src="myserver.uk.com?domain=one.com"/>

Тоді ви можете встановити змінну сеансу, яка зберігатиме ці дані у всій програмі.


1
головне важливо, щоб він включав номер порту, так що мені не потрібно згортати його. phpinfo, запропонований bsdnoobz, допомагає мені знайти правильне рішення.

30

Єдиний безпечний спосіб зробити це

Усі інші відповіді на цій сторінці мають наслідки для безпеки, про які вам потрібно знати.

Єдиний гарантований безпечний метод отримання поточного домену це до 𝓼𝓽𝓸𝓻𝓮 𝓲𝓽 𝓲𝓷 𝓪 𝓼𝓮𝓬𝓾𝓻𝓮 𝓵𝓸𝓬𝓪𝓽𝓲𝓸𝓷 𝔂𝓸𝓾𝓻𝓼𝓮𝓵𝓯.

Більшість фреймворків дбають про збереження домену для вас, тому вам захочеться ознайомитися з документацією для конкретного фреймворку. Якщо ви не використовуєте фреймворк, подумайте про збереження домену в одному з наступних місць:

+ ------------------------------------------------- --- + ----------------------------------- +
 | Безпечні методи зберігання домену | Використовується |
+ ------------------------------------------------- --- + ----------------------------------- +
 | Конфігураційний файл | Joomla, Drupal / Symfony |
 | База даних | WordPress |
 | Екологічна змінна | Laravel |
 | Реєстр послуг | Kubernetes DNS |
+ ------------------------------------------------- --- + ----------------------------------- +


Ви можете використовувати наступне ... але вони небезпечні

Хакери можуть змусити ці змінні виводити будь-який домен, який вони хочуть. Це може призвести до отруєння кешем та ледь помітних фішинг-атак.

$_SERVER['HTTP_HOST']

Це отримує домен із заголовків запитів, відкритих для маніпуляцій хакерами . Те саме:

$_SERVER['SERVER_NAME']

Це може бути покращено, якщо параметр Apache usecanonicalname вимкнено; в такому випадку $_SERVER['SERVER_NAME']більше не буде дозволено заповнюватись довільними значеннями і буде захищено. Це, однак, не за замовчуванням і не так часто в налаштуваннях.


У популярних системах

Нижче описано, як можна отримати поточний домен у наступних рамках / системах:

WordPress

$urlparts = parse_url(home_url());
$domain = $urlparts['host'];

Якщо ви створюєте URL-адресу в WordPress, просто використовуйте home_url або site_url або будь-яку з інших функцій URL-адреси .

Ларавель

request()->getHost()

request()->getHostФункція успадкована від Symfony, і було безпечним , так як 2013 CVE-2013-4752 була виправлена.

Друпал

Інсталятор ще не піклується про безпеку ( випуск №2404259 ). Але в Drupal 8 є документація, яку ви можете дотримуватися у налаштуваннях довіреного хоста, щоб захистити установку Drupal, після чого можна використовувати наступне:

\Drupal::request()->getHost();

Інші рамки

Не соромтесь редагувати цю відповідь, щоб вказати, як отримати поточний домен у вашому улюбленому рамках. Роблячи це, будь ласка, додайте посилання на відповідний вихідний код або на будь-що інше, що допоможе мені переконатися, що рамка робить все безпечно.




Додаток

Приклади експлуатації:

  1. Отруєння кешем може статися, якщо ботнет постійно запитує сторінку, використовуючи неправильний заголовок хостів. Потім отриманий HTML буде містити посилання на веб-сайт зловмисників, де вони можуть фішизувати ваших користувачів. Спочатку зловмисні посилання будуть повернені лише до хакера, але якщо хакер зробить достатньо запитів, шкідлива версія сторінки опиниться у вашому кеші, де вона буде розповсюджуватися іншим користувачам.

  2. Фішинг може статися, якщо ви зберігаєте посилання в базі даних на основі заголовка хостів. Наприклад, скажімо, що ви зберігаєте абсолютну URL-адресу в профілях користувача на форумі. Використовуючи неправильний заголовок, хакер може змусити кожного, хто натиснув на посилання свого профілю, надіслати фішинг-сайт.

  3. Отруєння скидання пароля може статися, якщо хакер використовує зловмисний заголовок хостів під час заповнення форми для скидання пароля для іншого користувача. Потім користувач отримає електронний лист із посиланням для скидання пароля, що веде до фішинг-сайту.

  4. Ось ще кілька шкідливих прикладів

Додаткові застереження та примітки:

  • Коли вимкнено usecanonicalname , то $_SERVER['SERVER_NAME']заповнюється тим же заголовком$_SERVER['HTTP_HOST'] використовував би в будь-якому випадку (плюс порт). Це налаштування Apache за замовчуванням. Якщо ви або депп увімкнює це, тоді ви все в порядку - іш - але чи справді ви хочете розраховувати на окрему команду або на себе три роки в майбутньому, щоб зберегти те, що, здавалося б, є незначною конфігурацією -значення за замовчуванням? Незважаючи на те, що це робить все безпечним, я б застерігсь від того, щоб покладатися на цю установку.
  • Redhat, однак, вмикає usecanonical за замовчуванням [ джерело ].
  • Якщо serverAlias використовується у записі віртуальних хостів, а запитується псевдонім, $_SERVER['SERVER_NAME']він не поверне поточний домен, але поверне значення директиви serverName.
  • Якщо ім'я сервера неможливо вирішити, на його місці використовується команда ім'я хоста операційної системи [джерело] .
  • Якщо заголовок хоста буде опущено, сервер буде вести себе так, як ніби використання [джерело] було використане .
  • Нарешті, я просто спробував це використати на своєму локальному сервері і не зміг підробити заголовок хостів. Я не впевнений, чи було оновлення Apache, яке вирішило це, чи я просто робив щось не так. Незалежно від цього, цей заголовок все ще може бути використаний у середовищах, де не використовуються віртуальні хости.

Little Rant:

     Це запитання отримало сотні тисяч переглядів без жодної згадки про проблеми безпеки! Це повинно бути не так, але лише тому, що відповідь на переповнення стека популярна, це не означає, що вона є безпечною.




1
Ви можете згадати різницю між home_url та site_url. wordpress.stackexchange.com/a/50605/13
Volomike

1
+1 для користувачів Wordpress. Добре, якщо вам потрібно перевірити, чи встановлений він у subdir, але зауважте, що ключ parse_url: $urlparts['path']не встановлюється, якщо він встановлений у кореневому каталозі домену. Else $urlparts['path']повертає підкаталог.
Йонас Лундман

9

Спробуйте $_SERVER['SERVER_NAME'].

Поради: Створіть файл PHP, який викликає функцію, phpinfo()і перегляньте розділ «PHP-змінних». Є купа корисних змінних, про які ми ніколи не думаємо.


ви завжди можете спробувати print_r-ing $ _SERVER та шукати

3

Я знаю, що це може бути не повністю з цього питання, але, на моєму досвіді, я вважаю, що зберігання WWW-ності поточної URL-адреси у змінній корисно.

Редагувати: Окрім цього, будь ласка, дивіться мій коментар нижче, щоб побачити, що це.

Це важливо при визначенні того, чи слід відправляти дзвінки Ajax за допомогою "www" чи без:

$.ajax("url" : "www.site.com/script.php", ...

$.ajax("url" : "site.com/script.php", ...

Під час відправки дзвінка Ajax доменне ім'я повинно відповідати домену в адресному рядку браузера, інакше у консолі буде Uncaught SecurityError .

Тому я придумав таке рішення, щоб вирішити цю проблему:

<?php
    substr($_SERVER['SERVER_NAME'], 0, 3) == "www" ? $WWW = true : $WWW = false;

    if ($WWW) {
        /* We have www.example.com */
    } else {
        /* We have example.com */
    }
?>

Тоді, виходячи з того, чи є $ WWW істинним, чи неправдивим, виконайте належний виклик Ajax.

Я знаю, що це може здатися тривіальним, але це така поширена проблема, яку легко подолати.


ОП явно запитав домен, а не SERVER_NAME .
Себастьян Г. Марінеску

Щоправда, але в наші дні вам також потрібно хвилюватися з приводу www проблеми.
InfiniteStack

Чому? У JS ви могли заглянути window.location. У PHP ви отримали SERVER_NAME.
Себастьян Г. Марінеску

4
SERVER_NAME повертає "www.site.com", навіть коли в адресний рядок вводиться "site.com". Якщо ви використовуєте SERVER_NAME протягом усього коду, неминуче ви стикаєтеся з проблемою безпеки www / no-www, особливо якщо мова йде про здійснення дзвінків Ajax. Але щоб відповісти на ваше запитання, в розширеному програмуванні PHP іноді PHP потрібно динамічно генерувати код, який здійснює дзвінок HTTP на сервер. Якщо цільова URL-адреса містить "www" на сторінці, яка цього не робить, вона призведе до помилки безпеки.
InfiniteStack

Гаразд добре ... я читав про це, і ти маєш рацію. Тож ваша відповідь може бути актуальною для когось. Хороша робота :)
Себастьян Г. Марінеску

3

Усі використовують цю parse_urlфункцію, але іноді користувач може передавати аргумент в іншому форматі.

Щоб виправити це, я створив функцію. Заціни:

function fixDomainName($url='')
{
    $strToLower = strtolower(trim($url));
    $httpPregReplace = preg_replace('/^http:\/\//i', '', $strToLower);
    $httpsPregReplace = preg_replace('/^https:\/\//i', '', $httpPregReplace);
    $wwwPregReplace = preg_replace('/^www\./i', '', $httpsPregReplace);
    $explodeToArray = explode('/', $wwwPregReplace);
    $finalDomainName = trim($explodeToArray[0]);
    return $finalDomainName;
}

Просто введіть URL-адресу та отримайте домен.

Наприклад,

echo fixDomainName('https://stackoverflow.com');

поверне результат буде

stackoverflow.com

І в якійсь ситуації:

echo fixDomainName('stackoverflow.com/questions/id/slug');

І також повернеться stackoverflow.com.


1
$_SERVER['HTTP_HOST'] 

// отримати домен

$protocol=strpos(strtolower($_SERVER['SERVER_PROTOCOL']),'https') === FALSE ? 'http' : 'https';
$domainLink=$protocol.'://'.$_SERVER['HTTP_HOST'];

// домен з протоколом

$url=$protocol.'://'.$_SERVER['HTTP_HOST'].'?'.$_SERVER['QUERY_STRING'];

// протокол, домен, queryString total ** Оскільки $ _SERVER ['SERVER_NAME'] не є надійним для багатодоменного хостингу!


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.