Sometimes when using $_SERVER['HTTP_X_FORWARDED_FOR'] OR $_SERVER['REMOTE_ADDR'] more than 1 IP address is returned, for example '155.240.132.261, 196.250.25.120'. When this string is passed as an argument for gethostbyaddr() PHP gives the following error: Warning: Address is not a valid IPv4 or IPv6 address in...
To work around this I use the following code to extract the first IP address from the string and discard the rest. (If you wish to use the other IPs they will be in the other elements of the $ips array).
if (strstr($remoteIP, ', ')) {
$ips = explode(', ', $remoteIP);
$remoteIP = $ips[0];
}
Hope this helps someone :)
PHP.mk документација
gethostbyaddr
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
Патека
function.gethostbyaddr.php
Локална патека за оваа страница.
Извор
php.net/manual/en
Оригиналниот HTML се реупотребува и локално се стилизира.
Режим
Прокси + превод во позадина
Кодовите, табелите и белешките остануваат читливи во истиот тек.
Референца
function.gethostbyaddr.php
gethostbyaddr
Референца за `function.gethostbyaddr.php` со подобрена типографија и навигација.
gethostbyaddr
(PHP 4, PHP 5, PHP 7, PHP 8)
gethostbyaddr — Добијте го името на Интернет домаќинот што одговара на дадена IP адреса
= NULL
Враќа име на домаќин на Интернет домаќинот специфициран од
ip.
Параметри
ip-
IP адресата на домаќинот.
Вратени вредности
Враќа име на домаќин при успех, непроменето ip
при неуспех, или false при погрешно внесување.
Примери
Пример #1 Едноставен gethostbyaddr() example
<?php
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
echo $hostname;
?>Види Исто така
- gethostbyname() - Добијте ја IPv4 адресата што одговара на дадено име на Интернет домаќин
- gethostbynamel() - Добијте листа на IPv4 адреси што одговараат на дадено име на Интернет домаќин
Белешки од корисници 4 белешки
lukevb_at_iafrica.com ¶
пред 23 години
king dot macro at gmail dot com ¶
21 години пред
The problem of broken DNS servers was causing me a problem because i had a page for user statistics that required around 20 reverse dns lookups to be done, and even as many as 5/6 of them being broken was causing a huge delay in loading the page. so i wrote a function that uses a UDP socket to talk directly to the DNS server (instead of going via the normal gethostbyaddr function) this let me set a timeout.
The only requirement is that your DNS server must be able to do recursive lookups, it wont go to other DNS servers if its told to... and of course you need to know your DNS servers IP address :-)
<?
function gethostbyaddr_timeout($ip, $dns, $timeout=1000)
{
// random transaction number (for routers etc to get the reply back)
$data = rand(0, 99);
// trim it to 2 bytes
$data = substr($data, 0, 2);
// request header
$data .= "\1\0\0\1\0\0\0\0\0\0";
// split IP up
$bits = explode(".", $ip);
// error checking
if (count($bits) != 4) return "ERROR";
// there is probably a better way to do this bit...
// loop through each segment
for ($x=3; $x>=0; $x--)
{
// needs a byte to indicate the length of each segment of the request
switch (strlen($bits[$x]))
{
case 1: // 1 byte long segment
$data .= "\1"; break;
case 2: // 2 byte long segment
$data .= "\2"; break;
case 3: // 3 byte long segment
$data .= "\3"; break;
default: // segment is too big, invalid IP
return "INVALID";
}
// and the segment itself
$data .= $bits[$x];
}
// and the final bit of the request
$data .= "\7in-addr\4arpa\0\0\x0C\0\1";
// create UDP socket
$handle = @fsockopen("udp://$dns", 53);
// send our request (and store request size so we can cheat later)
$requestsize=@fwrite($handle, $data);
@socket_set_timeout($handle, $timeout - $timeout%1000, $timeout%1000);
// hope we get a reply
$response = @fread($handle, 1000);
@fclose($handle);
if ($response == "")
return $ip;
// find the response type
$type = @unpack("s", substr($response, $requestsize+2));
if ($type[1] == 0x0C00) // answer
{
// set up our variables
$host="";
$len = 0;
// set our pointer at the beginning of the hostname
// uses the request size from earlier rather than work it out
$position=$requestsize+12;
// reconstruct hostname
do
{
// get segment size
$len = unpack("c", substr($response, $position));
// null terminated string, so length 0 = finished
if ($len[1] == 0)
// return the hostname, without the trailing .
return substr($host, 0, strlen($host) -1);
// add segment to our host
$host .= substr($response, $position+1, $len[1]) . ".";
// move pointer on to the next segment
$position += $len[1] + 1;
}
while ($len != 0);
// error - return the hostname we constructed (without the . on the end)
return $ip;
}
return $ip;
}
?>
This could be expanded quite a bit and improved but it works and i've seen quite a few people trying various methods to achieve something like this so i decided to post it here. on most servers it should also be more efficient than other methods such as calling nslookup because it doesn't need to run external programs
Note: I'm more a C person than a PHP person, so just ignore it if anything hasn't been done the *recomended* way :-)
tom ¶
20 години пред
Be careful with the usage of this function - it will slow down a server to a crawl if called a lot and the slowness won't be reflected in any of the obvious places, like CPU usage, apache requests, SQL etc. When you do use it make a special note of where!
Винсент ¶
пред 7 години
I discovered that gethostbyaddr sometimes returned the same host name with some uppercase letters in it and sometimes with all lowercase letters.
example:
d54c34fa1.access.example.com
d54C34FA1.access.example.com
This is probably not the fault of gethostbyaddr, but this can be a problem when comparing or storing, because it will give two entries instead of one.
A simple solution to this is to use strtolower on the host name.