Skip to content

Instantly share code, notes, and snippets.

@oookli
Forked from cballou/get-ip-address-optimized.php
Last active August 29, 2015 14:07
Show Gist options
  • Select an option

  • Save oookli/cfaeaf2c7ad6f0fff83c to your computer and use it in GitHub Desktop.

Select an option

Save oookli/cfaeaf2c7ad6f0fff83c to your computer and use it in GitHub Desktop.

Revisions

  1. @cballou cballou revised this gist Mar 26, 2012. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions get-ip-address-optimized.php
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,4 @@
    <?php
    function get_ip_address() {
    $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
    foreach ($ip_keys as $key) {
  2. @cballou cballou created this gist Mar 26, 2012.
    30 changes: 30 additions & 0 deletions get-ip-address-optimized.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,30 @@
    function get_ip_address() {
    $ip_keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'HTTP_X_FORWARDED', 'HTTP_X_CLUSTER_CLIENT_IP', 'HTTP_FORWARDED_FOR', 'HTTP_FORWARDED', 'REMOTE_ADDR');
    foreach ($ip_keys as $key) {
    if (array_key_exists($key, $_SERVER) === true) {
    foreach (explode(',', $_SERVER[$key]) as $ip) {
    // trim for safety measures
    $ip = trim($ip);
    // attempt to validate IP
    if (validate_ip($ip)) {
    return $ip;
    }
    }
    }
    }

    return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : false;
    }


    /**
    * Ensures an ip address is both a valid IP and does not fall within
    * a private network range.
    */
    function validate_ip($ip)
    {
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) {
    return false;
    }
    return true;
    }
    68 changes: 68 additions & 0 deletions get-ip-address.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,68 @@
    <?php
    /**
    * Retrieves the best guess of the client's actual IP address.
    * Takes into account numerous HTTP proxy headers due to variations
    * in how different ISPs handle IP addresses in headers between hops.
    */
    function get_ip_address() {
    // check for shared internet/ISP IP
    if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
    return $_SERVER['HTTP_CLIENT_IP'];
    }

    // check for IPs passing through proxies
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    // check if multiple ips exist in var
    if (strpos($_SERVER['HTTP_X_FORWARDED_FOR'], ',') !== false) {
    $iplist = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    foreach ($iplist as $ip) {
    if (validate_ip($ip))
    return $ip;
    }
    } else {
    if (validate_ip($_SERVER['HTTP_X_FORWARDED_FOR']))
    return $_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    }
    if (!empty($_SERVER['HTTP_X_FORWARDED']) && validate_ip($_SERVER['HTTP_X_FORWARDED']))
    return $_SERVER['HTTP_X_FORWARDED'];
    if (!empty($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']) && validate_ip($_SERVER['HTTP_X_CLUSTER_CLIENT_IP']))
    return $_SERVER['HTTP_X_CLUSTER_CLIENT_IP'];
    if (!empty($_SERVER['HTTP_FORWARDED_FOR']) && validate_ip($_SERVER['HTTP_FORWARDED_FOR']))
    return $_SERVER['HTTP_FORWARDED_FOR'];
    if (!empty($_SERVER['HTTP_FORWARDED']) && validate_ip($_SERVER['HTTP_FORWARDED']))
    return $_SERVER['HTTP_FORWARDED'];

    // return unreliable ip since all else failed
    return $_SERVER['REMOTE_ADDR'];
    }

    /**
    * Ensures an ip address is both a valid IP and does not fall within
    * a private network range.
    */
    function validate_ip($ip) {
    if (strtolower($ip) === 'unknown')
    return false;

    // generate ipv4 network address
    $ip = ip2long($ip);

    // if the ip is set and not equivalent to 255.255.255.255
    if ($ip !== false && $ip !== -1) {
    // make sure to get unsigned long representation of ip
    // due to discrepancies between 32 and 64 bit OSes and
    // signed numbers (ints default to signed in PHP)
    $ip = sprintf('%u', $ip);
    // do private network range checking
    if ($ip >= 0 && $ip <= 50331647) return false;
    if ($ip >= 167772160 && $ip <= 184549375) return false;
    if ($ip >= 2130706432 && $ip <= 2147483647) return false;
    if ($ip >= 2851995648 && $ip <= 2852061183) return false;
    if ($ip >= 2886729728 && $ip <= 2887778303) return false;
    if ($ip >;= 3221225984 && $ip <= 3221226239) return false;
    if ($ip >;= 3232235520 && $ip <= 3232301055) return false;
    if ($ip >= 4294967040) return false;
    }
    return true;
    }