views:

132

answers:

3

Hello! Why this code return "" :

$ip = "";
if(getenv("HTTP_CLIENT_IP")) 
{
 $ip = getenv("HTTP_CLIENT_IP");
} elseif(getenv("HTTP_X_FORWARDED_FOR")) {
 $ip = getenv("HTTP_X_FORWARDED_FOR");
} else {
 $ip = getenv("REMOTE_ADDR");
}

Environment: W2003EE, IIS 6.0, PHP 5.2.9 (ISAPI)

$_SERVER is a built-in PHP variable. getenv() looks at the current environment.

In my case i need to use $_SERVER. Thank all!

Thanks!

A: 

The value of environment variable REMOTE_ADDR must be empty or not set. If working on linux check its value on terminal by the command echo $REMOTE_ADDR. If it returns null, sets its value before assigning $ip.

stack programmer
This code run on W2003EE, IIS 6.0, PHP 5.2.9 (ISAPI).
Sasha
+1  A: 

Try $_SERVER['REMOTE_ADDR'] or $_SERVER['HTTP_X_FORWARDED_FOR']

If you wonder what is set you can dump $_SERVER somewhere.

OIS
$_SERVER["REMOTE_ADDR"] work fine! But why getenv("REMOTE_ADDR") dont???
Sasha
Good post: http://stackoverflow.com/questions/1636644/which-is-the-better-way-to-get-the-ip
Sasha
A: 

The problem may have something to do with IIS working a bit differently. I've had success with these two function from the CakePHP project.

/**
 * Gets remote client IP
 *
 * @return string Client IP address
 * @access public
 */
function getClientIP($safe = true) {
 if (!$safe && env('HTTP_X_FORWARDED_FOR') != null) {
  $ipaddr = preg_replace('/(?:,.*)/', '', env('HTTP_X_FORWARDED_FOR'));
 } else {
  if (env('HTTP_CLIENT_IP') != null) {
   $ipaddr = env('HTTP_CLIENT_IP');
  } else {
   $ipaddr = env('REMOTE_ADDR');
  }
 }

 if (env('HTTP_CLIENTADDRESS') != null) {
  $tmpipaddr = env('HTTP_CLIENTADDRESS');

  if (!empty($tmpipaddr)) {
   $ipaddr = preg_replace('/(?:,.*)/', '', $tmpipaddr);
  }
 }
 return trim($ipaddr);
}

/**
 * Gets an environment variable from available sources, and provides emulation
 * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
 * IIS, or SCRIPT_NAME in CGI mode).  Also exposes some additional custom
 * environment information.
 *
 * @param  string $key Environment variable name.
 * @return string Environment variable setting.
 * @link http://book.cakephp.org/view/701/env
 */
    function env($key) {
     if ($key == 'HTTPS') {
      if (isset($_SERVER['HTTPS'])) {
       return (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off');
      }
      return (strpos(env('SCRIPT_URI'), 'https://') === 0);
     }

     if ($key == 'SCRIPT_NAME') {
      if (env('CGI_MODE') && isset($_ENV['SCRIPT_URL'])) {
       $key = 'SCRIPT_URL';
      }
     }

     $val = null;
     if (isset($_SERVER[$key])) {
      $val = $_SERVER[$key];
     } elseif (isset($_ENV[$key])) {
      $val = $_ENV[$key];
     } elseif (getenv($key) !== false) {
      $val = getenv($key);
     }

     if ($key === 'REMOTE_ADDR' && $val === env('SERVER_ADDR')) {
      $addr = env('HTTP_PC_REMOTE_ADDR');
      if ($addr !== null) {
       $val = $addr;
      }
     }

     if ($val !== null) {
      return $val;
     }

     switch ($key) {
      case 'SCRIPT_FILENAME':
       if (defined('SERVER_IIS') && SERVER_IIS === true) {
        return str_replace('\\\\', '\\', env('PATH_TRANSLATED'));
       }
      break;
      case 'DOCUMENT_ROOT':
       $name = env('SCRIPT_NAME');
       $filename = env('SCRIPT_FILENAME');
       $offset = 0;
       if (!strpos($name, '.php')) {
        $offset = 4;
       }
       return substr($filename, 0, strlen($filename) - (strlen($name) + $offset));
      break;
      case 'PHP_SELF':
       return str_replace(env('DOCUMENT_ROOT'), '', env('SCRIPT_FILENAME'));
      break;
      case 'CGI_MODE':
       return (PHP_SAPI === 'cgi');
      break;
      case 'HTTP_BASE':
       $host = env('HTTP_HOST');
       if (substr_count($host, '.') !== 1) {
        return preg_replace('/^([^.])*/i', null, env('HTTP_HOST'));
       }
      return '.' . $host;
      break;
     }
     return null;
    }
Jason
Thanks. This work too, but I need a smaller source ...
Sasha