Neither of the most up-voted answers will reliably return the server's public address. Generally $_SERVER['SERVER_ADDR']
will be correct, but if you're accessing the server via a VPN it will likely return the internal network address rather than a public address, and even when not on the same network some configurations will will simply be blank or have some other specified value.
Likewise, there are scenarios where $host= gethostname[]; $ip = gethostbyname[$host];
won't return the correct values because it's relying on
on both DNS [either internally configured or external records] and the server's hostname settings to extrapolate the server's IP address. Both of these steps are potentially faulty. For instance, if the hostname of the server is formatted like a domain name [i.e. HOSTNAME=yahoo.com
] then [at least on my php5.4/Centos6 setup] gethostbyname
will skip straight to finding Yahoo.com's address rather than the local server's.
Furthermore, because gethostbyname
falls back on public DNS records a testing server with
unpublished or incorrect public DNS records [for instance, you're accessing the server by localhost
or IP address, or if you're overriding public DNS using your local hosts
file] then you'll get back either no IP address [it will just return the hostname] or even worse it will return the wrong address specified in the public DNS records if one exists or if there's a wildcard for the domain.
Depending on the situation, you can also try a third approach by doing something like this:
$external_ip = exec['curl //ipecho.net/plain; echo'];
This has its own flaws [relies on a specific third-party site, and there could be network settings that route outbound connections through a different host or proxy] and like gethostbyname
it can be slow. I'm honestly not sure which approach will be correct most often, but the lesson to take to heart is that specific scenarios/configurations will result in incorrect outputs for all of these approaches... so if possible verify that the approach you're using is returning the values you expect.
Many times we need to get the IP address of the visitor for different purposes. It is very easy to collect the IP address in PHP. PHP provides PHP $_SERVER variable to get the user IP address easily. We can track the activities of the visitor on the website for the security purpose, or we can know that who uses my website and many more.
The simplest way to collect the visitor IP address in PHP is the REMOTE_ADDR. Pass the 'REMOTE_ADDR' in PHP $_SERVER variable. It will return the IP address of the visitor who is currently viewing the webpage.
Note: We can display this IP address on the webpage and also even can store in database for many other purposes such as - for security, redirecting a visitor to another site, blocking/banning the visitor.
Get the IP address of the website
$_SERVER['REMOTE_ADDR'] - It returns the IP address of the user currently visiting the webpage.
For example
Output
But sometimes the REMOTE_ADDR does not return the IP address of the client, and the main reason behind is to use the proxy. In such type of situation, we will try another way to get the real IP address of the user in PHP.
Output
Flowchart:
The flowchart for the above program will be like given below.
Get the IP address of the website
We can also get the IP address of any website by its URL. Pass the URL of the website inside gethostbyname[] function.
For example
Output
IP Address of Google is - 172.217.166.4 IP Address of javaTpoint is - 95.216.57.234
[PHP 4, PHP 5, PHP 7, PHP 8]
gethostbyaddr — Get the Internet host name corresponding to a given IP address
Description
gethostbyaddr[string $ip
]: string|false
Parameters
ip
The host IP address.
Return Values
Returns the host name on success, the unmodified ip
on failure, or false
on malformed input.
Examples
Example #1 A simple gethostbyaddr[] example
See Also
- gethostbyname[] - Get the IPv4 address corresponding to a given Internet host name
- gethostbynamel[] - Get a list of IPv4 addresses corresponding to a given Internet host name
lukevb_at_iafrica.com ¶
19 years ago
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 :]
king dot macro at gmail dot com ¶
17 years ago
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 :-]
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 :-]
Vincent ¶
3 years ago
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.
Matt AKA Junkie ¶
18 years ago
Since my little ISP thing isn't globally acceptable, here's an update.
phalkon at nospam dot home dot com ¶
21 years ago
Be cautious when looking up many hostnames. If your DNS server is slow to respond, you may have to pump up your Max execution time for your scripts, otherwise, it will timeout. I found that even 3 unresolvable hosts can cause a 30 second delay in processing.
tom ¶
16 years ago
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!
oryan at zareste dot com ¶
16 years ago
If all else fails, but you have shell access, Unix/Linux servers can use this for a timeout response:
shell_exec['host -W 2 0.0.0.0'];
Where 0.0.0.0 is of course the IP, and '2' is the number of seconds for the timeout. This returns a more detailed string of info, with some additional text which might vary depending on the system, so if you want a string with the hostname and nothing else, you'll have to do some substring cutting. There should be an equivalent of 'host' for Windows users to execute, but it isn't my platform.
Anonymous ¶
1 year ago
There is 1 bug in gethostbyaddr_timeout[] function that king dot macro at gmail dot com posted in the most important line of all, setting the timeout with socket_set_timeout[]. It should be:
@socket_set_timeout[$handle, intdiv[$timeout_ms, 1000], $timeout_ms % 1000];
I'd also make the $dns parameter last and optional and parse it from /etc/resolve.conf [or something else] if not given.
abe at abe2k dot net ¶
19 years ago
gethostbyaddr[] doesn't seem to be able to resolve ip6.int
[ipv6] adresses, so I made a function that can, and works
just like the normal gethostbyaddr[].
You need dig and ipv6calc, dig should come with most
distributions, if not, install bind from //www.isc.org.
ipv6calc can be found at //www.bieringer.de/linux/IPv6/ipv6calc/index.html.
function gethostbyaddr6[$ip6] {
$ipv6calc = "/bin/ipv6calc";
$dig = "/usr/bin/dig";
$file = popen[$ipv6calc." --in ipv6addr --out revnibbles.int ".escapeshellarg[$ip6], r];
$ip = fread[$file, 128];
pclose[$file];
if [[substr[$ip, 0, 5] == "Error"] || [!$ip]] return "Address is not a valid IPv6 address";
$file = popen[$dig." ptr ".$ip, r];
while [!feof [$file]] {
$buffer = fgets[$file, 128];
if [substr[$buffer, 0, 1] == ";"] continue;
$buffer = explode[" ", $buffer];
if [$buffer[3] == "PTR"] {
$host = substr[trim[$buffer[4]], 0, -1];
pclose[$file];
return $host;
}
}
pclose[$file];
return $ip6;
}
echo gethostbyaddr6[$_SERVER[REMOTE_ADDR]];
elpmille at indiana dot edu ¶
20 years ago
I previously used something very similar to what posted but found it to be quite tedious for getting the 'nicehost'. This method below is a lot cleaner, and it also works for numeric addresses.
function nicehost[$host] {
if [ereg['^[[0-9]{1,3}\.]{3}[0-9]{1,3}$', $host]] {
return[ereg_replace['\.[0-9]{1,3}$', '.*', $host]];
} else {
return[ereg_replace['^.{' . strpos[$host, '.'] . '}', '*', $host]];
}
}
Stuart Macdonald ¶
12 years ago
Here's a simple function that uses Dig to obtain the hostname for a given IP address. If no hostname can be found it returns the IP again.
Works only on linux / unix, or whatever other platform with dig installed as a command line utility.
robbakAgmail_com ¶
14 years ago
it appears that gethostbyname[] fails if the domain name contains unicode. Example:
$ host 10.10.10.128
128.10.10.10.in-addr.arpa domain name pointer PC-de-S\130bastien.flexi.robbak.com.
$ php
10.10.10.128
gethostbyaddr is listed as unicode compatable in version 6, so a fix may be in the works.
james at trnxs dot net ¶
11 years ago
You should be careful in the use of $_SERVER['HTTP_X_FORWARDED_FOR'], as I discovered, once using Amazon AWS's Elastic Load Balancer's, this value may be a comma separated list of IP addresses and will thusly not compare as conceived in almost every example I have seen posted by users in the comments.
dhjdhj at gmail dot com ¶
11 years ago
I have observed that there are problems with all approaches that use the existence of an IP address to verify that the name being looked up actually exists.
If you're using opendns, then a request to a non-existent server returns an IP address anyway, the address being one for an opendns server. This is process is presumably in place so that errant URLs in browser requests take you to a "legitimate" page, i.e, the openDNS website where they can notify you of a problem.
Unfortunately, that mechanism seems to occur for ANY non-existent hostname. Appending a single period to the hostname does not seem to help.
pulstar at mail dot com ¶
19 years ago
If you need to store an IP addresses in a database, you can convert and store it in an INT type column [4 bytes]. The functions below can convert IP addresses to its integer decimal value and vice-versa.
function ip2dec[$ipaddr] {
$base=explode[".",$ipaddr];
$decimal=[double] $base[0]*16777216;
$decimal+=$base[1]*65536;
$decimal+=$base[2]*256;
$decimal+=$base[3];
if[$decimal>2147483647] {
$decimal-=4294967296;
}
return [int] $decimal;
}
function dec2ip[$dec] {
if[$dec16777215] {
$ip=$dec-[intval[$dec/256]*256];
$dec=[double] intval[$dec/256];
} else $ip="0";
if[$dec>65535] {
$ip=[$dec-[intval[$dec/256]*256]].".".$ip;
$dec=[double] intval[$dec/256];
} else $ip="0.".$ip;
if[$dec>255] {
$ip=[$dec-[intval[$dec/256]*256]].".".$ip;
$dec=[double] intval[$dec/256];
} else $ip="0.".$ip;
$ip=$dec.".".$ip;
return [string] $ip;
}
andy at occ dot nu ¶
21 years ago
if the user is sitting behind a proxy server, you can do this;
ps; i use $HTTP_SERVER_VARS["something"] instead of just $something;
you can get most of the $HTTP_SERVER_VARS by just using there $something equivalent, see the manual for that [preserved variables]
Mark in Sussex ¶
11 years ago
If you use gethostbyaddr[] with a bad IP address then it will send an error message to the error log.
If you don't want your error log file getting too big then first check that the IP address is valid.
In the following example I first check if the IP number starts with a number,
if not then don't use gethostbyaddr['..']
marco[DOT]ceppi[@T]seacrow[DOT]org ¶
12 years ago
Anonymous has a good point [though I don't agree with pushing to execution to shell unless I have to. However this is a faster example [explode then loop is a little too intensive for a simple check]
Though to be honest I would use:
reinhard at ess dot co dot at ¶
17 years ago
tried out some of the examples below, but no one worked for me.
[
"host" returns something if domain-name wasn't found
"gethostbyaddr" has a too long timeout when it fails
"the udp-example" returns some strange characters...
]
so i have changed the "host"-example a little bit. hope someone can need it. [maybe with little changes like without error-description]
grimNOSPAMtraffic at hotNOSPAMmail dot com ¶
19 years ago
If you have found the host of the ip, the shortest way to cut it not to display the full hostname to the public would be:
$host = substr[$host, strpos[$host, "."] + 1];
P.S. strpos[] can also be easily used if you want to put "*" for every simbol you ommit, like so:
$os = strpos[$host, "."];
$host = substr[$host, $os];
$host = str_repeat["*", $os] . $host;
--McTrafik
ven at PragaKhan dot com ¶
20 years ago
$REMOTE_HOST or $_SERVER['REMOTE_HOST'] will give you the reversed ip IF apache is setup to do hostname lookups.
HostnameLookups On
alexey at ozerov dot de ¶
20 years ago
This function seems to be very slow on IIS 4.0 Server [Win32]. I use system call to NSLOOKUP instead to get PC-Hostname:
unset [$execoutput];
exec ["nslookup $IPAdresse 2>nul",$execoutput,$nslookstatus];
if [isset [$execoutput[3]] && ereg ["^Name: *[[A-Za-z0-9]{2,}]\.",$execoutput[3],$regs]]
$nslookname=strtoupper[$regs[1]];
else $nslookname="Unknown";
Note by members: This is not portable to Windows platforms. so you would be better to stay with our function.
billyblue ¶
14 years ago
I just spent a dickens of a time trying to figure out why my gethostbyaddr's were simply failing halfway through.
I'm returning a log of page visits, and with each new IP, I wanted to pull the hostname of the IP. On each report page, I'm pulling 500 lines from my Db, but only maybe 25 IPs on average. Sometimes this report would generate in under 15 seconds, other times it would fail with a connection reset.
It turns out that several of the IPs in my Db looked like this: x.255.x.x. gethostbyaddr really hates that and simply dies when it reaches one of these IPs.
For my case, I purged the Db and prevented the logging of IPs that contain 255.
webmaster at askapache dot com ¶
13 years ago
Here is a simple function I compiled from user-notes that works great.. any improvements?
www.ad-rotator.com ¶
19 years ago
For ad-rotator.com, we need to do a lot of IP lookups, gethostbyaddr is very easy get timed-out and the script stucks there forever. Here is a fail-safe alternative, 1 sec max for timeout per IP.
function ar_gethostbyaddr[$ip] {
$output = `host -W 1 $ip`;
if [ereg['.*pointer [[A-Za-z0-9.-]+]\..*',$output,$regs]] {
return $regs[1];
}
return $ip;
}
Matt AKA Junkie ¶
18 years ago
Going through numerous tests, the following results are concluded: