PHP как получить локальный IP системы


96

Мне нужно получить локальный IP-адрес компьютера, например 192. * .... Возможно ли это с помощью PHP?

Мне нужен IP-адрес системы, в которой запущен скрипт, но мне не нужен внешний IP, мне нужен его адрес локальной сетевой карты.

Ответы:


112

Из интерфейса командной строки

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, тот отвечает вам. Если нет, вы должны использовать asnwers @andras.tim, потому что он сообщает вам основной IP-адрес системы.
m3nda

Это именно то, что я хотел, потому что мои серверы находятся за балансировщиком нагрузки, поэтому getHostNameне возвращают доменное имя сайта.
Yep_It's_Me

Это не работает, если вы работаете в контейнере
докеров

30

Это старый пост, но получите его вот так:

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

Например:

die( getLocalIp() );

Нашли его на другом сайте, не удаляйте команду обрезки, иначе вы получите имя компьютера.

НАЗАД (специальные кавычки): это работает, потому что 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: из-за специальных кавычек, когда вы используете обычные кавычки, они по какой-то причине не работают, а когда вы удаляете команду обрезки, она даже не работает. Я знаю, это звучит странно. Нехорошо отрицать ответ за это. Прочтите ответ.
Codebeat

2
Обратные кавычки (`) в PHP называются оператором выполнения. То, что вы делаете в первом блоке кода, почти то же самое, что и команда exec. См. PHP: Операторы выполнения - Руководство
Christiaan

2
Не лучшая идея. Возможно и действительно для gethostbynameвозврата IP-адреса обратной петли (например, 127.0.0.1) для хост-машины.
никто

2
Это мне очень помогло, я думал, что будет простая функция PHP вроде $ _SERVER ['REMOTE_ADDR']; что не сработало, но это решение сработало для меня !!!
Pini Cheyni

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

21

Внешний 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. Я использую его только для выполнения определенных функций, если сервер работает в промежуточной или производственной локальной сети. Отлично!
За

Это элегантный ответ. Я приспособил его в сценарии управления Docker контейнеров , чтобы получить IP - адрес моего хоста в сети Docker:$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) и найти адрес с помощью grep.

Если под локальным вы подразумеваете удаленный адрес посетителя веб-сайта, но не его внешний IP-адрес (поскольку вы специально указали 192. *), то вам не повезло. Весь смысл маршрутизации NAT - скрыть этот адрес. Вы не можете определить локальные адреса отдельных компьютеров за IP-адресом, но есть некоторые уловки (пользовательский агент, возможно, MAC-адрес), которые могут помочь различить, есть ли несколько компьютеров, осуществляющих доступ с одного и того же IP-адреса.


1
И последнее, но не менее важное: ipconfig / ifconfig, скорее всего, вернет несколько IP-адресов: потому что у компьютера обычно нет одного адреса. Отличный ответ.
Альваро Гонсалес,

да, весь смысл NAT заключается в том, чтобы скрыть локальный IP-адрес, теперь проверьте whatismyip.com, они знают ваш внутренний IP-адрес, также откройте этот веб-сайт, используя свой мобильный телефон, они также знают локальный IP-адрес вашего мобильного телефона. РЕДАКТИРОВАТЬ: Я использую маршрутизатор JioFi, на мобильном устройстве я использую мобильные данные на Android 9 на базе AOSP
Ришаб Гусейн

10

hostname (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()вместо этого
Thanu

5
$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.
Марк Эмери

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.