|
|
 |
getenv (PHP 3, PHP 4, PHP 5) getenv -- Gets the value of an environment variable
User Contributed Notes
getenv
renko at <remove>virtual-life dot net
08-Nov-2004 08:40
The function 'getenv' does not work if your Server API is ASAPI (IIS).
So, try to don't use getenv('REMOTE_ADDR'), but $_SERVER["REMOTE_ADDR"].
NOdonn [AT] edonn . comSPAM
21-Sep-2004 12:10
I am not sure if this is obvious or not, but besides filtering LAN addresses, you can also filter proxies as well. When I switched servers from one based in Singapore to one based in the United States, my IP-detection script (using the basic $_SERVER['REMOTE_ADDR']) started returning 165.21.*.* for all Singaporean users, as they had to go through our ISP's proxy.
Below is the script I use to get IP addresses of Singaporean internet users (based on code I saw on from some other people's contributions here):
<?php
function convertIp($originalIp)
{
$ipParts = explode(".", $originalIp);
if ($ipParts[0] == "165" && $ipParts[1] == "21") {
if (getenv("HTTP_CLIENT_IP")) {
$ip = getenv("HTTP_CLIENT_IP");
} elseif (getenv("HTTP_X_FORWARDED_FOR")) {
$ip = getenv("HTTP_X_FORWARDED_FOR");
} elseif (getenv("REMOTE_ADDR")) {
$ip = getenv("REMOTE_ADDR");
}
} else {
return $originalIp;
}
return $ip;
}
?>
It is very basic, but gets the job done for my mostly Singaporean visitors.
isaacschlueter at removethis dot hotmail dot com
13-Jun-2004 12:33
I have an application where I want to track the remote address, and if that's not available, then the local address. (Sometimes it's over a network, and sometimes over the internet, and for security, some features should only be run over the local network.) I added some checking that should be redundant to get around a few weird situations I encountered, where addresses were set, but empty.
<?php
$private_net_ip_masks = array( '10.0.0.', '192.168.', '127.0.0.', '172.16.0.' );
if( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '' )
{
$ipStrings = explode( ',',$_SERVER['HTTP_X_FORWARDED_FOR']);
foreach($ipStrings as $k => $v)
{
if( empty($v) )
{
unset( $ipStrings[$k] );
}
else
{ if(!isset($ipString)) $ipString = $v;
}
}
}
if( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '' )
{
$ipStrings[] = $_SERVER['REMOTE_ADDR'];
if(!isset($ipString)) $ipString = $_SERVER['REMOTE_ADDR'];
}
foreach($ipStrings as $k1 => $ip)
{
foreach($private_net_ip_masks as $k2 => $pip)
{
if(strpos($ip, $pip) === 0)
{ unset($ipStrings[$k1]);
break;
}
}
}
if( !empty($ipStrings) )
{
foreach( $ipStrings as $v )
{
if(!empty($v))
{
$ipString = $v;
$is_local_ip = false;
break;
}
}
}
else
{
$is_local_ip = true;
}
$ipArray = explode('.', $ipString);
foreach($ipStrings as $k => $v) echo '$ipStrings['.$k.'] = ' . $v . '<br />';
echo "\$ipString = $ipString<br />";
foreach($ipArray as $k => $v) echo '$ipArray['.$k.'] = ' . $v . '<br />';
?>
mkaman at aldeafutura dot com
23-Apr-2004 08:33
I think there is a better way to determine a correct ip. This is based in the fact that the private ip's for lan use are described in RFC 1918.
So all we have to do is get an ordered array of ip's and take the first ip that doesn't is a private ip.
//List of the private ips described in the RFC. You can easily add the
//127.0.0.0/8 to this if you need it.
$ip_private_list=array(
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
);
//Determine if an ip is in a net.
//E.G. 120.120.120.120 in 120.120.0.0/16
//I saw this in another post in this site but don't remember where :P
function isIPInNet($ip,$net,$mask) {
$lnet=ip2long($net);
$lip=ip2long($ip);
$binnet=str_pad( decbin($lnet),32,"0","STR_PAD_LEFT" );
$firstpart=substr($binnet,0,$mask);
$binip=str_pad( decbin($lip),32,"0","STR_PAD_LEFT" );
$firstip=substr($binip,0,$mask);
return(strcmp($firstpart,$firstip)==0);
}
//This function check if a ip is in an array of nets (ip and mask)
function isIpInNetArray($theip,$thearray)
{
$exit_c=false;
#print_r($thearray);
foreach ( $thearray as $subnet ) {
list($net,$mask)=split("/",$subnet);
if(isIPInNet($theip,$net,$mask)){
$exit_c=true;
break;
}
}
return($exit_c);
}
//Building the ip array with the HTTP_X_FORWARDED_FOR and
//REMOTE_ADDR HTTP vars.
//With this function we get an array where first are the ip's listed in
//HTTP_X_FORWARDED_FOR and the last ip is the REMOTE_ADDR.
//This is inspired (copied and modified) in the function from daniel_dll.
function GetIpArray()
{
$cad="";
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND
$_SERVER['HTTP_X_FORWARDED_FOR']!="")
$cad=$_SERVER['HTTP_X_FORWARDED_FOR'];
if(isset($_SERVER['REMOTE_ADDR']) AND
$_SERVER['REMOTE_ADDR']!="")
$cad=$cad.",".$_SERVER['REMOTE_ADDR'];
$arr= explode(',',$cad);
return $arr;
}
//We check each ip in the array and we returns the first that is not a
//private ip.
function getIp()
{
global $ip_private_list;
$ip = "unknown";
$ip_array=getIpArray();
foreach ( $ip_array as $ip_s ) {
if( $ip_s!="" AND !isIPInNetArray($ip_s,$ip_private_list)){
$ip=$ip_s;
break;
}
}
return($ip);
}
mayday at tria dot lv
19-Apr-2004 01:00
daniele_dll:
Your function hase a bug!
If You check this IPs:
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
$_SERVER['HTTP_X_FORWARDED_FOR'] = '127.0.0.2,127.0.0.3';
the function will return this:
Array
(
[0] => 127.0.0.1
[1] => 127.0.0.3
)
Yes, the first element from 'HTTP_X_FORWARDED_FOR' is lost.
The only fixes you need to make is to move down one line.
This is the correct way:
<?php
function get_ip_list() {
$tmp = array();
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && strpos($_SERVER['HTTP_X_FORWARDED_FOR'],',')) {
$tmp += explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
} elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$tmp[] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
$tmp[] = $_SERVER['REMOTE_ADDR'];
return $tmp;
}
?>
daniele_dll at yahoo dot it
15-Mar-2004 03:14
referred to info at barclaey nospam dot com post
getIP function is written bad! If a user, that is behind a proxy in his lan, connect to a web site, and someone use this function to get ip, and proxy send HTTP_X_FORWARDED_FOR or HTTP_CLIENT_IP header your script will have a LAN ip, totally unuseful over internet! So, i think, that a good solution can use all headers! For example:
<?php
function getIP() {
$tmparr = array();
$tmparr[] = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$tmparr += explode(',',$_SERVER['HTTP_X_FORWARDED_FOR']);
}
return $tmparr;
}
print_r(getIP());
?>
this code contains a list of ips...the last is client ip, the second is first proxy, the second before the last is the second proxy...ecc ecc ecc...the first is ip client or last proxy used. Naturally if any proxy is used there is only an element...ip of the client :)
(HTTP_X_FORWARDED_FOR contains a comma separated list of clients IP - Proxy can be configure to use other proxies so, if proxy is configured to use HTTP_X_FORWARDED_FOR, will send a comma separated list of ips)
I've haven't used into script HTTP_CLIENT_IP because i don't know this header, i haven't found it in any rfc however it can be added without any difficult
PS: pls do not use getenv to read standard vars :) getenv is a function so is very very very slow compare to a simply array read :)
PS2: sorry for my english :)
bye
kyong
04-Feb-2004 03:06
As you know, getenv('DOCUMENT_ROOT') is useful.
However, under CLI environment(I tend to do quick check
if it works or not), it doesn't work without modified php.ini
file. So I add "export DOCUMENT_ROOT=~" in my .bash_profile.
info at barclaey nospam dot com
22-Oct-2003 01:11
Joenema at aol dot com, there is a syntax error in your note. You forgot a hyphen after HTTP_X_FORWARDED_FOR. This is the correct code:
function getIP() {
$ip;
if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP");
else if(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR");
else if(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR");
else $ip = "UNKNOWN";
return $ip;
}
ng4rrjanbiah at rediffmail dot com
03-Sep-2003 05:04
[Worked depending upon the comment of "hanez at forpresident dot com". Reviewed Anders Winther and "Joenema at aol dot com"'s "bullet-proof" IP address fetcher and came out with a new tight code.]
<?php
function GetIP()
{
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}?>
HTH,
R. Rajesh Jeba Anbiah
Joenema at aol dot com
29-May-2003 05:25
This is just a reply to Anders Winther's fool-proof IP address fetcher.
What he has is good, but uses a lot of superfluous lines. Basically, he could have done this:
function getIP() {
$ip;
if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP");
else if(getenv("HTTP_X_FORWARDED_FOR)) $ip = getenv("HTTP_X_FORWARDED_FOR");
else if(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR");
else $ip = "UNKNOWN";
return $ip;
}
Do you see how those numerous lines of code compressed into a few lines?
daman at SPAM_BlockERmralaska dot com
08-Sep-2002 08:37
Be careful using HTTP_X_FORWARDED_FOR in conditional statements collecting the IP address. Sometimes the user's LAN address will get forwarded, which of course is pretty worthless by itself.
kriplozoik dot ma dot velky at kokot dot com
24-Jul-2002 10:32
on some freehostings getenv() function is verbidden. in that case, simply use for example $HTTP_REMOTE_ADDR instead of getenv("REMOTE_ADDR")
alex at acid-edge dot net
23-Jul-2002 12:32
Note that some caches seem to send the client-ip header *backwards*. be careful :)
john-php at pc dot xs4all dot nl
15-Aug-2000 08:56
Note that the X-Forwarded for header might contain multiple addresses, comma separated, if the request was forwarded through multiple proxies.
Finally, note that any user can add an X-Forwarded-For header themselves. The header is only good for traceback information, never for authentication. If you use it for traceback, just log the entire X-Forwarded-For header, along with the REMOTE_ADDR.
sorry at spammed dot nut
12-Jul-1999 09:43
To show a use of getenv("QUERY_STRING")....
suppose you have a site with frames... the frames create the "interface", and one frame called "main" has an active document... now, suppose you made a page.php3 which took an argument "pg" and spit out the framesets necessary, with "main" frame containing whatever "pg" is... so now you can bring up any page in your site with page.php3?pg=test.html
now, take this one step further, and suppose you want outside links to point to php3 pages which takes parameters, ON your site... but you still want them to appear in frames, so what do you do? well, if "ok.php3" was the page you wanted to show, and it was requested as "ok.php3?some=params&go=here", then the very thing in the beginning of ok.php3 could be
if (!isset($inframe)) {
header("Location: http://yoursite/page.php3?pg=".urlencode("inframes=1&").getenv("QUERY_STRING"));
exit;
}
Now... you might ask, how in the world did I come up with THAT? Well, perhaps it was because I came here not able to remember which environment variable held the query string...
| |