![]() |
|
Snippets |
|
This snippet allows you to retrieve the country of the visitor using the IP number of the visitor. It will also become available as a symfony Plugin.
Very handy when you are developing a internationalized application. You can use the ISO code in lowercase to set the interface language. Like this:
$lang = strtolower(Country::getIso2WithIp(Country::getIpAddress()))
By passing the IP number to a function, you'll get the following information: - ISO 3166 Code, 2 characters, might be used to set the culture - Country, 20 characters
The IP data is imported from the webnet77 (http://software77.net/cgi-bin/ip-country/geo-ip.pl) database, probably the most frequently updated database on the web.
Data is stored on your server, that means that retrieving data is a lot faster compared to the already existing plugin sfIp2Country, which uses a web request.
config/schema.xml:
<table name="YOURDB_country" phpName="Country"> <column name="ipfrom" type="bigint" size="20" required="true" primaryKey="true" /> <column name="ipto" type="bigint" size="20" /> <column name="registry" type="varchar" size="7" /> <column name="assigned" type="varchar" size="8" /> <column name="iso2" type="varchar" size="2" /> <column name="iso3" type="varchar" size="3" /> <column name="country" type="varchar" size="20" /> </table>
Do a build-model and whatever is needed.
Additions to lib/model/country.php
static function getIpAddress() { // Get the ip v4 address if (getenv("HTTP_CLIENT_IP")) $ipaddr = getenv("HTTP_CLIENT_IP"); else if(getenv("HTTP_X_FORWARDED_FOR")) $ipaddr = getenv("HTTP_X_FORWARDED_FOR"); else if(getenv("REMOTE_ADDR")) $ipaddr = getenv("REMOTE_ADDR"); else $ipaddr = "127.0.0.1"; // not found, make it localhost return $ipaddr; } static function retrievePkByIp($ipaddr) { // Make IP numerical $ipnum = sprintf("%u", ip2long($ipaddr)); // lookup IP address $c = new Criteria(); $c->add(CountryPeer::IPFROM, "'$ipnum' >= ".CountryPeer::IPFROM." and "."'$ipnum' <= ".CountryPeer::IPTO, Criteria::CUSTOM); $rs = CountryPeer::doSelectRS($c); $pk = 0; while ($rs->next()){ $pk = $rs->getString(1); } return $pk; } static function getIso2WithIp($ipaddr) { // Make IP numerical $ipnum = sprintf("%u", ip2long($ipaddr)); // lookup IP address $c = new Criteria(); $c->add(CountryPeer::IPFROM, "'$ipnum' >= ".CountryPeer::IPFROM." and "."'$ipnum' <= ".CountryPeer::IPTO, Criteria::CUSTOM); $rs = CountryPeer::doSelectRS($c); $iso2 = "EN"; // initialize with your default country while ($rs->next()){ $iso2 = $rs->getString(5); } return $iso2; }
Helper to demonstrate the works: \apps\frontend\lib\helper\CountryHelper.php
<?php function display_ipinfo() { // Get IP address and make numeric $ipaddr = Country::getIpAddress(); $ipnum = sprintf("%u", ip2long($ipaddr)); // Retrieve from database $country = CountryPeer::retrieveByPk(Country::retrievePkByIp($ipaddr)); // Output $o = '<p>'; $o .= 'Your IP number: ' . ' ' . $ipaddr . '<br />'; $o .= 'Your IP numerical: ' . $ipnum . '<br />'; $o .= 'Data retrieved from IP database:<br />'; if ($country) // found { $o .= 'ISO code: ' . $country->getIso2() . '<br />'; $o .= 'Country: ' . ' ' . $country->getCountry(); } else // not found { $o .= 'Your IP number was not found in the IP-database'; } $o .= '</p>'; echo $o; }
Code to call the demo function in the helper:
<?php use_helper('Country'); ?> <?php display_ipinfo() ?>
I load my data with a Cron job, the SQL statement is as follows:
LOAD DATA INFILE 'YOURPATH_IpToCountry.csv' REPLACE INTO TABLE YOURDB_country FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n'
Demo at http://www.noorden.com/en/my+symfony+php+projects/project-ip-number-to-country.html