Jak zidentyfikować adres IP serwera w PHP


122

Jak mogę zidentyfikować adres IP serwera w PHP?


2
czy masz na myśli adres IP żądania czy adres IP maszyny, na której działa Twoja aplikacja?
wosis

Odpowiedzi:


175

W ten sposób dla IP serwera:

$_SERVER['SERVER_ADDR'];

i to dla portu

$_SERVER['SERVER_PORT'];

9
Nie. Na niektórych współdzielonych hostach zwraca to :: 1
TheRealChx101

3
Może to być nieprawidłowe w zależności od używanego modułu równoważenia obciążenia przed serwerem sieci Web. Potrzebujesz nagłówka X-Forwarded-For również w tym scenariuszu: en.wikipedia.org/wiki/X-Forwarded-For
Ligemer

31
To NIE jest adres serwera! Jest to adres, który zdalna przeglądarka wywołuje serwer, który jest pod kontrolą zdalnego użytkownika. John KZamiast tego skorzystaj z odpowiedzi
Ariel,

To nie daje IP serwera. Z jakiegoś powodu podaje mój lokalny adres IP
Thomas Williams

Nie podaje również adresu serwera php-fpm, ale dotyczy powiązanego serwera internetowego (nginx, apache). Więc nie będzie to poprawne dla specyfikacji hosta mysql-client (user @ host).
scipilot

105

Jeśli używasz PHP w wersji 5.3 lub nowszej, możesz wykonać następujące czynności:

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

Działa to dobrze, gdy uruchamiasz samodzielny skrypt, a nie przez serwer WWW.


Idealnie, czego szukam. Dzięki John
Frank

6
+1 To jedyne rozwiązanie, które będzie działać z wierszem poleceń.
Adam Elsodaney,

2
@andreas Nie powinno. Lokalna nazwa hosta powinna znajdować się w /etc/hostspliku i będzie szybka - chociaż może tak być 127.0.0.1. Jeśli będzie musiał dzwonić do DNS, będzie działać wolno, jak mówisz.
Ariel

+1, ale tylko pytanie ... próbuję z xampp na lokalnym serwerze i zwraca adres IP 192.168etc, ale ... powinno być 127.0.0.1 nie ??
Andrea Bori

to działa dla mnie, ale niektóre komputery wyświetlają nazwę domeny. jak rozwiązać ten problem.
Dharani Dharan

19

na przykład:

$_SERVER['SERVER_ADDR']

gdy korzystasz z usług IIS, spróbuj:

$_SERVER['LOCAL_ADDR']

2
$_SERVER['LOCAL_ADDR']jest dostępny tylko w IIS, gdy PHP działa jako moduł CGI.
Rudi Visser

@rudi_visser działa również z fastcgi, ale jeśli połączysz się przez locahost, zamiast tego otrzymasz :: 1 z powrotem. Jeśli połączysz się za pośrednictwem nazwy lub adresu IP serwera, odzyskasz prawdziwy adres IP.
starbeamrainbowlabs

@starbeamrainbowlabs FastCGI to CGI :) Miałem na myśli, w przeciwieństwie do uruchamiania jako moduł ISAPI, zostało to napisane przed wielkim pojawieniem się FastCGI jako stabilnej platformy.
Rudi Visser

@starbeamrainbowlabs wszystko, co wygląda :: 1 to prawdopodobnie adres IP6
Toby Allen,

@TobyAllen Dziękuję :). Dziwne jest to, że moja sieć nie obsługuje protokołu IPv6, a mimo to mój serwer (komputer z systemem Windows 7) zgłasza swój adres IP jako :: 1, czyli adres sprzężenia zwrotnego ipv6.
starbeamrainbowlabs

13

Przyszedłem na tę stronę, szukając sposobu na uzyskanie własnego adresu IP, a nie adresu zdalnego komputera, który się ze mną łączy.

To nie zadziała na komputerze z systemem Windows.

Ale na wypadek, gdyby ktoś szukał tego, czego szukałem:

#! /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;

(Bezwstydnie zaadaptowane z How to I get the primary IP address of the local machine on Linux and OS X? )


Jest to jedyna opcja, która faktycznie działa podczas uruchamiania skryptów PHP z powłoki. Pytanie: jeśli istnieje wiele aktywnych interfejsów, w jaki sposób decyduje o tym, który adres zwrócić? Testowałem z aktywnymi przewodowymi i bezprzewodowymi połączeniami Ethernet, a następnie tylko z aktywną siecią bezprzewodową i dwukrotnie zwraca wlan ip. Dobry scenariusz, dzięki!
Ryan Griggs

Właściwie nie wie, który z nich zwrócić. Zwraca po prostu ostatni interfejs inet z danych wyjściowych ifconfig, ale ignoruje 127.0.0.1. Jeśli masz tylko „zwykłe” interfejsy, robi to całkiem nieźle. Prawdopodobnie najbezpieczniej jest określić żądany interfejs "ifconfig wlan0 | ...". Ten skrypt nie jest bynajmniej doskonały, ale działa w prostych ustawieniach i pokazuje, jak to zrobić w zasadzie, aby można go było dostosować w razie potrzeby.
Dom

1
ifconfig | grep 'inet addr' | cut -d ':' -f 2 | awk '{print $ 1}' | grep -vE '^ (192 \ .168 | 10 \. | 172 \ .1 [6789] \. | 172 \ .2 [0-9] \. | 172 \ .3 [01] \. | 127 \. ) ”to moja ostatnia wersja tego. Odfiltrowuje wszystkie lokalne adresy IP i udostępnia tylko zewnętrzne
Dom

Mam wiele interfejsów sieciowych, więc tak zrobiłemifconfig | 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\.'
Jonathan

10

Żadna z najczęściej wybieranych odpowiedzi nie zwróci niezawodnie adresu publicznego serwera. Ogólnie$_SERVER['SERVER_ADDR'] będzie poprawne, ale jeśli uzyskujesz dostęp do serwera przez VPN, prawdopodobnie zwróci on adres sieci wewnętrznej zamiast adresu publicznego, a nawet jeśli nie jest w tej samej sieci, niektóre konfiguracje będą po prostu puste lub będą miały określone inne wartość.

Podobnie istnieją scenariusze, w których $host= gethostname(); $ip = gethostbyname($host);nie zwraca prawidłowych wartości, ponieważ opiera się on zarówno na systemie DNS (albo wewnętrznie skonfigurowanym lub zewnętrznych rekordach), jak i ustawieniach nazwy hosta serwera w celu ekstrapolacji adresu IP serwera. Oba te kroki są potencjalnie błędne. Na przykład, jeśli nazwa hosta serwera jest sformatowana jak nazwa domeny (tj. HOSTNAME=yahoo.com), To (przynajmniej w mojej konfiguracji php5.4 / Centos6) gethostbynameprzejdzie od razu do znalezienia adresu Yahoo.com, a nie lokalnego serwera.

Ponadto, ponieważ gethostbynamewraca do publicznych rekordów DNS serwera testowego z nieopublikowanymi lub nieprawidłowymi publicznymi rekordami DNS (na przykład uzyskujesz dostęp do serwera za localhostpomocą adresu IP lub jeśli zastępujesz publiczny DNS przy użyciu lokalnego hostspliku), Otrzymam albo brak adresu IP (zwróci tylko nazwę hosta), albo, co gorsza, zwróci zły adres określony w publicznych rekordach DNS, jeśli taki istnieje, lub jeśli istnieje wieloznacznik dla domeny.

W zależności od sytuacji możesz również wypróbować trzecie podejście, wykonując coś takiego:

$external_ip = exec('curl http://ipecho.net/plain; echo');

Ma to swoje wady (zależy od konkretnej witryny innej firmy i mogą istnieć ustawienia sieciowe, które kierują połączenia wychodzące przez inny host lub serwer proxy) i gethostbynamemogą być powolne. Szczerze mówiąc nie jestem pewien, które podejście będzie najczęściej poprawne, ale lekcja, którą należy wziąć sobie do serca, jest taka, że ​​określone scenariusze / konfiguracje spowodują nieprawidłowe wyniki dla wszystkich tych podejść ... więc jeśli to możliwe, sprawdź, czy podejście jest using zwraca oczekiwane wartości.


9

To właśnie możesz wykorzystać jako adaptację powyższych przykładów, nie martwiąc się o curl zainstalowaną na serwerze.

<?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

Jeśli używasz PHP w powłoce bash, możesz użyć:

$server_name=exec('hostname');

Ponieważ $_SERVER[] SERVER_ADDR, HTTP_HOSTi SERVER_NAMEnie są ustawione.


4

Wszystkie poprzednie odpowiedzi dają $ _SERVER ['SERVER_ADDR']. To nie zadziała w przypadku niektórych instalacji usług IIS. Jeśli chcesz, aby to działało w usługach IIS, użyj następującego:

$server_ip = gethostbyname($_SERVER['SERVER_NAME']);

2

Okazało się, że działa dla mnie: GetHostByName („”);

Uruchamianie XAMPP w wersji 1.7.1 na Windows 7 z serwerem internetowym Apache. Niestety podaje tylko adres IP mojej bramy.


2

Właśnie stworzyłem prosty skrypt, który przywróci $ _SERVER ['REMOTE_ADDR'] i $ _SERVER ['SERVER_ADDR'] w IIS, więc nie musisz zmieniać każdej zmiennej. Po prostu wklej ten tekst do pliku php, który jest zawarty na każdej stronie.

/** IIS IP Check **/
if(!$_SERVER['SERVER_ADDR']){ $_SERVER['SERVER_ADDR'] = $_SERVER['LOCAL_ADDR']; }
if(!$_SERVER['REMOTE_ADDR']){ $_SERVER['REMOTE_ADDR'] = $_SERVER['LOCAL_ADDR']; }

1
$serverIP = $_SERVER["SERVER_ADDR"];
echo "Server IP is: <b>{$serverIP}</b>";

1

Być może będziesz musiał użyć, $HTTP_SERVER_VARS['server_ADDR']jeśli nie otrzymujesz niczego z powyższych odpowiedzi i jeśli używasz starszej wersji PHP


0

Sprawdź tablicę $ _SERVER

echo $_SERVER['SERVER_ADDR'];

1
To nie znajduje „prawdziwego adresu IP”, ale znajduje dowolne, niezweryfikowane nagłówki HTTP, które każdy może ustawić i każdy może użyć do sfałszowania swojego adresu IP, jeśli wolisz. Jeśli klient znajduje się za serwerem proxy, niech tak będzie, nie ufaj żadnym nagłówkom HTTP. To również w ogóle nie pasuje do pytania.
deceze

2
Nie mogę pojąć, dlaczego ta odpowiedź w ogóle nie pasuje do pytania. Pytanie brzmiało: „Jak mogę zidentyfikować adres IP serwera w PHP?”. Albo PO powinien nauczyć się lepiej zadawać pytania, albo powinieneś nauczyć się czytać pytanie. Poza tym, jeśli klient jest za serwerem proxy, nadal masz spieprzone bez względu na to, co próbujesz po stronie serwera. Zupełnie inny scenariusz to sytuacja, w której serwer znajduje się za proxy, ponieważ możesz sprawdzić nagłówki X-FORWARDED-FOR.
Luis Masuelli

@deceze $_SERVER["SERVER_ADDR"]nie ma nic wspólnego z nagłówkami HTTP. Jest to wypełniane przez oprogramowanie serwera, wszystkie rzeczy związane z HTTP w $ _SERVER mają prefiks HTTP_. php.net/manual/en/reserved.variables.server.php
poncha

@poncha Mój komentarz dotyczył oryginalnej wersji tego posta.
deceze

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.