PHP วิธีรับ IP ในระบบของระบบ


96

ฉันต้องการรับ IP ภายในของคอมพิวเตอร์เช่น 192 * .... เป็นไปได้ด้วย PHP หรือไม่?

ฉันต้องการที่อยู่ IP ของระบบที่รันสคริปต์ แต่ฉันไม่ต้องการ IP ภายนอกฉันต้องการที่อยู่การ์ดเครือข่ายในพื้นที่ของเขา

คำตอบ:


112

จาก CLI

PHP <5.3.0

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

PHP> = 5.3.0

$localIP = getHostByName(getHostName());


2
นี่เป็นวิธีแก้ปัญหาที่เหมาะกับฉันและหลีกเลี่ยงการเรียกเชลล์คำสั่งระบบปฏิบัติการและสิ่งต่างๆทุกประเภทที่สามารถเปิดช่องโหว่ด้านความปลอดภัยหรือทำให้เกิดปัญหาแปลก ๆ ในภายหลัง
Dario Fumagalli

1
การตอบสนองที่ดีที่สุดมักมาพร้อมกับความเรียบง่าย เช่นนั้น.
m3nda

1
@ andras.tim ฉันชอบคำตอบง่ายๆ แต่เมื่อฉันเรียกใช้สคริปต์ของคุณมันไม่ส่งคืนที่อยู่ IP ของเครื่องของฉัน แต่จะส่งคืนที่อยู่ IP ที่ใช้ในเครื่องเสมือนของฉัน .. จะมีปัญหาอย่างไร
Scarl

โปรดทราบว่าวิธีนี้อาศัย DNS ในการแก้ไขสิ่งที่ชื่อโฮสต์ของระบบตั้งค่าเป็นอย่างถูกต้อง ซึ่งจะไม่เป็นเช่นนั้นเสมอไป
Justin McAleer

3
ในสภาพแวดล้อมการโฮสต์บนคลาวด์สิ่งนี้อาจไม่ส่งคืนผลลัพธ์ที่คาดหวัง เพราะทุกโฮสต์มีมากกว่า 2 IP
UnixAgain

60
$_SERVER['SERVER_ADDR']

13
คำชี้แจง: คอมพิวเตอร์สามารถมีที่อยู่ IP ได้หลายแห่ง ตัวแปรนี้เป็น HTTP เท่านั้นและมีที่อยู่ IP ที่โฮสต์เสมือนทำงานอยู่ เนื่องจากคำถามคลุมเครือเพียงใดจึงยากที่จะบอกว่านี่เป็นคำตอบที่คาดหวังหรือไม่
ÁlvaroGonzález

ฉันคิดว่านี่ถูกต้องเพราะคุณต้องการ ip แบบ asigned เสมออันที่ตอบสนองคุณ หากไม่เป็นเช่นนั้นคุณต้องใช้ asnwers ของ @ andras.tim เพราะจะบอกให้คุณทราบถึง ip หลักของระบบ
m3nda

นี่คือสิ่งที่ฉันต้องการอย่างแท้จริงเนื่องจากเซิร์ฟเวอร์ของฉันอยู่หลังตัวจัดสรรภาระงานจึงgetHostNameไม่ส่งคืนชื่อโดเมนของไซต์
Yep_It's_Me

สิ่งนี้จะไม่ได้ผลหากคุณกำลังทำงานในตู้คอนเทนเนอร์นักเทียบท่า
Freedo

31

นี่เป็นโพสต์เก่า แต่ใช้สิ่งนี้:

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

ตัวอย่างเช่น:

die( getLocalIp() );

พบในเว็บไซต์อื่นอย่าลบคำสั่งตัดออกเพราะมิฉะนั้นคุณจะได้รับชื่อคอมพิวเตอร์

BACKTICKS (เครื่องหมายคำพูดพิเศษ): ทำงานได้เนื่องจาก PHP จะพยายามเรียกใช้สิ่งที่อยู่ระหว่าง "เครื่องหมายคำพูดพิเศษ" (backticks) เป็นคำสั่งเชลล์และส่งกลับผลลัพธ์ที่ได้

gethostbyname(trim(`hostname`));

มีความคล้ายคลึงกันมาก (แต่มีประสิทธิภาพมากกว่า) มากกว่าการทำ:

$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: เนื่องจากคำพูดพิเศษเมื่อคุณใช้เครื่องหมายคำพูดปกติมันไม่ได้ผลด้วยเหตุผลบางประการและเมื่อคุณลบคำสั่งตัดมันก็ไม่ได้ผล ฉันรู้ว่ามันฟังดูแปลก ๆ ไม่ดีที่จะลงคะแนนคำตอบสำหรับสิ่งนั้น อ่านคำตอบ
Codebeat

2
Backticks (`) เรียกว่าตัวดำเนินการใน PHP สิ่งที่คุณทำในบล็อกโค้ดแรกเกือบจะเหมือนกับคำสั่ง exec ดูPHP: Execution Operators - Manual
Christiaan

2
ไม่ใช่ความคิดที่ดีที่สุดจริงๆ เป็นไปได้และถูกต้องสำหรับgethostbynameการส่งคืน IP แบบย้อนกลับ (เช่น 127.0.0.1) สำหรับเครื่องโฮสต์
ไม่มีใคร

2
สิ่งนี้ช่วยฉันได้มากฉันคิดว่าจะมีฟังก์ชัน PHP ง่ายๆเช่น$ _SERVER ['REMOTE_ADDR']; ซึ่งไม่ได้ผล แต่วิธีนี้ใช้ได้ผลสำหรับฉัน !!!
Pini Cheyni

24

ลองใช้สิ่งนี้ (หากเซิร์ฟเวอร์ของคุณเป็น Linux):

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

9
ไม่ถูกต้องอย่างแน่นอน ไม่มีการรับประกันว่าeth0เป็นอินเทอร์เฟซที่เหมาะสม
ไม่มีใคร

ขอบคุณสิ่งนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน ความสามารถในการตั้งค่าอินเทอร์เฟซช่วยได้!
Rahim Khoja

ในกรณีของฉัน (IP ท้องถิ่นในเครือข่ายท้องถิ่น WiFi) ฉันต้องระบุwlan0แทนeth0และแทนที่'inet addr:'ด้วย'inet adr:'อาจเนื่องมาจากภาษาที่ใช้ในระบบของฉัน (fr_FR) นอกเหนือจากนั้นคำตอบนี้เป็นทางออกที่ฉันกำลังมองหา ขอบคุณ!
Niavlys

ใช้งานได้ดี'inet adr:'ในเทอร์มินัลของฉัน (ภาษาฝรั่งเศส) แต่ในสคริปต์ PHP 'inet addr:'เป็นค่าที่ถูกต้อง (ฉันเดาว่าภาษาอังกฤษ)
Niavlys

22

ที่อยู่ IP ภายนอกเริ่มต้นของเครื่องท้องถิ่นสามารถรับได้ดังนี้:

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

มันทำงานอย่างไร:

เนื่องจากนี่คือ UDP socket_connectอย่าออกไปบนเครือข่าย กำหนดเฉพาะที่อยู่ในเครื่องและพอร์ตให้กับซ็อกเก็ต สิ่งนี้ทำให้เราได้รับที่อยู่ในท้องถิ่น

โซลูชันนี้ทำงานได้โดยไม่มีการรับส่งข้อมูลเครือข่าย DNS หรือการดำเนินการคำสั่ง

อาจใช้ไม่ได้หากไม่มีเส้นทางไปยัง8.8.8.8(เช่นคุณไม่มีการเชื่อมต่ออินเทอร์เน็ต)


3
คำตอบนี้ดีกว่าคำตอบอื่น ๆ การพึ่งพาอาร์เรย์ $ _SERVER ขึ้นอยู่กับสิ่งนี้ที่ทำงานภายใต้ Apache แนวคิดนี้ใช้ได้กับงาน cron ด้วย ฉันใช้มันเพื่อเรียกใช้ฟังก์ชันบางอย่างเท่านั้นหากเซิร์ฟเวอร์กำลังทำงานบน staging หรือ LAN ที่ใช้งานจริง สมบูรณ์แบบ!
ต่อ

นี่คือคำตอบที่สง่างาม ฉันปรับใช้ในสคริปต์จัดการคอนเทนเนอร์นักเทียบท่าเพื่อรับ ip ของโฮสต์ของฉันบนเครือข่ายนักเทียบท่า:$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP); socket_connect($sock, $this->getDockerMachineIp(), 53);
FatherShawn

ฉันเดาว่าพกพาสะดวกกว่า นอกจากนี้สิ่งสำคัญคือต้องกล่าวถึงsocketsโมดูลควรติดตั้งและเปิดใช้งานบน PHP
Fabio Montefuscolo

ใช่ขอบคุณมาก @Arnaud Le Blanc มันมีประโยชน์มากสำหรับฉันฉันได้รับที่อยู่ IP ของฉันด้วยเทคนิคนี้
Abid Ali

15

ขึ้นอยู่กับความหมายของท้องถิ่น:

หากในพื้นที่คุณหมายถึงที่อยู่ของเซิร์ฟเวอร์ / ระบบที่เรียกใช้โค้ด PHP ก็ยังมีสองช่องทางในการหารือ ถ้า PHP $_SERVER['SERVER_ADDR']จะถูกเรียกใช้ผ่านเว็บเซิร์ฟเวอร์แล้วคุณจะได้รับที่อยู่เซิร์ฟเวอร์โดยการอ่าน หาก PHP ถูกเรียกใช้ผ่านอินเทอร์เฟซบรรทัดคำสั่งคุณอาจต้องดำเนินการเชลล์ipconfig(Windows) / ifconfig(* nix) และแยกแอดเดรสออก

หากตามท้องถิ่นคุณหมายถึงที่อยู่ระยะไกลของผู้เยี่ยมชมเว็บไซต์ แต่ไม่ใช่ที่อยู่ IP ภายนอกของพวกเขา (เนื่องจากคุณพูดเฉพาะ 192. *) แสดงว่าคุณโชคไม่ดี จุดรวมของการกำหนดเส้นทาง NAT คือการซ่อนที่อยู่นั้น คุณไม่สามารถระบุที่อยู่ภายในของคอมพิวเตอร์แต่ละเครื่องหลังที่อยู่ IP ได้ แต่มีกลเม็ดบางอย่าง (ตัวแทนผู้ใช้อาจเป็นที่อยู่ mac) ที่สามารถช่วยแยกความแตกต่างได้หากมีคอมพิวเตอร์หลายเครื่องเข้าถึงจาก IP เดียวกัน


1
และสุดท้าย แต่ไม่ท้ายสุด ipconfig / ifconfig มักจะส่งคืนที่อยู่ IP หลายรายการเนื่องจากปกติคอมพิวเตอร์ไม่มีที่อยู่เดียว คำตอบที่ดี
ÁlvaroGonzález

ใช่ประเด็นทั้งหมดของ NAT คือการซ่อน IP ในเครื่องตอนนี้ตรวจสอบwhatismyip.comพวกเขารู้ที่อยู่ IP ภายในของคุณและเปิดเว็บไซต์นี้โดยใช้มือถือของคุณพวกเขารู้จักที่อยู่ IP ในเครื่องของคุณด้วย แก้ไข: ฉันใช้ JioFi Router บนมือถือฉันใช้ข้อมูลมือถือบน ROM Android 9 AOSP
Rishabh

10

ชื่อโฮสต์ (1) สามารถบอกที่อยู่ IP: hostname --ip-addressหรือตามที่มนุษย์กล่าวว่าควรใช้hostname --all-ip-addresses


6

คุณสามารถลองเป็นผู้ใช้ทั่วไปใน CLI บนโฮสต์ 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);

เอาท์พุต:

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', )ฉันได้รับสิ่งนี้ ฉันเพิ่มรหัสนี้ในไฟล์ php
หมวกฟาง

คำตอบที่ดีขอบคุณ split()ฟังก์ชันถูกเลิกใช้งานเมื่อ PHP 5.3.0 ดังนั้นแนะนำให้ใช้explode()แทน
ธนู


4

มันง่ายมากและคำตอบข้างต้นเป็นสิ่งที่ซับซ้อน เพียงแค่คุณรับที่อยู่ IP ในพื้นที่และสาธารณะโดยใช้วิธีนี้

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

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

?>

2

มันเป็นเรื่องง่าย คุณสามารถรับชื่อโฮสต์โดยใช้รหัสง่ายๆนี้

$ip = getHostByName(getHostName());

หรือคุณสามารถใช้$_SERVER['HTTP_HOST']เพื่อรับชื่อโฮสต์


1

ฉันตอบคำถามนี้สำหรับ php ฝั่งเซิร์ฟเวอร์ (ทำงานจากเทอร์มินัล Linux)

ฉันระเบิด 'ifconfig' และตัดทอนเป็นที่อยู่ IP

นี่คือ:

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

และแน่นอนเปลี่ยน 'wlan0' เป็นอุปกรณ์เครือข่ายที่คุณต้องการ

ผลลัพธ์ของฉันคือ:

192.168.1.5

0

หากคุณอยู่ในสภาพแวดล้อมการพัฒนาบน OS X เชื่อมต่อผ่าน Wifi:

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


-4
$_SERVER['REMOTE_ADDR']
  • PHP_SELF ส่งคืนชื่อไฟล์ของสคริปต์ปัจจุบันด้วยพา ธ ที่สัมพันธ์กับรูท

  • SERVER_PROTOCOL ส่งคืนชื่อและการแก้ไขของโปรโตคอลที่ร้องขอเพจ

  • REQUEST_METHOD ส่งคืนวิธีการร้องขอที่ใช้เพื่อเข้าถึงเพจ

  • DOCUMENT_ROOT ส่งคืนไดเร็กทอรีรากที่สคริปต์ปัจจุบันกำลังเรียกใช้


ทั้งหมดเป็นความจริง แต่ทั้งหมดไม่เกี่ยวข้องกับคำถามที่ถาม -1.
Mark Amery

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.