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.
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); }
Caching
Hi, can you post where you've modified the code? Thank you
Setting defaults in CRN
At the end of
geoip/GeoIP/CRN.php
(underneath the$crnMap
) I have added default values in case thegetRegionName
orgetRegionCode
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); } }
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
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
RE: Defaults in CRN
@Dinis I see your point, and it does make perfect sense that adding a default location may not be the best way to go about this, and I agree, adding "other" may be a good one.
Yes, it did cause an error:
... at the following line (it's line 4519 in my implementation, probably the same on the original version):
return self::$crnMap[$countryCode][$regionCode];
The map obviously was missing Malta as a country, and during my review I found that there were several other countries missing too. Though it wasn't easy, I finally did find MaxMind's country/region map somehow, but it was slightly different from the one in this extension. Since then I extracted the country list above, and merged it with this one, so I should have a more or less complete (but at least a slightly larger) list helping to prevent failures, along with the default selection check I created below.
If I get the time, I may create a pull request for the "other" solution, but you may be faster than me. :)
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.