Yii 1.1: geoip

Net_GeoIP port for Yii - Get a geographical location given an IP address
21 followers

This extension is a port of the Net_GeoIP PEAR package for Yii to get a geographical location given an IP address.

Made some adjustments to make it independent of the PEAR package. Basically it's just a proxy module that uses the library developed ported by Hans Lellelid in the PEAR package.

Resources

Documentation

Requirements

  • Yii 1.0 or above (tested with Yii 1.1.3 but should work with previous versions)

Installation

  • Extract the release file under protected/extensions
  • Change main.php configuration file
'components' => array(
      ...
      'geoip' => array(
          'class' => 'application.extensions.geoip.CGeoIP',
          // specify filename location for the corresponding database
          'filename' => 'C:\path\to\GeoIP\GeoLiteCity.dat',
          // Choose MEMORY_CACHE or STANDARD mode
          'mode' => 'STANDARD',
      ),
      ...
  ),

Usage

See the following code example:

$location = Yii::app()->geoip->lookupLocation();
  // with IP in google.com
  $location = Yii::app()->geoip->lookupLocation('209.85.135.104');
  $countryCode = Yii::app()->geoip->lookupCountryCode();
  $countryName = Yii::app()->geoip->lookupCountryName();
  $org = Yii::app()->geoip->lookupOrg();
  $regionCode = Yii::app()->geoip->lookupRegion();
 
  // Location attributes:
  $location->countryCode
  $location->countryCode3
  $location->countryName
  $location->region
  $location->regionName
  $location->city
  $location->postalCode
  $location->latitude
  $location->longitude
  $location->areaCode
  $location->dmaCode

Notes:

Methods lookupOrg and lookupRegion require specific databases (only paid versions available from MaxMind).

Change Log

June 1, 2013

  • Fix usage of non-static method in static context

July 21, 2010

  • Initial release.

Total 5 comments

#19774 report it
Dinis at 2016/02/12 06:46am
Defaults in CRN

@benomatis, thanks for your feedback.

Some notes: I'm not sure if returning a default behaviour would be a good option. In this case it would be "impossible" to distinguish between a visitor really identified as coming from region X (where X is the default) and another coming from another country Y but that could not be identified. The current behaviour of returning null values (can you confirm if it currently doesn't cause an error?) should stay as the default behaviour. What we could do is specify a "other" country/region that would be used when the check failed to identify a country.

By the way, can you confirm if this module still works with newer versions of the Yii framework?

Regards, Dinis

#19773 report it
Dinis at 2016/02/12 06:36am
Caching

I know this has been quite some while but I've since left Yii behing so stopped developing using it. Anyway, I'll happily maintain the module (hadn't received any updates about comments here).

@Sarke, thank you for your feedback, credit goes mostly to the original creators of the PEAR package. Could you (and this applies to other potential contributors) take the time to create a Pull Request on Github repo so I can analyse the diff and integrate your changes into a new version of the module?

Thank you.

Regards, Dinis

#19770 report it
benomatis at 2016/02/09 03:40pm
Setting defaults in CRN

At the end of geoip/GeoIP/CRN.php (underneath the $crnMap) I have added default values in case the getRegionName or getRegionCode functions would return false:

/**
   * Lookup the metro region based on the provided DMA code.
   *
   * @param int $dmaCode The DMA code
   *
   * @return string Metro region name.
   */
  public static function getRegionName($countryCode, $regionCode) {
    if ($countryCode === null || $regionCode === null) {
      return null;
    }
    if (array_key_exists($countryCode, self::$crnMap) == false || array_key_exists($regionCode, self::$crnMap[$countryCode]) == false)
      return self::$crnMap['GB']['X5']; // Set this to what fits your needs chosen from $crnMap
    else
      return self::$crnMap[$countryCode][$regionCode];
  }
 
  /**
   * Reverse lookup of DMA code if [exact] metro region name is known.
   *
   * @param string $countryCode Country code.
   * @param string $regionName Region name.
   *
   * @return int Region code, or false if not found.
   */
  public static function getRegionCode($regionName, $countryCode=null) {
    if ($countryCode === null) {
      if (array_search($regionName, self::$crnMap) == false)          
        return 'X5'; // Set this to what fits your needs chosen from $crnMap
      else
        return array_search($regionName, self::$crnMap);
    } else {
      if (array_key_exists($countryCode, self::$crnMap) == false || array_key_exists($regionCode, self::$crnMap[$countryCode]) == false)
        return 'X5'; // Set this to what fits your needs chosen from $crnMap
      else
        return array_search($regionName[$countryCode], self::$crnMap);      
    }
  }
#15190 report it
seniorboss at 2013/10/16 05:17am
Caching

Hi, can you post where you've modified the code? Thank you

#2630 report it
Sarke at 2011/01/24 06:05am
Easy and fast.

Works great, thanks!

I found that the "MEMORY_CACHE" was not a good idea as it loads the entire database into memory, and it is then destroyed after the script ends. So it's really much slower and a lot more memory consuming (35MB instead of 5MB).

Instead, I am using a little caching as follows:

$ip = CHttpRequest::getUserHostAddress();
$handle = 'GeoIP:'.$ip;
 
$data = Yii::app()->cache->get($handle);
if ($data === false)
{
    $location = Yii::app()->geoip->lookupLocation($ip);
 
    $data = array(
        'ip' => $ip,
        'country' => $location ->countryCode3,
        'countryName' => $location ->countryName,
        'region' => $location ->region,
        'regionName' => $location ->regionName,
        'city' => $location ->city,
    );
 
    Yii::app()->cache->set($handle, $data, 3600);
}

Leave a comment

Please to leave your comment.

Create extension