Як ідентифікувати 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.