2012-03-28 83 views
9

我正在開發一個PHP應用程序,它只能在本地的企業網絡上運行。應用程序將使用自定義安裝程序安裝到服務器,就像我們使用Stunnix高級Web服務器所做的一樣。如何獲取使用PHP的服務器的本地IP地址?

隨着使得應用更加人性化,我打算以顯示服務器的本地IP所以這是網絡中的其他計算機非常容易通過只是在輸入這個IP來訪問應用程序的一部分,其地址欄。

問題是我無法獲得服務器的本地IP的

我已經試過

SERVER_NAME(只顯示127.0.0.1)

REMOTE_ADDR(客戶端顯示外部IP)

SERVER_ADDR顯示正確的IP,但它這樣做只是如果我從使用IP的客戶端訪問它,這完全違背了它的目的。

我只想顯示本地IP服務器直接從服務器通過http://localhost本身訪問。

我有點確定這是不可能的。但如果是這樣,請幫忙。

編輯

我開發一個跨平臺的PHP服務器應用程序之類的話。我們將Apache,PHP安裝程序和SQlite數據庫作爲一鍵安裝程序與我們的PHP應用程序捆綁在一起,以儘可能方便用戶使用。任何人都可以在運行Windows,Mac或Linux的計算機上部署它。安裝完成後,當用戶在服務器上打開應用程序時,他可以看到的IP地址[local ip]和可用於連接到此服務器的端口。該應用程序只能在本地網絡上運行,而不能在互聯網上運行。

它應該顯示本地IP,就像名爲Air Droid的Android應用程序一樣。 截圖:https://lh3.ggpht.com/PmLopRm-Lj9WTnzm2MBI-bTbCLopAyqtd4C_4nvyDwLg8X0QwDbBbEREdWGHG5xku4s

回答

12

的問題。任何給定的計算機都可以有多個與多個網卡關聯的IP地址。其中一些/全部/全部都沒有可用的Web服務。對於您要求的操作系統問題,可能沒有單一的答案。

如果你的服務器有一個簡單的單一的IP地址配置,那麼你可能最好是硬編碼 - 這是最簡單的選擇。如果要動態地確定它,這裏是信息的幾個位,你會希望找到有用的:

  • $_SERVER['HTTP_HOST']包含已輸入到瀏覽器的地址欄,以訪問該網頁的地址。如果您通過在瀏覽器中輸入(例如http://192.168.0.1/index.php)訪問該頁面,則$_SERVER['HTTP_HOST']將爲192.168.0.1
  • 如果您使用DNS名稱訪問該頁面,gethostbyname($_SERVER['HTTP_HOST']);會將該DNS名稱轉換爲IP地址。
  • $_SERVER['SERVER_NAME']包含已在Web服務器配置中配置的名稱,因爲它是服務器名稱。如果你打算使用這個,你可能只需要在PHP中對它進行硬編碼。
  • $_SERVER['SERVER_ADDR']將包含服務器主IP地址的操作系統。這可能是也可能不是用於訪問該頁面的IP地址,並且可能是也可能不是與Web服務器綁定的IP地址。它很大程度上取決於操作系統和服務器配置如果服務器有一個IP地址,這可能是可能是一個安全的賭注,雖然有些情況下這可能包含127.0.0.1

缺點是沒有100%可靠的方法來確定Web服務器的有效IP地址,而不檢查發送到Web服務器的信息以生成頁面你正在創建,就像你說的totally defeats its purpose

+0

感謝您的建議。這真的很有道理。如果服務器連接到2個網絡(例如連接到以太網和WiFi的筆記本電腦),我同意選擇正確的網絡和IP將非常不可靠。我沒有這樣想過。 順便說一句,讓用戶自己找到他的IP地址,使得應用程序不太適合n00b。 :( – ajaybc 2012-03-28 10:58:06

+1

@ajaybc這就是DNS的用途......如果它都是本地的,你可以使用機器名稱訪問網絡,如果它通過互聯網,在你的IP上指向一個域/子域的A記錄;-) – DaveRandom 2012-03-28 11:05:13

0

嘗試:

<?php gethostbyname($_SERVER['SERVER_NAME']);

編輯:

有點哈克,但它似乎工作:

<?php 
$str = file_get_contents("http://ip6.me/"); 
$pattern = "#\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b#"; 
preg_match($pattern, $str, $matches); 
print_r($matches[0]); 

但這種依靠第三個網站。 。

+0

對不起,這不起作用。因爲它顯示** 127.0.0.1 **。我想要的是一個IP,如** 192.168.1.6 **,這是服務器的本地IP – ajaybc 2012-03-28 10:40:32

+0

也試過了你的編輯。但它只是獲得服務器的**外部ip **。我需要的是服務器的**本地ip **。謝謝 – ajaybc 2012-03-28 10:54:33

0

你可以在命令行看看所有可用的信息:你在這裏的是,這不是一個靜態的資料片

print_r($_SERVER, 1); 
2

我也很確定這是不可能的。或者如果可能的話,結果將不可靠。

服務器可能有多個IP地址。此外,服務器上用於HTTP的IP地址可能不是用於從別處到達服務器的IP地址(如果涉及反向代理或NAT)。 SERVER_ADDR變量顯示用於調用PHP腳本的IP地址;這些信息是從Web服務器傳遞來的,所以它不會幫助獨立運行的PHP腳本(即從shell運行)。

讓我們來看另一種方式。你想解決什麼問題?也就是說,你爲什麼需要服務器的本地IP?讓我們看看最初的問題,看看是否有其他可行的解決方案,而不是獲得幫助來實現無效的解決方案。

我應該指出的是,根據您的操作系統上,有很多方法可以得到通過解析一個shell命令的輸出像ifconfig -aip addr分配給不同的接口的IP地址列表。但我不知道你的操作系統,所以我不能建議這對你有什麼用。

$h = popen("ip addr | awk '/inet/{print$2}'"); 
$ip_list = array(); 
while ($ip_list[] = fread($h, 15)) { } 
pclose($h); 

你可以把更多的邏輯到PHP,以避免在管道使用awk,但你的想法。

+0

我我正在開發一個跨平臺PHP服務器應用程序的東西。我們將Apache,PHP安裝程序和SQlite數據庫作爲一鍵安裝程序與我們的PHP應用程序捆綁在一起,以儘可能方便用戶使用。任何人都可以在他們的電腦上部署它 – ajaybc 2012-03-28 11:05:35

+0

好吧,如果您甚至不知道操作系統的用戶將運行您的應用程序,或者安全模式是否打開,那麼shell工具將無助於此。正如我所說,如果您可以描述您嘗試解決的問題而不是您提出的解決方案,那麼我們可以幫助解決該問題,而不是幫助實施解決方案。 – ghoti 2012-03-28 11:07:39

+0

請在問題中查看我的編輯。謝謝 – ajaybc 2012-03-28 11:12:46

3

解決方案:

硬編碼在PHP
  1. (在安裝時應該在腳本編輯這個)
  2. 設置Apache中的環境變量,這樣可以通過PHP(在安裝時應該加上這個被訪問apache的配置)
  3. 解析ifconfig -lipconfig -a輸出確定機器的網絡接口的IP地址,排除迴環接口。在最好的情況下,你會收到一個IP地址 - 這將是你需要的地址,加入$_SERVER['SERVER_PORT']。如果您將獲得多個IP地址 - 您可以嘗試全部查詢它們以檢查它們是否回答$_SERVER['SERVER_PORT']上的HTTP請求。如果機器在不同IP地址上運行多個HTTP服務器,您也可以將/ping.php文件與某種echo "my application";相關聯,以確定您的IP地址。
+0

請參閱我編輯的問題 – ajaybc 2012-03-28 11:13:10

+0

好吧,我會用第三部分。但是PHP應該能夠執行'exec()'並使用不同的解析算法,具體取決於操作系統 - windows的ipconfig -a,unix的ifconfig -l等等。 – 2012-03-28 11:26:42

2

如果你想獲得蘭IP地址192.168.x.x您可以使用下面的代碼:

我使用這個,完美滿足了我的要求。 (只在Windows機器上測試)

function getLocalIP(){ 
    exec("ipconfig /all", $output); 
     foreach($output as $line){ 
      if (preg_match("/(.*)IPv4 Address(.*)/", $line)){ 
       $ip = $line; 
       $ip = str_replace("IPv4 Address. . . . . . . . . . . :","",$ip); 
       $ip = str_replace("(Preferred)","",$ip); 
      } 
     } 
    return $ip; 
} 

echo $ip = getLocalIP(); //This will return: 192.168.x.x (Your Local IP) 

希望這有助於。 =)

+2

ipconfig是僅Windows。不是很有用。 – kodeart 2014-04-12 01:57:59

0

嘗試使用「ifconfig en1 inet」命令。

print_r(exec("ifconfig en1 inet"));

輸出: - INET 192.168。 netmask 0xffffff00 broadcast 192.168。*。255

+0

ifconfig不適用於Windows – 2015-10-20 14:26:30