PHP як отримати локальний IP системи


96

Мені потрібно отримати локальний IP комп’ютера, наприклад 192. * .... Чи можливо це за допомогою PHP?

Мені потрібна IP-адреса системи, яка запускає сценарій, але мені не потрібна зовнішня IP-адреса, мені потрібна адреса локальної мережевої картки.

Відповіді:


111

З CLI

PHP <5.3.0

$localIP = getHostByName(php_uname('n'));

PHP> = 5.3.0

$localIP = getHostByName(getHostName());


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

1
Найкраща реакція, як правило, полягає в простоті. Щось схоже на те.
m3nda

1
@ andras.tim Мені подобаються прості відповіді, однак, коли я запустив ваш сценарій, він не повертає IP-адресу моєї машини, а повертає IP-адресу, що використовується у моїй віртуальній машині ... що може бути проблемою?
Scarl

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

3
У середовищі хмарного хостингу це може не повернути очікуваного результату. Оскільки кожен хост має більше 2 IP-адрес.
UnixAgain

60
$_SERVER['SERVER_ADDR']

13
Уточнення: комп’ютер може мати кілька IP-адрес. Ця змінна призначена лише для HTTP та містить IP-адресу, на якій працює віртуальний хост. Враховуючи, наскільки розмитим є питання, важко сказати, чи це очікувана відповідь.
Альваро Гонсалес

Я вважаю, що це правильно, тому що вам завжди потрібний призначений ip, той відповідає вам. Якщо ні, ви повинні використовувати відповіді @ andras.tim, оскільки повідомляє вам основний ip системи.
m3nda

Це саме те, що я хотів, оскільки мої сервери стоять за балансиром навантаження, тому getHostNameне повертають доменне ім’я сайтів.
Yep_It's_Me

Це не працює, якщо ви працюєте в контейнері
докера

30

Це стара публікація, але отримайте її з цим:

function getLocalIp()
{ return gethostbyname(trim(`hostname`)); }

Наприклад:

die( getLocalIp() );

Знайшов його на іншому сайті, не видаляйте команду trim, бо інакше ви отримаєте ім'я комп'ютерів.

ЗВЕРНЕННЯ (Спеціальні лапки): Це працює, тому що PHP намагатиметься запускати все, що знаходиться між цими "спеціальними лапками" (зворотні позначки) як команду оболонки і повертає отриманий результат.

gethostbyname(trim(`hostname`));

Дуже подібний (але набагато ефективніший), ніж робити:

$exec = exec("hostname"); //the "hostname" is a valid command in both windows and linux
$hostname = trim($exec); //remove any spaces before and after
$ip = gethostbyname($hostname); //resolves the hostname using local hosts resolver or DNS

7
@paul: Через спеціальні лапки, коли ви використовуєте звичайні лапки, це не працює з якихось причин, а коли ви видаляєте команду trim, вона навіть не працює. Це звучить дивно, я знаю. Не приємно проголосувати за це відповідь. Прочитайте відповідь.
Codebeat

2
Зворотні позначки (`) називаються оператором виконання в PHP. Те, що ви робите в першому блоці коду, майже те саме, що і команда exec. Див. PHP: Оператори виконання - Посібник
Крістіан

2
Не зовсім найкраща ідея. gethostbynameПовернути петлевий IP-адрес (наприклад, 127.0.0.1) для хост-машини можливо і дійсно .
ніхто

2
Це мені дуже допомогло, я думав, що буде така проста PHP-функція, як $ _SERVER ['REMOTE_ADDR']; що не спрацювало, але це рішення спрацювало для мене !!!
Піні Чейні,

24

спробуйте це (якщо ваш сервер Linux):

$command="/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'";
$localIP = exec ($command);
echo $localIP;

9
Не зовсім правильно. Немає гарантії eth0, що відповідний інтерфейс.
ніхто

Дякую, у мене це спрацювало чудово. Можливість налаштування інтерфейсу допомогла!
Рахім Ходжа,

У моєму випадку (локальний IP в локальній мережі WiFi) мені довелося вказати wlan0замість eth0і замінити 'inet addr:'на 'inet adr:', можливо через локаль, що використовується в моїй системі (fr_FR). Окрім цього, ця відповідь була рішенням, яке я шукав. Дякую!
Niavlys

Добре насправді 'inet adr:'працював у моєму терміналі (французька мова), але в скрипті PHP 'inet addr:'було правильне значення (я думаю, англійська мова).
Niavlys

20

Зовнішню IP-адресу локальної машини за замовчуванням можна отримати так:

$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_connect($sock, "8.8.8.8", 53);
socket_getsockname($sock, $name); // $name passed by reference

$localAddr = $name;

Як це працює:

Оскільки це UDP, socket_connectне виходить з мережі. Він призначає лише локальну адресу та порт сокету. Це дозволяє нам отримати місцеву адресу.

Це рішення працює без мережевого трафіку, DNS або виконання команд.

Це може не спрацювати, якщо немає маршруту до 8.8.8.8(наприклад, у вас немає з’єднання з Інтернетом).


3
Ця відповідь набагато краща за інші. Будь-яка залежність від масиву $ _SERVER залежить від цього, що працює в Apache. Ця ідея також працює на роботі cron. Я використовую його для виконання певних функцій лише у тому випадку, якщо сервер працює на проміжній або виробничій локальній мережі. Ідеально!
За

Це елементарна відповідь. Я адаптував його в сценарії управління контейнерами докерів, щоб отримати ip мого хоста в докер-мережі:$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_connect($sock, $this->getDockerMachineIp(), 53);
FatherShawn

Напевно, це портативніше. Крім того, важливо згадати, що socketsмодуль повинен бути встановлений і включений на PHP.
Фабіо Монтефусколо,

так, дуже дякую @Arnaud Le Blanc, це дуже корисно для мене, я отримав свою IP-адресу за допомогою цієї техніки
Абід Алі

це те, що я шукаю. Дякую!
Йорж

15

Залежить від того, що ви маєте на увазі під місцевим:

Якщо під локальним ви маєте на увазі адресу сервера / системи, що виконує PHP-код, тоді є ще два шляхи обговорення. Якщо PHP запускається через веб-сервер, ви можете отримати адресу сервера, прочитавши $_SERVER['SERVER_ADDR']. Якщо PHP запускається через інтерфейс командного рядка, вам, швидше за все, доведеться виконати оболонку ipconfig(Windows) / ifconfig(* nix) і видалити адресу.

Якщо під місцевими мовами ви маєте на увазі віддалену адресу відвідувача веб-сайту, але не їх зовнішню IP-адресу (оскільки ви конкретно сказали 192. *), то вам не пощастило. Вся суть маршрутизації NAT полягає в тому, щоб приховати цю адресу. Ви не можете ідентифікувати локальні адреси окремих комп’ютерів за IP-адресою, але існують деякі хитрощі (агент користувача, можливо, mac-адреса), які можуть допомогти розрізнити, чи є кілька комп’ютерів, що мають доступ до однієї IP-адреси.


1
І останнє, але не менш важливе: ipconfig / ifconfig, швидше за все, поверне декілька IP-адрес: оскільки комп’ютер зазвичай не має однієї адреси. Чудова відповідь.
Альваро Гонсалес

так, вся суть NAT полягає в тому, щоб приховати локальний IP, тепер перевірте whatismyip.com, вони знають вашу внутрішню ip-адресу, а також відкрийте цей веб-сайт за допомогою мобільного, вони також знають вашу локальну ip-адресу вашого мобільного телефону. EDIT: Im using JioFi Router, on mobile im using mobile data on Android 9 AOSP Based rom
Rishabh Gusain

10

ім'я хосту (1) може вказати IP-адресу: hostname --ip-addressабо, як каже людина, краще використовуватиhostname --all-ip-addresses


6

Ви можете спробувати це як звичайний користувач у CLI на хості Linux:

function get_local_ipv4() {
  $out = split(PHP_EOL,shell_exec("/sbin/ifconfig"));
  $local_addrs = array();
  $ifname = 'unknown';
  foreach($out as $str) {
    $matches = array();
    if(preg_match('/^([a-z0-9]+)(:\d{1,2})?(\s)+Link/',$str,$matches)) {
      $ifname = $matches[1];
      if(strlen($matches[2])>0) {
        $ifname .= $matches[2];
      }
    } elseif(preg_match('/inet addr:((?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3})\s/',$str,$matches)) {
      $local_addrs[$ifname] = $matches[1];
    }
  }
  return $local_addrs;
}

$addrs = get_local_ipv4();
var_export($addrs);

Вихід:

array (
  'eth0' => '192.168.1.1',
  'eth0:0' => '192.168.2.1',
  'lo' => '127.0.0.1',
  'vboxnet0' => '192.168.56.1',
)

array('bond0'=>'10.66.42.83','bond1'=>'hosting Ip address','lo'=>'127.0.0.1', )Я отримав це. Я додав цей код у php-файл,
Солом’яний капелюх

Гарна відповідь, дякую. split()функція ВІДМОВЛЕНА станом на PHP 5.3.0. тому пропонуємо використовувати explode()замість цього
Тану

4
$localIP = gethostbyname(trim(exec("hostname")));

Я пробував у ПК з Windows, і це працювало, а також думаю, що буде працювати на Linux для.


4

Це дуже просто, і відповіді вище ускладнюють ситуацію. За допомогою цього методу ви можете отримати як місцеві, так і загальнодоступні ip-адреси.

   <?php 
$publicIP = file_get_contents("http://ipecho.net/plain");
echo $publicIP;

$localIp = gethostbyname(gethostname());
echo $localIp;

?>

2

Це легко. Ви можете отримати ім’я хосту за цим простим кодом.

$ip = getHostByName(getHostName());

Або ви також можете використовувати, $_SERVER['HTTP_HOST']щоб отримати ім'я хосту.


1

Я перебирав це питання для php на стороні сервера (працює з терміналу Linux)

Я вибухнув "ifconfig" і обрізав його до IP-адреси.

Ось:

$interface_to_detect = 'wlan0';
echo explode(' ',explode(':',explode('inet addr',explode($interface_to_detect,trim(`ifconfig`))[1])[1])[1])[0];

І звичайно, змініть 'wlan0' на потрібний мережевий пристрій.

Мій вихід:

192.168.1.5

0

Якщо ви перебуваєте в середовищі розробника на OS X, підключеному через Wi-Fi:

echo exec("/sbin/ifconfig en1 | grep 'inet ' | cut -d ' ' -f2");


-4
$_SERVER['REMOTE_ADDR']
  • PHP_SELF Повертає ім'я файлу поточного сценарію із шляхом відносно кореня

  • SERVER_PROTOCOL Повертає назву та редакцію запитуваного сторінкою протоколу

  • REQUEST_METHOD Повертає метод запиту, який використовується для доступу до сторінки

  • DOCUMENT_ROOT Повертає кореневий каталог, під яким виконується поточний сценарій


Все вірно, але також і абсолютно не має відношення до поставленого питання. -1.
Mark Amery

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