├── IpToCountry.csv ├── example.php ├── README.md └── Ip2Country.php /IpToCountry.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alienwithin/Ip2Country-1/master/IpToCountry.csv -------------------------------------------------------------------------------- /example.php: -------------------------------------------------------------------------------- 1 | parseCSV2(); 8 | 9 | //to display countryCode: 10 | echo $i->load('24.24.24.24')->countryCode; 11 | 12 | //to display country and countryCode: 13 | $i->load('24.24.24.24'); 14 | echo $i->countryCode; 15 | echo $i->country; 16 | ?> 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ip2Country 2 | ========== 3 | 4 | PHP class and .csv file that helps to get the location of an ip extremely fast 5 | 6 | Ip2Country.php converts the .csv file to PHP arrays and manage to get the location. 7 | 8 | Run the file example.php 9 | 10 | $i->parseCSV2(); 11 | this function parse the .csv into PHP arrays, just run it once. 12 | 13 | Update (04.02.2010): 14 | Function parseCSV() is storing over 99 000 entries in a memory table before saving to files. Each table entry in PHP is taking a lot of space, so the script needs more than 40 MB of RAM. So I added the parseCSV2() function, which does exactly the same, but requires less than 1 MB of RAM. New function is a bit slower, as it is doing more disk operations. 15 | 16 | You can get the updates from the .csv file here: http://software77.net/geo-ip/ 17 | 18 | Source of the code: http://de77.com/php/how-to-detect-visitors-country-using-his-ip-address 19 | 20 | -------------------------------------------------------------------------------- /Ip2Country.php: -------------------------------------------------------------------------------- 1 | 'AFGHANISTAN', 16 | 'AL'=>'ALBANIA', 17 | 'DZ'=>'ALGERIA', 18 | 'AS'=>'AMERICAN SAMOA', 19 | 'AD'=>'ANDORRA', 20 | 'AO'=>'ANGOLA', 21 | 'AI'=>'ANGUILLA', 22 | 'AQ'=>'ANTARCTICA', 23 | 'AG'=>'ANTIGUA AND BARBUDA', 24 | 'AR'=>'ARGENTINA', 25 | 'AM'=>'ARMENIA', 26 | 'AW'=>'ARUBA', 27 | 'AC'=>'ASCENSION ISLAND', 28 | 'AU'=>'AUSTRALIA', 29 | 'AT'=>'AUSTRIA', 30 | 'AZ'=>'AZERBAIJAN', 31 | 'BS'=>'BAHAMAS', 32 | 'BH'=>'BAHRAIN', 33 | 'BD'=>'BANGLADESH', 34 | 'BB'=>'BARBADOS', 35 | 'BY'=>'BELARUS', 36 | 'BE'=>'BELGIUM', 37 | 'BZ'=>'BELIZE', 38 | 'BJ'=>'BENIN', 39 | 'BM'=>'BERMUDA', 40 | 'BT'=>'BHUTAN', 41 | 'BO'=>'BOLIVIA', 42 | 'BA'=>'BOSNIA AND HERZEGOWINA', 43 | 'BW'=>'BOTSWANA', 44 | 'BV'=>'BOUVET ISLAND', 45 | 'BR'=>'BRAZIL', 46 | 'IO'=>'BRITISH INDIAN OCEAN TERRITORY', 47 | 'BN'=>'BRUNEI DARUSSALAM', 48 | 'BG'=>'BULGARIA', 49 | 'BF'=>'BURKINA FASO', 50 | 'BI'=>'BURUNDI', 51 | 'KH'=>'CAMBODIA', 52 | 'CM'=>'CAMEROON', 53 | 'CA'=>'CANADA', 54 | 'CV'=>'CAPE VERDE', 55 | 'KY'=>'CAYMAN ISLANDS', 56 | 'CF'=>'CENTRAL AFRICAN REPUBLIC', 57 | 'TD'=>'CHAD', 58 | 'CL'=>'CHILE', 59 | 'CN'=>'CHINA', 60 | 'CX'=>'CHRISTMAS ISLAND', 61 | 'CC'=>'COCOS (KEELING) ISLANDS', 62 | 'CO'=>'COLOMBIA', 63 | 'KM'=>'COMOROS', 64 | 'CD'=>'CONGO THE DEMOCRATIC REPUBLIC OF THE', 65 | 'CG'=>'CONGO', 66 | 'CK'=>'COOK ISLANDS', 67 | 'CR'=>'COSTA RICA', 68 | 'CI'=>'COTE D\'IVOIRE', 69 | 'HR'=>'CROATIA', 70 | 'CU'=>'CUBA', 71 | 'CY'=>'CYPRUS', 72 | 'CZ'=>'CZECH REPUBLIC', 73 | 'DK'=>'DENMARK', 74 | 'DJ'=>'DJIBOUTI', 75 | 'DM'=>'DOMINICA', 76 | 'DO'=>'DOMINICAN REPUBLIC', 77 | 'TP'=>'EAST TIMOR', 78 | 'EC'=>'ECUADOR', 79 | 'EG'=>'EGYPT', 80 | 'SV'=>'EL SALVADOR', 81 | 'GQ'=>'EQUATORIAL GUINEA', 82 | 'ER'=>'ERITREA', 83 | 'EE'=>'ESTONIA', 84 | 'ET'=>'ETHIOPIA', 85 | 'EU'=>'EUROPEAN UNION', 86 | 'FK'=>'FALKLAND ISLANDS (MALVINAS)', 87 | 'FO'=>'FAROE ISLANDS', 88 | 'FJ'=>'FIJI', 89 | 'FI'=>'FINLAND', 90 | 'FX'=>'FRANCE METRO', 91 | 'FR'=>'FRANCE', 92 | 'GF'=>'FRENCH GUIANA', 93 | 'PF'=>'FRENCH POLYNESIA', 94 | 'TF'=>'FRENCH SOUTHERN TERRITORIES', 95 | 'GA'=>'GABON', 96 | 'GM'=>'GAMBIA', 97 | 'GE'=>'GEORGIA', 98 | 'DE'=>'GERMANY', 99 | 'GH'=>'GHANA', 100 | 'GI'=>'GIBRALTAR', 101 | 'GR'=>'GREECE', 102 | 'GL'=>'GREENLAND', 103 | 'GD'=>'GRENADA', 104 | 'GP'=>'GUADELOUPE', 105 | 'GU'=>'GUAM', 106 | 'GT'=>'GUATEMALA', 107 | 'GG'=>'GUERNSEY', 108 | 'GN'=>'GUINEA', 109 | 'GW'=>'GUINEA-BISSAU', 110 | 'GY'=>'GUYANA', 111 | 'HT'=>'HAITI', 112 | 'HM'=>'HEARD AND MC DONALD ISLANDS', 113 | 'VA'=>'HOLY SEE (VATICAN CITY STATE)', 114 | 'HN'=>'HONDURAS', 115 | 'HK'=>'HONG KONG', 116 | 'HU'=>'HUNGARY', 117 | 'IS'=>'ICELAND', 118 | 'IN'=>'INDIA', 119 | 'ID'=>'INDONESIA', 120 | 'IR'=>'IRAN (ISLAMIC REPUBLIC OF)', 121 | 'IQ'=>'IRAQ', 122 | 'IE'=>'IRELAND', 123 | 'IM'=>'ISLE OF MAN', 124 | 'IL'=>'ISRAEL', 125 | 'IT'=>'ITALY', 126 | 'JM'=>'JAMAICA', 127 | 'JP'=>'JAPAN', 128 | 'JE'=>'JERSEY', 129 | 'JO'=>'JORDAN', 130 | 'KZ'=>'KAZAKHSTAN', 131 | 'KE'=>'KENYA', 132 | 'KI'=>'KIRIBATI', 133 | 'KP'=>'KOREA DEMOCRATIC PEOPLE\'S REPUBLIC OF', 134 | 'KR'=>'KOREA REPUBLIC OF', 135 | 'KW'=>'KUWAIT', 136 | 'KG'=>'KYRGYZSTAN', 137 | 'LA'=>'LAO PEOPLE\'S DEMOCRATIC REPUBLIC', 138 | 'LV'=>'LATVIA', 139 | 'LB'=>'LEBANON', 140 | 'LS'=>'LESOTHO', 141 | 'LR'=>'LIBERIA', 142 | 'LY'=>'LIBYAN ARAB JAMAHIRIYA', 143 | 'LI'=>'LIECHTENSTEIN', 144 | 'LT'=>'LITHUANIA', 145 | 'LU'=>'LUXEMBOURG', 146 | 'MO'=>'MACAU', 147 | 'MK'=>'MACEDONIA', 148 | 'MG'=>'MADAGASCAR', 149 | 'MW'=>'MALAWI', 150 | 'MY'=>'MALAYSIA', 151 | 'MV'=>'MALDIVES', 152 | 'ML'=>'MALI', 153 | 'MT'=>'MALTA', 154 | 'MH'=>'MARSHALL ISLANDS', 155 | 'MQ'=>'MARTINIQUE', 156 | 'MR'=>'MAURITANIA', 157 | 'MU'=>'MAURITIUS', 158 | 'YT'=>'MAYOTTE', 159 | 'MX'=>'MEXICO', 160 | 'FM'=>'MICRONESIA FEDERATED STATES OF', 161 | 'MD'=>'MOLDOVA REPUBLIC OF', 162 | 'MC'=>'MONACO', 163 | 'MN'=>'MONGOLIA', 164 | 'MS'=>'MONTSERRAT', 165 | 'MA'=>'MOROCCO', 166 | 'MZ'=>'MOZAMBIQUE', 167 | 'MM'=>'MYANMAR', 168 | 'ME'=>'Montenegro', 169 | 'NA'=>'NAMIBIA', 170 | 'NR'=>'NAURU', 171 | 'NP'=>'NEPAL', 172 | 'AN'=>'NETHERLANDS ANTILLES', 173 | 'NL'=>'NETHERLANDS', 174 | 'NC'=>'NEW CALEDONIA', 175 | 'NZ'=>'NEW ZEALAND', 176 | 'NI'=>'NICARAGUA', 177 | 'NE'=>'NIGER', 178 | 'NG'=>'NIGERIA', 179 | 'NU'=>'NIUE', 180 | 'AP'=>'NON-SPEC ASIA PAS LOCATION', 181 | 'NF'=>'NORFOLK ISLAND', 182 | 'MP'=>'NORTHERN MARIANA ISLANDS', 183 | 'NO'=>'NORWAY', 184 | 'OM'=>'OMAN', 185 | 'PK'=>'PAKISTAN', 186 | 'PW'=>'PALAU', 187 | 'PS'=>'PALESTINIAN TERRITORY OCCUPIED', 188 | 'PA'=>'PANAMA', 189 | 'PG'=>'PAPUA NEW GUINEA', 190 | 'PY'=>'PARAGUAY', 191 | 'PE'=>'PERU', 192 | 'PH'=>'PHILIPPINES', 193 | 'PN'=>'PITCAIRN', 194 | 'PL'=>'POLAND', 195 | 'PT'=>'PORTUGAL', 196 | 'PR'=>'PUERTO RICO', 197 | 'QA'=>'QATAR', 198 | 'ZZ'=>'RESERVED', 199 | 'RE'=>'REUNION', 200 | 'RO'=>'ROMANIA', 201 | 'RU'=>'RUSSIAN FEDERATION', 202 | 'RW'=>'RWANDA', 203 | 'KN'=>'SAINT KITTS AND NEVIS', 204 | 'LC'=>'SAINT LUCIA', 205 | 'VC'=>'SAINT VINCENT AND THE GRENADINES', 206 | 'WS'=>'SAMOA', 207 | 'SM'=>'SAN MARINO', 208 | 'ST'=>'SAO TOME AND PRINCIPE', 209 | 'SA'=>'SAUDI ARABIA', 210 | 'SN'=>'SENEGAL', 211 | 'SC'=>'SEYCHELLES', 212 | 'SL'=>'SIERRA LEONE', 213 | 'SG'=>'SINGAPORE', 214 | 'SK'=>'SLOVAKIA (SLOVAK REPUBLIC)', 215 | 'SI'=>'SLOVENIA', 216 | 'SB'=>'SOLOMON ISLANDS', 217 | 'SO'=>'SOMALIA', 218 | 'ZA'=>'SOUTH AFRICA', 219 | 'GS'=>'SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS', 220 | 'ES'=>'SPAIN', 221 | 'LK'=>'SRI LANKA', 222 | 'SH'=>'ST. HELENA', 223 | 'PM'=>'ST. PIERRE AND MIQUELON', 224 | 'SD'=>'SUDAN', 225 | 'SR'=>'SURINAME', 226 | 'SJ'=>'SVALBARD AND JAN MAYEN ISLANDS', 227 | 'SZ'=>'SWAZILAND', 228 | 'SE'=>'SWEDEN', 229 | 'CH'=>'SWITZERLAND', 230 | 'SY'=>'SYRIAN ARAB REPUBLIC', 231 | 'CS'=>'SERBIA AND MONTENEGRO', 232 | 'YU'=>'SERBIA AND MONTENEGRO', 233 | 'RS'=>'Serbia', 234 | 'TW'=>'TAIWAN; REPUBLIC OF CHINA (ROC)', 235 | 'TJ'=>'TAJIKISTAN', 236 | 'TZ'=>'TANZANIA UNITED REPUBLIC OF', 237 | 'TH'=>'THAILAND', 238 | 'TL'=>'TIMOR-LESTE', 239 | 'TG'=>'TOGO', 240 | 'TK'=>'TOKELAU', 241 | 'TO'=>'TONGA', 242 | 'TT'=>'TRINIDAD AND TOBAGO', 243 | 'TN'=>'TUNISIA', 244 | 'TR'=>'TURKEY', 245 | 'TM'=>'TURKMENISTAN', 246 | 'TC'=>'TURKS AND CAICOS ISLANDS', 247 | 'TV'=>'TUVALU', 248 | 'UG'=>'UGANDA', 249 | 'UA'=>'UKRAINE', 250 | 'AE'=>'UNITED ARAB EMIRATES', 251 | 'GB'=>'UNITED KINGDOM', 252 | 'UK'=>'UNITED KINGDOM', 253 | 'UM'=>'UNITED STATES MINOR OUTLYING ISLANDS', 254 | 'US'=>'UNITED STATES', 255 | 'UY'=>'URUGUAY', 256 | 'UZ'=>'UZBEKISTAN', 257 | 'VU'=>'VANUATU', 258 | 'VE'=>'VENEZUELA', 259 | 'VN'=>'VIET NAM', 260 | 'VG'=>'VIRGIN ISLANDS (BRITISH)', 261 | 'VI'=>'VIRGIN ISLANDS (U.S.)', 262 | 'WF'=>'WALLIS AND FUTUNA ISLANDS', 263 | 'EH'=>'WESTERN SAHARA', 264 | 'YE'=>'YEMEN', 265 | 'ZM'=>'ZAMBIA', 266 | 'ZW'=>'ZIMBABWE', 267 | 'AX'=>'ALAND ISLANDS', 268 | 'MF'=>'SAINT MARTIN' 269 | ); 270 | 271 | //properties 272 | private $property = array( 273 | 'country' => false, 274 | 'countryCode' => false 275 | ); 276 | 277 | //methods 278 | private function appendToFile($db) 279 | { 280 | foreach ($db AS $piece=>$entries) 281 | { 282 | $filename = $this->dir . $piece . '.php'; 283 | 284 | if (!file_exists($filename)) 285 | { 286 | $f = fopen($filename, 'w'); 287 | fputs($f, '$entries) 338 | { 339 | $f = fopen($this->dir . $piece . '.php', 'w'); 340 | fputs($f, '$entry) 343 | { 344 | fputs($f, "array('" . $entry[0] . "','" . $entry[1] . "','" . $entry[2] . "'),\n"); 345 | } 346 | 347 | fputs($f, ');'); 348 | fclose($f); 349 | } 350 | } 351 | 352 | public function parseCSV2($filename = 'IpToCountry.csv') 353 | { 354 | $f = fopen($filename, 'r'); 355 | $db = array(); 356 | $dbSize = 0; 357 | 358 | //parse into array 359 | while (!feof($f)) 360 | { 361 | $s = fgets($f); 362 | 363 | if (substr($s, 0, 1) == '#') continue; 364 | 365 | $temp = explode(',', $s); 366 | if (count($temp)<7) continue; 367 | 368 | list($from, $to, $a, $b, $code, $c, $country) = $temp; 369 | 370 | $from = trim($from, '"'); 371 | $to = trim($to, '"'); 372 | $code = trim($code, '"'); 373 | 374 | $piece = substr($from, 0, 3); 375 | 376 | $db[$piece][] = array($from, $to, $code); 377 | $dbSize++; 378 | 379 | if ($dbSize>100) 380 | { 381 | $this->appendToFile($db); 382 | unset($db); 383 | $dbSize = 0; 384 | } 385 | } 386 | fclose($f); 387 | 388 | $this->appendToFile($db); 389 | 390 | //now "finish" all files 391 | if (is_dir($this->dir)) 392 | { 393 | if ($dh = opendir($this->dir)) 394 | { 395 | while (($file = readdir($dh)) !== false) 396 | { 397 | if ($file == '.' or $file == '..') 398 | { 399 | continue; 400 | } 401 | $this->finishFile($this->dir . $file); 402 | } 403 | closedir($dh); 404 | } 405 | } 406 | 407 | //echo memory_get_usage(); 408 | } 409 | 410 | public function load($ip) 411 | { 412 | $ip = floatval($this->ip2int($ip)); 413 | $piece = substr($ip, 0, 3); 414 | 415 | if (!file_exists($this->dir . $piece . '.php')) 416 | { 417 | $this->property['countryCode'] = '?'; 418 | $this->property['country'] = '?'; 419 | 420 | return $this; 421 | } 422 | 423 | include $this->dir . $piece . '.php'; 424 | 425 | foreach ($entries AS $e) 426 | { 427 | $e[0] = floatval($e[0]); 428 | 429 | if ($e[0] <= $ip and $e[1] >= $ip) 430 | { 431 | $this->property['countryCode'] = $e[2]; 432 | $this->property['country'] = $this->codes[$e[2]]; 433 | return $this; 434 | } 435 | } 436 | 437 | $this->property['countryCode'] = '?'; 438 | $this->property['country'] = '?'; 439 | 440 | return $this; 441 | } 442 | 443 | private function ip2int($ip) 444 | { 445 | //In case you wonder how it works... 446 | //$t = explode('.', $ip); 447 | //return $t[0] * 256*256*256 + $t[1]*256*256 + $t[2]*256 + $t[3]; 448 | return sprintf("%u\n", ip2long($ip)); 449 | } 450 | 451 | public function __get($var) 452 | { 453 | if (isset($this->property[$var])) 454 | { 455 | if ($this->property[$var] != false) 456 | { 457 | return $this->property[$var]; 458 | } 459 | $this->error = 'No IP specified'; 460 | } 461 | return false; 462 | } 463 | 464 | } --------------------------------------------------------------------------------