Як ідентифікувати IP-адресу сервера в PHP


122

Як я можу визначити IP-адресу сервера в PHP?


2
Ви маєте на увазі IP-адресу запиту чи IP-адресу машини, на якій працює ваш додаток?
— wosis

Відповіді:


175

Як це для ip сервера:

$_SERVER['SERVER_ADDR'];

і це для порту

$_SERVER['SERVER_PORT'];

9
Ні. На деяких спільних хостах це повертається :: 1
— TheRealChx101,

3
Це може бути неправильним, залежно від того, який балансир завантаження використовується перед вашим веб-сервером. Ви хочете, щоб заголовок X-Forwarded-For також був у цьому сценарії: en.wikipedia.org/wiki/X-Forwarded-For
— Ligemer

31
Це НЕ адреса сервера! Це адреса, яку віддалений браузер називає сервером, який знаходиться під контролем віддаленого користувача. Використовуйте John Kнатомість відповідь
— Аріель,

Це не дає серверу ip. Чомусь це дає мій місцевий ip
— Thomas Williams

Він також не дає адреси сервера php-fpm, але призначений для пов'язаного веб-сервера (nginx, apache). Таким чином, це не буде правильним для специфікації хоста mysql (клієнт @ хост).
— науковець

105

Якщо ви використовуєте PHP версії 5.3 або новішої, ви можете зробити наступне:

$host= gethostname();
$ip = gethostbyname($host);

Це добре працює, якщо ви використовуєте автономний скрипт, а не працюєте через веб-сервер.


Ідеально, Що я шукаю. Спасибі Джон
— Френк

6
+1 Це єдине рішення, яке буде працювати з командним рядком.
— Адам Елсодані

2
@andreas Це не повинно. Місцеве ім’я хоста має бути у /etc/hostsфайлі і буде швидко, хоча це може бути просто так 127.0.0.1. Якщо все-таки доведеться викликати DNS, це буде повільно, як ви говорите.
— Аріель

+1, але лише питання .. Я спробую це з xampp на локальному сервері, і це повернути ip 192.168etc, але .. воно повинно бути 127.0.0.1 ні ??
— Андреа Борі

це працює для мене, але деякі машини показують доменне ім'я. як виправити це питання.
— Дхарані Дхаран

19

наприклад:

$_SERVER['SERVER_ADDR']

коли ви на IIS, спробуйте:

$_SERVER['LOCAL_ADDR']

2
$_SERVER['LOCAL_ADDR']доступний лише під IIS, коли PHP працює як модуль CGI.
— Руді Віссер

@rudi_visser також працює з fastcgi, але якщо ви підключитесь через lochost, ви отримаєте :: 1 назад. Якщо ви підключитесь через ім'я сервера або ip, ви отримаєте реальний ip назад.
— starbeamrainbowlabs

@starbeamrainbowlabs FastCGI - це CGI :) Я мав на увазі, на відміну від роботи в якості модуля ISAPI, це було написано до головного появи FastCGI як стабільної платформи.
— Руді Віссер

@starbeamrainbowlabs все, що виглядає так: 1 - це, мабуть, IP6-адреса
— Toby Allen

@TobyAllen Дякую :). Дивна річ у тому, що моя мережа не підтримує ipv6, але мій сервер (машина Windows 7) повідомляє про свій IP як: 1, адреса петлі ipv6.
— starbeamrainbowlabs

13

Я зайшов на цю сторінку, шукаючи спосіб отримати власну ip-адресу, а не одну з віддалених до мене машин.

Це не буде працювати для машини Windows.

Але якщо хтось шукає те, що я шукав:

#! /usr/bin/php
<?php
$my_current_ip=exec("ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1'");
echo $my_current_ip;

(Безсоромно адаптовано з Як я отримати первинний IP - адреса локальної машини на Linux і OS X? )


Це єдиний варіант, який насправді працює при запуску PHP-скриптів із оболонки. Питання: коли є кілька активних інтерфейсів, як це вирішує, яку адресу повернути? Я перевіряв активовані бездротові та бездротові Ethernet-з'єднання, а потім лише бездротові активні, і він обидва рази повертає wlan ip. Гарний сценарій, дякую!
— Райан Гріггс

Насправді не відомо, до кого повернутись. Він просто повертає останній інтернет-інтерфейс з виводу ifconfig, але ігноруючи 127.0.0.1. Якщо у вас є лише "звичайні" інтерфейси, то це робить досить непогану роботу. Це, мабуть, найбезпечніше, якщо ви вкажете потрібний інтерфейс "ifconfig wlan0 | ...". Цей скрипт аж ніяк не ідеальний, але він працює в простих налаштуваннях, і він демонструє, як це зробити в принципі, підлаштовуючись за потребою.
— Дом

1
ifconfig | grep 'inet addr' | вирізати -d ':' -f 2 | awk '{print $ 1}' | grep -vE '^ (192 \ .168 | 10 \. | 172 \ .1 [6789] \. | 172 \ .2 [0-9] \. | 172 \ .3 [01] \. | 127 \. ) "- це моя остання редакція цього. Він фільтрує всі локальні ips та надає лише зовнішнє середовище
— Dom

У мене є декілька мережевих інтерфейсів, так я і зробивifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | grep -e '192\.168\.1\.'
— Джонатан

10

Жоден з найбільш голосованих відповідей надійно не поверне публічну адресу сервера. Як правило, $_SERVER['SERVER_ADDR']це буде правильно, але якщо ви звертаєтесь до сервера через VPN, він, швидше за все, поверне внутрішню мережеву адресу, а не загальнодоступну адресу, і навіть якщо він не знаходиться в одній мережі, деякі конфігурації будуть просто порожніми або матимуть іншу інформацію значення.

Так само існують сценарії, коли $host= gethostname(); $ip = gethostbyname($host);не повертаються правильні значення, оскільки він покладається як на DNS (або внутрішньо налаштовані, або на зовнішні записи), і на назви сервера, щоб екстраполювати IP-адресу сервера. Обидва ці кроки є потенційно несправними. Наприклад, якщо ім'я хоста сервера відформатоване як доменне ім’я (тобто HOSTNAME=yahoo.com), то (принаймні, у моїй настройці php5.4 / Centos6) gethostbynameбуде пропущено прямо до пошуку адреси Yahoo.com, а не до локального сервера.

Крім того, через те, що gethostbynameзнову потрапляє на загальнодоступні записи DNS, тестуючий сервер із неопублікованими або невірними загальнодоступними записами DNS (наприклад, ви звертаєтесь до сервера за localhostIP-адресою або якщо ви перекриваєте загальнодоступний DNS за допомогою локального hostsфайлу), Я поверну або будь-яку IP-адресу (вона просто поверне ім’я хоста), або ще гірше, вона поверне неправильну адресу, вказану в загальнодоступних записах DNS, якщо така існує, або якщо є доменна карта для домену.

Залежно від ситуації, ви можете також спробувати третій підхід, зробивши щось подібне:

$external_ip = exec('curl http://ipecho.net/plain; echo');

У цього є свої недоліки (покладається на певний сторонній сайт, і там можуть бути мережеві налаштування, які маршрутизують вихідні з'єднання через інший хост або проксі), і gethostbynameвони можуть бути повільними. Я, чесно кажучи, не впевнений, який підхід буде правильним найчастіше, але урок, який слід сприйняти, полягає в тому, що конкретні сценарії / конфігурації призведуть до неправильних результатів для всіх цих підходів ... тому, якщо можливо, перевірте, що підхід ви є використання повертає очікувані значення.


9

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

<?php
      // create a new cURL resource
      $ch = curl_init ();

      // set URL and other appropriate options
      curl_setopt ($ch, CURLOPT_URL, "http://ipecho.net/plain");
      curl_setopt ($ch, CURLOPT_HEADER, 0);
      curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);

      // grab URL and pass it to the browser

      $ip = curl_exec ($ch);
      echo "The public ip for this server is: $ip";
      // close cURL resource, and free up system resources
      curl_close ($ch);
    ?>


5

Якщо ви використовуєте PHP в bash shell, ви можете використовувати:

$server_name=exec('hostname');

Тому що $_SERVER[] SERVER_ADDR, HTTP_HOSTі SERVER_NAMEне встановлені.


4

Попередні відповіді дають $ _SERVER ['SERVER_ADDR']. Це не працюватиме на деяких установках IIS. Якщо ви хочете, щоб це працювало на IIS, тоді використовуйте наступне:

$server_ip = gethostbyname($_SERVER['SERVER_NAME']);

2

Я виявив, що це працює для мене: GetHostByName ("");

Запуск XAMPP v1.7.1 на Windows 7 під керуванням веб-сервера Apache. На жаль, це просто дасть IP-адресу мого шлюзу.


2

Щойно я створив простий сценарій, який поверне $ _SERVER ['REMOTE_ADDR'] та $ _SERVER ['SERVER_ADDR'] в IIS, тому вам не доведеться змінювати кожну змінну. Просто вставте цей текст у свій PHP-файл, який міститься на кожній сторінці.

/** IIS IP Check **/
if(!$_SERVER['SERVER_ADDR']){ $_SERVER['SERVER_ADDR'] = $_SERVER['LOCAL_ADDR']; }
if(!$_SERVER['REMOTE_ADDR']){ $_SERVER['REMOTE_ADDR'] = $_SERVER['LOCAL_ADDR']; }


1

Можливо, вам доведеться скористатися, $HTTP_SERVER_VARS['server_ADDR']якщо ви не отримаєте нічого з наведених вище відповідей і якщо ви використовуєте старішу версію PHP


0

Перевірте масив $ _SERVER

echo $_SERVER['SERVER_ADDR'];

1
Це не знаходить "справжній IP", він знаходить довільні, неперевірені заголовки HTTP, які може встановити будь-хто, і будь-хто може використовувати для підробки свого IP-адреси, якщо ви бажаєте їх. Якщо клієнт стоїть за проксі-сервером, то нехай не довіряйте заголовкам HTTP. Це також зовсім не відповідає питанню.
— деге

2
Не можу зрозуміти, як ця відповідь взагалі не відповідає питанню. Питання було таке: "Як я можу ідентифікувати IP-адресу сервера в PHP?". Або ОП повинна навчитися краще ставити запитання, або ви повинні навчитися читати запитання. Крім того, якщо клієнт стоїть за проксі-сервером, ви все одно будете накручені незалежно від того, що ви намагаєтеся з боку сервера. Зовсім інший сценарій - це коли сервер стоїть за проксі, оскільки ви можете перевірити за допомогою заголовків X-FORWARDED-FOR.
— Луїс Масуеллі

@deceze $_SERVER["SERVER_ADDR"]не має нічого спільного з заголовками HTTP. Це заповнено серверним програмним забезпеченням, усі речі, пов’язані з HTTP, у $ _SERVER з префіксом HTTP_. php.net/manual/en/reserved.variables.server.php
— понча

@poncha Мій коментар стосувався оригінальної редакції цієї публікації.
— деге

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