PHP cách lấy IP cục bộ của hệ thống


96

Tôi cần lấy IP cục bộ của máy tính như 192. * .... Điều này có khả thi với PHP không?

Tôi cần địa chỉ IP của hệ thống chạy script, nhưng tôi không cần IP bên ngoài, tôi cần địa chỉ card mạng cục bộ của anh ấy.

Câu trả lời:


111

Từ CLI

PHP <5.3.0

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

PHP> = 5.3.0

$localIP = getHostByName(getHostName());


2
Đây là giải pháp phù hợp với tôi và tránh gọi shell, lệnh của hệ điều hành và tất cả những thứ có thể mở lỗ hổng bảo mật hoặc phát sinh các vấn đề kỳ quặc sau này.
Dario Fumagalli,

1
Phản hồi tốt nhất thường đi kèm với sự đơn giản. Như vậy đó.
m3nda

1
@ andras.tim Tôi thích các câu trả lời đơn giản, tuy nhiên khi tôi chạy tập lệnh của bạn, nó không trả về địa chỉ IP máy của tôi mà trả về địa chỉ IP được sử dụng trong máy ảo của tôi.. Tuy nhiên, vấn đề có thể là gì?
Scarl

chỉ cần lưu ý, cách tiếp cận này dựa vào DNS phân giải chính xác bất kỳ tên máy chủ nào của hệ thống được đặt thành. điều đó sẽ không phải luôn luôn như vậy.
Justin McAleer

3
Trong môi trường lưu trữ đám mây, điều này có thể không trả lại kết quả mong đợi. Vì mỗi host đều có nhiều hơn 2 IP.
UnixAgain

60
$_SERVER['SERVER_ADDR']

13
Làm rõ: một máy tính có thể có nhiều địa chỉ IP. Biến này là chỉ HTTP và chứa địa chỉ IP mà máy chủ ảo đang chạy. Với câu hỏi mơ hồ đến mức nào, thật khó để nói liệu đây có phải là câu trả lời mong đợi hay không.
Álvaro González

Tôi nghĩ điều này là chính xác, bởi vì bạn luôn luôn cần một ip được đánh dấu, một trong những phản hồi cho bạn. Nếu không, bạn phải sử dụng asnwers của @ andras.tim, vì nó cho bạn biết ip chính của hệ thống.
m3nda

Đây chính xác là những gì tôi muốn, bởi vì các máy chủ của tôi ở sau một bộ cân bằng tải nên getHostNamekhông trả về tên miền trang web.
Yep_It's_Me

Điều này không hiệu quả nếu bạn đang chạy bên trong một thùng chứa
docker

30

Đây là một bài viết cũ, nhưng hãy lấy nó với cái này:

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

Ví dụ:

die( getLocalIp() );

Tìm thấy nó trên một trang web khác, không gỡ bỏ lệnh trim vì nếu không bạn sẽ nhận được tên máy tính.

BACKTICKS (Dấu ngoặc kép): Nó hoạt động vì PHP sẽ cố gắng chạy bất cứ thứ gì nằm giữa các "dấu ngoặc kép" (dấu ngoặc kép) đó như một lệnh shell và trả về kết quả đầu ra.

gethostbyname(trim(`hostname`));

Rất giống (nhưng hiệu quả hơn nhiều) so với:

$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: Bởi vì các dấu ngoặc kép đặc biệt, khi bạn sử dụng dấu ngoặc kép bình thường, nó không hoạt động vì một số lý do và khi bạn xóa lệnh trim, nó thậm chí không hoạt động. Nghe có vẻ lạ tôi biết. Thật không hay khi từ chối câu trả lời cho điều đó. Đọc câu trả lời.
Codebeat

2
Backticks (`) được gọi là toán tử thực thi trong PHP. Những gì bạn làm trong khối mã đầu tiên gần giống như lệnh thi hành. Xem PHP: Các toán tử thực thi - Hướng dẫn sử dụng
Christiaan

2
Không hẳn là ý tưởng tốt nhất. Có thể và hợp lệ gethostbynameđể trả về một IP lặp lại (ví dụ: 127.0.0.1) cho máy chủ.
không ai

2
Điều này giúp tôi rất nhiều, tôi nghĩ sẽ có một hàm PHP đơn giản như $ _SERVER ['REMOTE_ADDR']; mà không hoạt động, nhưng giải pháp này đã làm việc cho tôi !!!
Pini Cheyni

24

hãy thử điều này (nếu máy chủ của bạn là Linux):

$command="/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}'";
$localIP = exec ($command);
echo $localIP;

9
Không hoàn toàn đúng. Không có gì đảm bảo eth0là giao diện phù hợp.
không ai

Cảm ơn, điều này đã làm việc hoàn hảo cho tôi. Có thể thiết lập giao diện đã giúp!
Rahim Khoja

Trong trường hợp của tôi (IP cục bộ trong mạng cục bộ WiFi), tôi phải chỉ định wlan0thay vì eth0và thay thế 'inet addr:'bằng 'inet adr:', có thể do ngôn ngữ được sử dụng trên hệ thống của tôi (fr_FR). Ngoài ra, câu trả lời này là giải pháp mà tôi đang tìm kiếm. Cảm ơn!
Niavlys 14/02/17

Thực sự 'inet adr:'đã hoạt động trong thiết bị đầu cuối của tôi (ngôn ngữ Pháp), nhưng trong tập lệnh PHP 'inet addr:'là giá trị chính xác (tôi đoán là ngôn ngữ tiếng Anh).
Niavlys 14/02/17

20

Địa chỉ IP bên ngoài mặc định của máy cục bộ có thể được lấy như sau:

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

Làm thế nào nó hoạt động:

Vì đây là UDP, socket_connectnên không đi ra ngoài mạng. Nó chỉ gán địa chỉ cục bộ và cổng cho ổ cắm. Điều này cho phép chúng tôi có được địa chỉ địa phương.

Giải pháp này hoạt động mà không cần bất kỳ lưu lượng mạng, DNS hoặc thực thi lệnh nào.

Nó có thể không hoạt động nếu không có đường dẫn đến 8.8.8.8(ví dụ như bạn không có kết nối internet).


3
Câu trả lời này là CÁCH tốt hơn những câu khác. Mọi sự phụ thuộc vào mảng $ _SERVER đều phụ thuộc vào mảng này đang chạy trong Apache. Ý tưởng này cũng hoạt động trên một công việc cron. Tôi đang sử dụng nó để chỉ thực thi các chức năng nhất định nếu máy chủ đang chạy trên hệ thống hoặc mạng LAN sản xuất. Hoàn hảo!
mỗi

Đây là một câu trả lời thanh lịch. Tôi đã điều chỉnh nó trong một tập lệnh quản lý vùng chứa docker để lấy ip của máy chủ lưu trữ của tôi trên mạng $sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_connect($sock, $this->getDockerMachineIp(), 53);
docker

Tôi đoán nó dễ di chuyển hơn. Ngoài ra, điều quan trọng là phải đề cập đến socketsmô-đun nên được cài đặt và kích hoạt trên PHP.
Fabio Montefuscolo

vâng, thankyou rất nhiều @Arnaud Le Blanc, nó rất hữu ích cho tôi, tôi đã nhận địa chỉ của tôi IP với kỹ thuật này
Abid Ali

đây là những gì tôi đang tìm kiếm. cảm ơn!
Jorz

15

Phụ thuộc vào ý bạn muốn nói về địa phương:

Nếu địa chỉ của bạn là địa chỉ của máy chủ / hệ thống thực thi mã PHP, thì vẫn còn hai cách để thảo luận. Nếu PHP đang được chạy thông qua một máy chủ web, thì bạn có thể lấy địa chỉ máy chủ bằng cách đọc $_SERVER['SERVER_ADDR']. Nếu PHP đang được chạy thông qua một giao diện dòng lệnh, thì bạn có thể phải thực thi trình bao ipconfig(Windows) / ifconfig(* nix) và gửi địa chỉ ra.

Nếu địa chỉ của bạn là địa chỉ từ xa của khách truy cập trang web, nhưng không phải địa chỉ IP bên ngoài của họ (vì bạn đã nói cụ thể là 192. *), thì bạn đã không gặp may. Toàn bộ điểm của định tuyến NAT là ẩn địa chỉ đó. Bạn không thể xác định địa chỉ cục bộ của từng máy tính sau một địa chỉ IP, nhưng có một số thủ thuật (tác nhân người dùng, có thể là địa chỉ mac) có thể giúp phân biệt nếu có nhiều máy tính truy cập từ cùng một IP.


1
Và cuối cùng nhưng không kém phần quan trọng, ipconfig / ifconfig rất có thể sẽ trả về một số địa chỉ IP: bởi vì máy tính thường không có một địa chỉ duy nhất. Câu trả lời chính xác.
Álvaro González

vâng, toàn bộ điểm của NAT là ẩn địa chỉ IP cục bộ bây giờ hãy kiểm tra whatismyip.com họ biết địa chỉ ip nội bộ của bạn, mở trang web này bằng điện thoại di động của bạn, họ cũng biết địa chỉ ip cục bộ của điện thoại di động của bạn. EDIT: Im sử dụng JioFi Router, trên im di động sử dụng dữ liệu di động trên Android 9 AOSP Dựa rom
Rishabh Gusain

10

tên máy (1) có thể cho biết địa chỉ IP: hostname --ip-addresshoặc như người ta nói, tốt hơn là sử dụnghostname --all-ip-addresses


6

Bạn có thể thử điều này với tư cách là người dùng thông thường trong CLI trên máy chủ 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);

Đầu ra:

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', )Tôi hiểu rồi. Tôi đã thêm mã này vào tệp php,
Mũ Rơm

Câu trả lời tốt, thanx. split()hàm đã được DEPRECATED kể từ PHP 5.3.0. vì vậy đề nghị sử dụng explode()thay thế
Thanu

4
$localIP = gethostbyname(trim(exec("hostname")));

Tôi đã thử trong máy tính Windows và nó đã hoạt động và cũng nghĩ rằng Sẽ hoạt động trên Linux.


4

Nó rất đơn giản và những câu trả lời ở trên làm phức tạp mọi thứ. Đơn giản là bạn có thể lấy cả địa chỉ ip cục bộ và địa chỉ IP công cộng bằng phương pháp này.

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

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

?>

2

Nó là một trong những dễ dàng. Bạn có thể lấy tên máy chủ bằng mã đơn giản này.

$ip = getHostByName(getHostName());

Hoặc bạn cũng có thể sử dụng $_SERVER['HTTP_HOST']để lấy tên máy chủ.


1

Tôi đã tìm câu hỏi này cho một php phía máy chủ (chạy từ thiết bị đầu cuối Linux)

Tôi đã phát nổ 'ifconfig' và cắt nó xuống địa chỉ IP.

Nó đây:

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

Và tất nhiên thay đổi 'wlan0' thành thiết bị mạng mong muốn của bạn.

Đầu ra của tôi là:

192.168.1.5

0

Nếu bạn đang ở trong môi trường nhà phát triển trên OS X, được kết nối qua Wifi:

echo exec("/sbin/ifconfig en1 | grep 'inet ' | cut -d ' ' -f2");

0
$_SERVER['SERVER_NAME']

Nó đã làm việc cho tôi.


-4
$_SERVER['REMOTE_ADDR']
  • PHP_SELF Trả về tên tệp của tập lệnh hiện tại với đường dẫn liên quan đến gốc

  • SERVER_PROTOCOL Trả về tên và bản sửa đổi của giao thức do trang yêu cầu

  • REQUEST_METHOD Trả về phương thức yêu cầu được sử dụng để truy cập trang

  • DOCUMENT_ROOT Trả về thư mục gốc mà tập lệnh hiện tại đang thực thi


Tất cả đều đúng, nhưng cũng hoàn toàn không liên quan đến câu hỏi đã được đặt ra. -1.
Mark Amery

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.