Cách xác định địa chỉ IP máy chủ trong PHP


122

Làm cách nào để xác định địa chỉ IP của máy chủ trong PHP?


2
ý bạn là địa chỉ IP yêu cầu hay IP của máy chạy ứng dụng của bạn?
wosis

Câu trả lời:


175

Như thế này cho ip máy chủ:

$_SERVER['SERVER_ADDR'];

và cái này cho cảng

$_SERVER['SERVER_PORT'];

9
Số Trên một số host chia sẻ lợi nhuận này :: 1
TheRealChx101

3
Điều này có thể không chính xác tùy thuộc vào Cân bằng tải đang được sử dụng trước máy chủ web của bạn. Bạn cũng muốn có tiêu đề X-Forwarded-For trong trường hợp này: en.wikipedia.org/wiki/X-Forwarded-For
Ligemer

31
Đây KHÔNG phải là địa chỉ máy chủ! Đây là địa chỉ mà trình duyệt từ xa gọi đến máy chủ, máy chủ nằm dưới sự kiểm soát của người dùng từ xa. John KThay vào đó, hãy sử dụng câu trả lời
Ariel

Điều này không cung cấp cho máy chủ ip. Vì lý do nào đó, nó đang cấp cho ip cục bộ của tôi
Thomas Williams

Nó cũng không cung cấp địa chỉ máy chủ php-fpm, nhưng dành cho máy chủ web được liên kết (nginx, apache). Vì vậy, nó sẽ không chính xác đối với đặc tả máy chủ mysql-client (user @ host).
scipilot

105

Nếu bạn đang sử dụng phiên bản PHP 5.3 trở lên, bạn có thể làm như sau:

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

Điều này hoạt động tốt khi bạn đang chạy một tập lệnh độc lập, không chạy qua máy chủ web.


Hoàn hảo, những gì tôi đang tìm kiếm. Cảm ơn John
Frank

6
+1 Đây là giải pháp duy nhất sẽ hoạt động với dòng lệnh.
Adam Elsodaney

2
@andreas Nó không nên. Tên máy chủ cục bộ phải có trong /etc/hoststệp và sẽ nhanh - mặc dù có thể là vậy 127.0.0.1. Nếu nó phải gọi DNS thì nó sẽ chậm như bạn nói.
Ariel

+1 nhưng chỉ là một câu hỏi .. tôi thử nó với xampp trên máy chủ cục bộ và nó trả về ip 192.168etc nhưng .. nó phải là 127.0.0.1 không ??
Andrea Bori

điều này làm việc cho tôi nhưng một số máy hiển thị tên miền của nó. làm thế nào để khắc phục vấn đề này.
Dharani Dharan

19

ví dụ:

$_SERVER['SERVER_ADDR']

khi bạn sử dụng IIS, hãy thử:

$_SERVER['LOCAL_ADDR']

2
$_SERVER['LOCAL_ADDR']chỉ khả dụng trong IIS khi PHP đang chạy dưới dạng mô-đun CGI.
Rudi Visser

@rudi_visser nó cũng hoạt động với fastcgi, nhưng nếu bạn kết nối qua locahost, bạn sẽ nhận được :: 1 trở lại. Nếu bạn kết nối qua tên hoặc ip của máy chủ, bạn sẽ lấy lại được ip thực.
starbeamrainbowlabs 21/07/12

@starbeamrainbowlabs FastCGI CGI :) Ý tôi là trái ngược với việc chạy dưới dạng mô-đun ISAPI, điều này được viết trước khi FastCGI ra đời chính như một nền tảng ổn định.
Rudi Visser

bất cứ điều gì @starbeamrainbowlabs mà trông giống như :: 1 có lẽ là một địa chỉ IP6
Toby Allen

@TobyAllen Cảm ơn bạn :). Điều kỳ lạ là mạng của tôi không hỗ trợ ipv6, nhưng máy chủ của tôi (máy windows 7) lại báo cáo IP của nó là :: 1, địa chỉ vòng lặp ipv6.
starbeamrainbowlabs 21/12/12

13

Tôi đến trang này để tìm cách lấy địa chỉ ip của chính mình không phải của một máy từ xa đang kết nối với tôi.

Điều này sẽ không hoạt động đối với máy tính Windows.

Nhưng trong trường hợp ai đó tìm kiếm những gì tôi đang tìm kiếm:

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

(Điều chỉnh một cách đáng xấu hổ từ Cách lấy địa chỉ IP chính của máy cục bộ trên Linux và OS X? )


Đây là tùy chọn duy nhất thực sự hoạt động khi chạy các tập lệnh PHP từ shell. Câu hỏi: khi có nhiều giao diện hoạt động, điều này sẽ quyết định địa chỉ nào sẽ trả về? Tôi đã thử nghiệm với các kết nối ethernet có dây và không dây đang hoạt động, và sau đó chỉ với không dây hoạt động và nó trả về ip wlan cả hai lần. Kịch bản tốt, cảm ơn!
Ryan Griggs

Nó thực sự không biết cái nào để trả lại. Nó chỉ trả về giao diện inet cuối cùng từ đầu ra của ifconfig, nhưng bỏ qua 127.0.0.1. Nếu bạn chỉ có các giao diện "thông thường", thì nó hoạt động khá tốt. Có lẽ là an toàn nhất nếu bạn chỉ định giao diện bạn muốn "ifconfig wlan0 | ...". Tập lệnh này không có nghĩa là hoàn hảo nhưng nó hoạt động trong các cài đặt đơn giản và nó thể hiện cách thực hiện điều này về nguyên tắc, được điều chỉnh khi cần thiết.
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 \. ) 'là bản sửa đổi mới nhất của tôi về điều này. Nó lọc ra tất cả các ips cục bộ và chỉ cung cấp cho bạn các phần mềm bên ngoài
Dom

Tôi có nhiều giao diện mạng vì vậy tôi đã làmifconfig | 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

Không câu trả lời nào được bình chọn nhiều nhất sẽ trả về địa chỉ công cộng của máy chủ một cách đáng tin cậy. Nói chung $_SERVER['SERVER_ADDR']sẽ đúng, nhưng nếu bạn đang truy cập máy chủ thông qua VPN, nó có thể sẽ trả về địa chỉ mạng nội bộ thay vì địa chỉ công cộng và ngay cả khi không ở trên cùng một mạng, một số cấu hình sẽ đơn giản là trống hoặc có một số cấu hình khác được chỉ định giá trị.

Tương tự như vậy, có những trường hợp $host= gethostname(); $ip = gethostbyname($host);sẽ không trả về giá trị chính xác vì nó dựa vào cả DNS (được định cấu hình nội bộ hoặc bản ghi bên ngoài) và cài đặt tên máy chủ của máy chủ để ngoại suy địa chỉ IP của máy chủ. Cả hai bước này đều có khả năng bị lỗi. Ví dụ: nếu tên máy chủ của máy chủ được định dạng giống như tên miền (tức là HOSTNAME=yahoo.com) thì (ít nhất là trên thiết lập php5.4 / Centos6 của tôi) gethostbynamesẽ chuyển thẳng đến việc tìm địa chỉ của Yahoo.com thay vì máy chủ cục bộ.

Hơn nữa, do lỗi gethostbynameghi lại DNS công cộng, một máy chủ thử nghiệm có các bản ghi DNS công cộng chưa được xuất bản hoặc không chính xác (ví dụ: bạn đang truy cập máy chủ bằng localhosthoặc địa chỉ IP hoặc nếu bạn đang ghi đè DNS công cộng bằng hoststệp cục bộ của mình ) thì bạn ' Sẽ lấy lại không có địa chỉ IP (nó sẽ chỉ trả về tên máy chủ) hoặc thậm chí tệ hơn là nó sẽ trả về địa chỉ sai được chỉ định trong các bản ghi DNS công cộng nếu tồn tại hoặc nếu có ký tự đại diện cho miền.

Tùy thuộc vào tình huống, bạn cũng có thể thử cách tiếp cận thứ ba bằng cách làm như sau:

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

Điều này có những sai sót riêng (phụ thuộc vào một trang web cụ thể của bên thứ ba và có thể có các cài đặt mạng định tuyến các kết nối ra ngoài thông qua một máy chủ hoặc proxy khác) và giống như gethostbynamenó có thể chậm. Thành thật mà nói, tôi không chắc cách tiếp cận nào sẽ chính xác thường xuyên nhất, nhưng bài học cần rút ra là các tình huống / cấu hình cụ thể sẽ dẫn đến kết quả đầu ra không chính xác cho tất cả các cách tiếp cận này ... vì vậy nếu có thể hãy xác minh rằng cách tiếp cận bạn đang sử dụng đang trả về các giá trị bạn mong đợi.


9

Đây là những gì bạn có thể sử dụng như một sự thích ứng của các ví dụ trên mà không cần lo lắng về việc cài đặt curl trên máy chủ của bạn.

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

Nếu bạn đang sử dụng PHP trong bash shell, bạn có thể sử dụng:

$server_name=exec('hostname');

Bởi vì $_SERVER[] SERVER_ADDR, HTTP_HOSTSERVER_NAMEkhông được thiết lập.


4

Tất cả các câu trả lời trước đó đều cho $ _SERVER ['SERVER_ADDR']. Điều này sẽ không hoạt động trên một số cài đặt IIS. Nếu bạn muốn điều này hoạt động trên IIS, hãy sử dụng như sau:

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

2

Tôi thấy điều này phù hợp với tôi: GetHostByName ("");

Chạy XAMPP v1.7.1 trên Windows 7 chạy máy chủ web Apache. Thật không may, nó chỉ cung cấp địa chỉ IP cổng của tôi.


2

Tôi vừa tạo một tập lệnh đơn giản sẽ trả lại $ _SERVER ['REMOTE_ADDR'] và $ _SERVER ['SERVER_ADDR'] trong IIS để bạn không phải thay đổi mọi biến. Chỉ cần dán văn bản này vào tệp php của bạn được bao gồm trong mọi trang.

/** 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

Bạn có thể phải sử dụng $HTTP_SERVER_VARS['server_ADDR']nếu bạn không nhận được bất kỳ điều gì từ các câu trả lời trên và nếu bạn đang sử dụng phiên bản PHP cũ hơn


0

Kiểm tra mảng $ _SERVER

echo $_SERVER['SERVER_ADDR'];

1
Điều đó không tìm thấy "IP thực", nó tìm thấy các tiêu đề HTTP tùy ý, chưa được xác minh mà bất kỳ ai cũng có thể đặt và bất kỳ ai cũng có thể sử dụng để giả mạo IP của họ nếu bạn thích chúng. Nếu máy khách đứng sau proxy thì cũng vậy, đừng tin tưởng bất kỳ tiêu đề HTTP nào. Điều này cũng không phù hợp với câu hỏi chút nào.
lừa đảo

2
Không thể hình dung câu trả lời này không phù hợp với câu hỏi như thế nào. Câu hỏi là: "Làm cách nào để xác định địa chỉ IP của máy chủ trong PHP?". OP nên học cách hỏi tốt hơn, hoặc bạn nên học cách đọc câu hỏi. Bên cạnh đó, nếu máy khách đứng sau proxy, bạn vẫn gặp khó khăn cho dù bạn có thử gì từ phía máy chủ. Một tình huống hoàn toàn khác là khi máy chủ chạy sau proxy, vì bạn có thể kiểm tra bằng tiêu đề X-FORWARDED-FOR.
Luis Masuelli

@deceze $_SERVER["SERVER_ADDR"]không liên quan gì đến tiêu đề HTTP. Điều này được lấp đầy bởi phần mềm máy chủ, tất cả những thứ liên quan đến HTTP trong $ _SERVER đều có tiền tố là HTTP_. php.net/manual/en/reserved.variables.server.php
poncha

@poncha Nhận xét của tôi liên quan đến bản sửa đổi ban đầu của bài đăng này.
mười hai

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.