Как определить IP-адрес сервера в PHP


122

Как я могу определить IP-адрес сервера в PHP?


2
Вы имеете в виду IP-адрес запроса или IP-адрес компьютера, на котором запущено ваше приложение?
wosis

Ответы:


175

Вот так для ip сервера:

$_SERVER['SERVER_ADDR'];

и это для порта

$_SERVER['SERVER_PORT'];

10
Нет. На некоторых общих хостах это возвращает: 1
TheRealChx101 02

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

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

Это не дает ip сервера. По какой-то причине он дает мой локальный IP
Томас Уильямс

Он также не дает адрес сервера php-fpm, но предназначен для связанного веб-сервера (nginx, apache). Таким образом, это будет неправильно для спецификации хоста mysql-client (пользователь @ хост).
scipilot

105

Если вы используете PHP версии 5.3 или выше, вы можете сделать следующее:

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

Это хорошо работает, когда вы запускаете автономный сценарий, а не через веб-сервер.


Отлично, то, что я ищу. Спасибо, Джон
Фрэнк

6
+1 Это единственное решение, которое будет работать с командной строкой.
Adam Elsodaney

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, но если вы подключаетесь через locahost, вместо этого вы получаете :: 1 обратно. Если вы подключаетесь через имя или IP-адрес сервера, вы получаете обратно настоящий IP-адрес.
starbeamrainbowlabs

@starbeamrainbowlabs FastCGI - это CGI :) Я имел в виду, что в отличие от работы в качестве модуля ISAPI, это было написано до того, как FastCGI стал стабильной платформой.
Rudi Visser

@starbeamrainbowlabs все, что выглядит как :: 1, вероятно, является адресом IP6
Тоби Аллен

@TobyAllen Спасибо :). Странно то, что моя сеть не поддерживает ipv6, но мой сервер (машина с Windows 7) сообщает свой IP как :: 1, адрес обратной связи ipv6.
starbeamrainbowlabs

13

Я зашел на эту страницу в поисках способа получить свой собственный IP-адрес, а не 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, а затем только с активным беспроводным соединением, и оба раза он возвращал ip wlan. Хороший сценарий, спасибо!
Райан Григгс

На самом деле он не знает, какой из них вернуть. Он просто возвращает последний интерфейс inet из вывода ifconfig, игнорируя 127.0.0.1. Если у вас есть только «обычные» интерфейсы, то он неплохо справляется. Вероятно, будет наиболее безопасным, если вы укажете нужный интерфейс "ifconfig wlan0 | ...". Этот сценарий ни в коем случае не идеален, но он работает с простыми настройками и демонстрирует, как это сделать в принципе, при необходимости.
Dom

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 \. ) '- это моя последняя редакция этого. Он отфильтровывает все локальные IP-адреса и дает только внешние
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это может быть медленным. Честно говоря, я не уверен, какой подход будет правильным чаще всего, но урок, который нужно усвоить, заключается в том, что конкретные сценарии / конфигурации приведут к неправильным результатам для всех этих подходов ... поэтому, если возможно, убедитесь, что подход, который вы using возвращает ожидаемые значения.


10

Это то, что вы могли бы использовать в качестве адаптации приведенных выше примеров, не беспокоясь о том, что curl установлен на вашем сервере.

<?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, вы можете использовать:

$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. Это тоже совершенно не подходит под вопрос.
deceze

2
Не могу понять, как этот ответ вообще не соответствует вопросу. Вопрос был: «Как я могу определить IP-адрес сервера в PHP?». Либо ОП научится лучше спрашивать, либо вы научитесь читать вопрос. Кроме того, если клиент находится за прокси-сервером, вы все равно ошибаетесь, что бы вы ни пытались со стороны сервера. Совершенно другой сценарий - когда сервер находится за прокси, поскольку вы можете проверить с помощью заголовков X-FORWARDED-FOR.
Луис Масуэлли

@deceze $_SERVER["SERVER_ADDR"]не имеет ничего общего с заголовками HTTP. Он заполняется серверным программным обеспечением, все связанные с HTTP вещи в $ _SERVER имеют префикс HTTP_. php.net/manual/en/reserved.variables.server.php
poncha

@poncha Мой комментарий относился к исходной версии этого поста.
deceze

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