PHP jak uzyskać lokalny adres IP systemu

96

Muszę uzyskać lokalny adres IP komputera, np. 192. * .... Czy jest to możliwe z PHP?

Potrzebuję adresu IP systemu z uruchomionym skryptem, ale nie potrzebuję zewnętrznego adresu IP, potrzebuję adresu jego lokalnej karty sieciowej.

powietrze
źródło

Odpowiedzi:

111

Z CLI

PHP <5.3.0

$localIP = getHostByName(php_uname('n'));

PHP> = 5.3.0

$localIP = getHostByName(getHostName());

andras.tim
źródło
2
To rozwiązanie zadziałało w moim przypadku i pozwala uniknąć wywoływania powłok, poleceń systemu operacyjnego i wszelkiego rodzaju rzeczy, które mogą otwierać luki w zabezpieczeniach lub powodować późniejsze dziwne problemy.
Dario Fumagalli,
1
Najlepsza odpowiedź zwykle wiąże się z prostotą. Tak.
m3nda
1
@ andras.tim Lubię proste odpowiedzi, ale kiedy uruchomiłem twój skrypt, nie zwraca on adresu IP mojej maszyny, ale zwraca adres IP użyty w mojej maszynie wirtualnej… co może być problemem?
Scarl
po prostu bądź świadomy, to podejście polega na poprawnym rozpoznaniu przez DNS dowolnej nazwy hosta systemu. nie zawsze tak będzie.
Justin McAleer,
3
W środowisku hostingu w chmurze może to nie przynieść oczekiwanego wyniku. Ponieważ każdy host ma więcej niż 2 adresy IP.
UnixAgain
60
$_SERVER['SERVER_ADDR']
Sergey Eremin
źródło
13
Wyjaśnienie: komputer może mieć kilka adresów IP. Ta zmienna obsługuje tylko protokół HTTP i zawiera adres IP, na którym działa wirtualny host. Biorąc pod uwagę, jak niejasne jest pytanie, trudno powiedzieć, czy jest to oczekiwana odpowiedź.
Álvaro González
Myślę, że to jest poprawne, ponieważ zawsze potrzebujesz przypisanego adresu IP, ten odpowiada ci. Jeśli nie, musisz użyć odpowiedzi @ andras.tim, ponieważ informuje cię o głównym adresie IP systemu.
m3nda
Właśnie tego chciałem, ponieważ moje serwery znajdują się za systemem równoważenia obciążenia, więc getHostNamenie zwracają nazwy domeny witryn.
Yep_It's_Me
To nie działa, jeśli korzystasz z kontenera
dockera
30

To jest stary post, ale pobierz go za pomocą tego:

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

Na przykład:

die( getLocalIp() );

Znalazłeś go w innej witrynie, nie usuwaj polecenia trim, ponieważ w przeciwnym razie otrzymasz nazwę komputera.

BACKTICKS (Specjalne cudzysłowy): Działa, ponieważ PHP spróbuje uruchomić wszystko, co znajduje się pomiędzy tymi "specjalnymi cudzysłowami" (lewy apostrof) jako polecenie powłoki i zwróci wynik.

gethostbyname(trim(`hostname`));

Jest bardzo podobny (ale znacznie bardziej wydajny) niż robienie:

$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
Codebeat
źródło
7
@paul: Ze względu na specjalne cudzysłowy, kiedy używasz zwykłych cudzysłowów, z jakiegoś powodu nie działa, a po usunięciu polecenia przycinania nawet nie działa. Wiem, brzmi dziwnie. Negowanie odpowiedzi na to pytanie nie jest miłe. Przeczytaj odpowiedź.
Codebeat
2
Backticks (`) nazywane są w PHP operatorem wykonywania. To, co robisz w pierwszym bloku kodu, jest prawie takie samo jak polecenie exec. Zobacz PHP: Operatorzy wykonania - Podręcznik
Christiaan,
2
Nie jest to najlepszy pomysł. Możliwe i ważne gethostbynamejest zwrócenie adresu IP pętli zwrotnej (np. 127.0.0.1) dla maszyny hosta.
nikt
2
To mi bardzo pomogło, pomyślałem, że będzie prosta funkcja PHP, taka jak $ _SERVER ['REMOTE_ADDR']; co nie zadziałało, ale to rozwiązanie zadziałało dla mnie !!!
Pini Cheyni
24

spróbuj tego (jeśli twój serwer to Linux):

$command="/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'";
$localIP = exec ($command);
echo $localIP;
George Deac
źródło
9
Niezupełnie w porządku. Nie ma gwarancji, eth0że interfejs jest odpowiedni.
nikt
Dzięki, to zadziałało idealnie dla mnie. Możliwość ustawienia interfejsu pomogła!
Rahim Khoja
W moim przypadku (lokalne IP w sieci lokalnej WiFi) Musiałem podać wlan0zamiast eth0i zastąpić 'inet addr:'z 'inet adr:', prawdopodobnie ze względu na lokalizacji używane w moim systemie (fr_FR). Poza tym ta odpowiedź była rozwiązaniem, którego szukałem. Dzięki!
Niavlys,
Właściwie 'inet adr:'działało na moim terminalu (francuskie locale), ale w skrypcie PHP 'inet addr:'była poprawna wartość (chyba angielskie ustawienie regionalne).
Niavlys,
21

Domyślny zewnętrzny adres IP komputera lokalnego można uzyskać w następujący sposób:

$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;

Jak to działa:

Ponieważ jest to UDP, socket_connectnie wychodzi w sieci. Przypisuje tylko lokalny adres i port do gniazda. To pozwala nam uzyskać lokalny adres.

To rozwiązanie działa bez ruchu sieciowego, DNS lub wykonywania poleceń.

Może nie działać, jeśli nie ma trasy do 8.8.8.8(np. Nie masz połączenia z Internetem).

Arnaud Le Blanc
źródło
3
Ta odpowiedź jest DUŻO lepsza niż inne. Każde poleganie na tablicy $ _SERVER jest zależne od tego, czy działa ona pod Apache. Ten pomysł działa również w zadaniu cron. Używam go tylko do wykonywania niektórych funkcji, jeśli serwer jest uruchomiony w pomostowej lub produkcyjnej sieci LAN. Idealny!
Na
To jest elegancka odpowiedź. Zaadaptowałem go w skrypcie zarządzającym kontenerami docker, aby uzyskać $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_connect($sock, $this->getDockerMachineIp(), 53);
adres
Sądzę, że jest bardziej przenośny. Należy również wspomnieć, że socketsmoduł powinien być zainstalowany i włączony w PHP.
Fabio Montefuscolo
tak, bardzo dziękuję @Arnaud Le Blanc, jest to dla mnie bardzo pomocne, otrzymałem swój adres IP za pomocą tej techniki
Abid Ali
15

Zależy, co masz na myśli mówiąc o lokalnym:

Jeśli przez lokalny masz na myśli adres serwera / systemu wykonującego kod PHP, nadal istnieją dwie możliwości do omówienia. Jeśli PHP jest uruchamiane przez serwer WWW, możesz uzyskać adres serwera, czytając $_SERVER['SERVER_ADDR']. Jeśli PHP jest uruchamiane przez interfejs wiersza poleceń, prawdopodobnie będziesz musiał wykonać polecenie powłoki ipconfig(Windows) / ifconfig(* nix) i odczytać adres.

Jeśli przez lokalny masz na myśli zdalny adres osoby odwiedzającej witrynę, ale nie jej zewnętrzny adres IP (skoro podałeś 192. *), to nie masz szczęścia. Celem routingu NAT jest ukrycie tego adresu. Nie można zidentyfikować lokalnych adresów poszczególnych komputerów za adresem IP, ale istnieją pewne sztuczki (agent użytkownika, prawdopodobnie adres MAC), które mogą pomóc w odróżnieniu wielu komputerów uzyskujących dostęp z tego samego adresu IP.

Fosco
źródło
1
I wreszcie, ipconfig / ifconfig najprawdopodobniej zwróci kilka adresów IP: ponieważ komputer zwykle nie ma jednego adresu. Świetna odpowiedź.
Álvaro González
tak, celem NAT jest ukrycie lokalnego adresu IP, teraz sprawdź whatismyip.com , znają twój wewnętrzny adres IP, a także otwórz tę witrynę za pomocą telefonu komórkowego, znają również lokalny adres IP twojego telefonu komórkowego. EDYCJA: Używam routera JioFi, na telefonie komórkowym korzystam z danych mobilnych na Androidzie 9 Rom oparty na
AOSP
10

nazwa hosta (1) może powiedzieć adres IP: hostname --ip-addresslub, jak mówi człowiek, lepiej jest użyćhostname --all-ip-addresses

ern0
źródło
6

Możesz spróbować tego jako zwykły użytkownik w CLI na hoście 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);

Wynik:

array (
  'eth0' => '192.168.1.1',
  'eth0:0' => '192.168.2.1',
  'lo' => '127.0.0.1',
  'vboxnet0' => '192.168.56.1',
)
ab1965
źródło
array('bond0'=>'10.66.42.83','bond1'=>'hosting Ip address','lo'=>'127.0.0.1', )Mam to. Dodałem ten kod w pliku php,
Słomkowy kapelusz,
Dobra odpowiedź, dzięki. split()funkcja została WYCOFANA w PHP 5.3.0. więc sugeruj użycie explode()zamiast tego
Thanu
5
$localIP = gethostbyname(trim(exec("hostname")));

Próbowałem na komputerze z systemem Windows i działało, a także myślę, że będzie działać na Linuksie.

Pratik Boda
źródło
4

Jest to bardzo proste, a powyższe odpowiedzi komplikują sprawę. Po prostu możesz uzyskać zarówno lokalne, jak i publiczne adresy IP za pomocą tej metody.

   <?php 
$publicIP = file_get_contents("http://ipecho.net/plain");
echo $publicIP;

$localIp = gethostbyname(gethostname());
echo $localIp;

?>
Chinthaka Devinda
źródło
2

To jest łatwe. Możesz uzyskać nazwę hosta za pomocą tego prostego kodu.

$ip = getHostByName(getHostName());

Możesz też użyć, $_SERVER['HTTP_HOST']aby uzyskać nazwę hosta.

Kowsigan Atsayam
źródło
1

Bawiłem się tym pytaniem dla PHP po stronie serwera (działającego z terminala Linux)

Wyrzuciłem „ifconfig” i sprowadziłem do adresu IP.

Oto ona:

$interface_to_detect = 'wlan0';
echo explode(' ',explode(':',explode('inet addr',explode($interface_to_detect,trim(`ifconfig`))[1])[1])[1])[0];

I oczywiście zmień „wlan0” na żądane urządzenie sieciowe.

Mój wynik to:

192.168.1.5
Gonen
źródło
0

Jeśli pracujesz w środowisku deweloperskim na OS X, połączonym przez Wi-Fi:

echo exec("/sbin/ifconfig en1 | grep 'inet ' | cut -d ' ' -f2");
gpupo
źródło
0
$_SERVER['SERVER_NAME']

U mnie to zadziałało.

Tytan
źródło
-4
$_SERVER['REMOTE_ADDR']
  • PHP_SELF Zwraca nazwę pliku bieżącego skryptu ze ścieżką względem katalogu głównego

  • SERVER_PROTOCOL Zwraca nazwę i wersję protokołu żądanego strony

  • REQUEST_METHOD Zwraca metodę żądania używaną do uzyskania dostępu do strony

  • DOCUMENT_ROOT Zwraca katalog główny, w którym wykonywany jest bieżący skrypt

user2301590
źródło
Wszystko prawda, ale też wszystko zupełnie nieistotne dla zadanego pytania. -1.
Mark Amery,
-6

Spróbuj tego

$localIP = gethostbyname(trim('hostname'));
matija kancijan
źródło