In other words, how can I tell if the person using my web application is on the server it resides on? If I remember correctly, PHPMyAdmin does something like this for security reasons.
11 Answers
You can use $_SERVER['REMOTE_ADDR']
, which contains the
IP address of the client requesting it, as given by the web server.
$whitelist = array(
'127.0.0.1',
'::1'
);
if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
// not valid
}
Note: the original version of this answer suggested verifying the destination hostname using $_SERVER['HTTP_HOST'], which is unsafe because it could in some cases be spoofed by the requester.

- 3,303
- 2
- 34
- 35

- 42,982
- 15
- 99
- 131
-
2Which would make this actually easier to break than spoofing the IP. You should really change it. – Pekka Jan 13 '10 at 00:09
-
This is not working for me. $_SERVER['HTTP_HOST'] returns the textual part of my domain (e.g. "example" if the domain were www.example.com). – skcin7 Jan 18 '12 at 08:26
-
3@skcin7 might be your server setting. check it. – mauris Jan 18 '12 at 11:53
-
4@Pekka웃 you can just send e.g. `Host: 127.0.0.1` and it would be populated in `HTTP_HOST`, so it's not reliable method at all. – Dejan Marjanović Mar 19 '13 at 15:49
-
6Yeah, this is bad advice and in its current form and needs to be edited - or downvoted. – Pekka Aug 03 '13 at 08:40
-
Edited post just only. You guys can directly edit this answer without waiting for me. – mauris Aug 04 '13 at 03:57
-
3Do not forget IPv6 : `$whitelist = array('127.0.0.1', '::1');` – CrazyMax Feb 19 '14 at 15:22
-
1@crazy added the IPv6 address! – mauris Feb 21 '14 at 03:13
-
1Wouldn't it be better to use `filter_input(INPUT_SERVER, 'REMOTE_ADDR')` instead of `$_SERVER['REMOTE_ADDR']`. – ban-geoengineering Apr 26 '17 at 12:30
As a complement, as a function...
function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}

- 23,180
- 45
- 124
- 206
-
7As good practice I would recommend adding "else return false;" so that the function always returns a boolean value. Or alternately, just remove the "if" completely and instead "return in_array( $_SERVER['REMOTE_ADDR'], $whitelist);" – Joe Irby Feb 01 '18 at 18:22
Newer OS users (Win 7, 8) may also find it necessary to include an IPV6-format remote address in their whitelist array:
$whitelist = array('127.0.0.1', "::1");
if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
// not valid
}

- 1,701
- 2
- 21
- 31
I'm sorry but all these answers seem terrible to me. I would suggest rephrasing the question because in a sense all machines are "localhost".
The question should be; How do I run different code paths depending on which machine it is executed on.
In my opinion, the easiest way is to create a file called DEVMACHINE or whatever you want really and then simply check
file_exists('DEVMACHINE')
Remember to exclude this file when uploading to the live hosting environment!
This solution is not depending on network configuration, it can not be spoofed and makes it easy to switch between running "live-code" and "dev-code".

- 945
- 8
- 10
$_SERVER["REMOTE_ADDR"]
should tell you the user's IP. It's spoofable, though.
Check this bounty question for a very detailed discussion.
I think what you remember with PHPMyAdmin is something different: Many MySQL Servers are configured so that they can only be accessed from localhost for security reasons.
-
It's worth noting that some MySQL servers are so configured by not binding to a public interface. Similarly, if you wanted to restrict a PHP application in the same way, you should consider serving it via an apache instance bound only to an internal interface. – Frank Farmer Jan 12 '10 at 23:44
It doesn't seem you should use $_SERVER['HTTP_HOST']
, because this is the value in http header, easily faked.
You may use $_SERVER["REMOTE_ADDR"]
too, this is the more secure value, but it is also possible to fake. This remote_addr
is the address where Apache returns result to.

- 398,270
- 210
- 566
- 880

- 2,141
- 1
- 19
- 19
-
`REMOTE_ADDR` is possible to fake, however if you want to fake it as `127.0.0.1` or `::1`, that requires compromising the machine, at which a spoofed `REMOTE_ADDR` is the least of your worries. Relevant answer - http://stackoverflow.com/a/5092951/3774582 – Goose Nov 16 '16 at 15:06
Used this simple PHP condition
if($_SERVER['HTTP_HOST'] == 'localhost')
{
die('Localhost');
}

- 2,418
- 25
- 27
-
I guess this works if you want to prevent people accidentally accessing it specifically through "http://localhost" hostname (note that "127.0.0.1" would still work), but in general it's not safe to use HTTP_HOST, because it can be spoofed. – mwfearnley Mar 14 '23 at 13:58
-
I used same, now i am using different port. and this condition does not work anymore. any ideas what to change? – Danial212k Jul 20 '23 at 03:05
If you want to have a whitelist / allowlist that supports static IPs and dynamic names.
For example:
$whitelist = array("localhost", "127.0.0.1", "devel-pc.ds.com", "liveserver.com");
if (!isIPWhitelisted($whitelist)) die();
This way you could set a list of names/IPs that will be able (for sure) to be detected. Dynamic names add more flexibility for accessing from different points.
You have two common options here, you could set a name in your local hosts file or you could just use one dynamic name provider that could be found anywhere.
This function CACHES results because gethostbyname is a very slow function.
For this pupose I've implemented this function:
function isIPWhitelisted($whitelist = false)
{
if ( isset($_SESSION) && isset($_SESSION['isipallowed']) )
{ return $_SESSION['isipallowed']; }
// This is the whitelist
$ipchecklist = array("localhost", "127.0.0.1", "::1");
if ($whitelist) $ipchecklist = $whitelist;
$iplist = false;
$isipallowed = false;
$filename = "resolved-ip-list.txt";
$filename = substr(md5($filename), 0, 8)."_".$filename; // Just a spoon of security or just remove this line
if (file_exists($filename))
{
// If cache file has less than 1 day old use it
if (time() - filemtime($filename) <= 60*60*24*1)
$iplist = explode(";", file_get_contents($filename)); // Read cached resolved ips
}
// If file was not loaded or found -> generate ip list
if (!$iplist)
{
$iplist = array(); $c=0;
foreach ( $ipchecklist as $k => $iptoresolve )
{
// gethostbyname: It's a VERY SLOW function. We really need to cache the resolved ip list
$ip = gethostbyname($iptoresolve);
if ($ip != "") $iplist[$c] = $ip;
$c++;
}
file_put_contents($filename, implode(";", $iplist));
}
if (in_array($_SERVER['REMOTE_ADDR'], $iplist)) // Check if the client ip is allowed
$isipallowed = true;
if (isset($_SESSION)) $_SESSION['isipallowed'] = $isipallowed;
return $isipallowed;
}
For better reliability you could replace the $_SERVER['REMOTE_ADDR'] for the get_ip_address() that @Pekka mentioned in his post as "this bounty question"

- 1
- 1

- 1,241
- 1
- 18
- 23
-
1I don't know why someone set a negative score to my answer while it clearly offers dynamic name resolution and others not. DNS resolution is slow that's why caching resolutions is required. – Heroselohim Mar 21 '16 at 19:27
How about to compare $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']
to determine if client is on the same machine as server?

- 111
- 1
- 3
-
1`$_SERVER['SERVER_ADDR']` doesn't always reliably return the server address eg if using load balancers it returns the IP address of the load balancer I believe. – user115014 Aug 29 '18 at 09:15
Also there is another easy way to check is localhost or not: this code check if ip is in private or reserved range if it is thene we are in localhost.
- support ipv4 & ipv6.
- support ip range like 127.0.0.1 - 127.255.255.255
PHP Code:
function is_localhost() {
$server_ip = null;
if ( defined( 'INPUT_SERVER' ) && filter_has_var( INPUT_SERVER, 'REMOTE_ADDR' ) ) {
$server_ip = filter_input( INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP );
} elseif ( defined( 'INPUT_ENV' ) && filter_has_var( INPUT_ENV, 'REMOTE_ADDR' ) ) {
$server_ip = filter_input( INPUT_ENV, 'REMOTE_ADDR', FILTER_VALIDATE_IP );
} elseif ( isset( $_SERVER['REMOTE_ADDR'] ) ) {
$server_ip = filter_var( $_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP );
}
if ( empty( $server_ip ) ) {
$server_ip = '127.0.0.1';
}
return empty( filter_var( $server_ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE ));
}
- for get ip i use
filter_input
to avoid ip injection in code by user. - in some case
filter_input
not supported in CGI scripts so if not exist i get ip in normal way with$_SERVER
var. FILTER_VALIDATE_IP
AndFILTER_FLAG_NO_PRIV_RANGE
are documented in php site you can find more information in this link.

- 466
- 1
- 4
- 12
I found a easy answer.
Because all local drives have C: or D: or F: ... etc.
Just detect if the second character is a :
if ( substr_compare(getcwd(),":",1,1) == 0)
{
echo '<script type="text/javascript">alert(" The working dir is at the local computer ")</script>';
$client_or_server = 'client';
}
else
{
echo '<script type="text/javascript">alert(" The working dir is at the server ")</script>';
$client_or_server = 'server';
}

- 101
- 9
-
1This solution seems to be pretty susceptible for errors and only works on Windows. – Husky Oct 08 '20 at 09:42