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.