Как определить 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.