PHP如何使用GeoIP数据库

1、首先下载GeoIP的IP库。参考《利用GeoIP数据库及API进行地理定位查询》。下载后解压,得到一个GeoIP.dat文件

2、新建一个文件geoip.inc。内容为

   1 <?php
   2 
   3 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
   4 /* geoip.inc
   5  *
   6  * Copyright (C) 2007 MaxMind LLC
   7  *
   8  * This library is free software; you can redistribute it and/or
   9  * modify it under the terms of the GNU Lesser General Public
  10  * License as published by the Free Software Foundation; either
  11  * version 2.1 of the License, or (at your option) any later version.
  12  *
  13  * This library is distributed in the hope that it will be useful,
  14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16  * Lesser General Public License for more details.
  17  *
  18  * You should have received a copy of the GNU Lesser General Public
  19  * License along with this library; if not, write to the Free Software
  20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21  */
  22 
  23 define("GEOIP_COUNTRY_BEGIN", 16776960);
  24 define("GEOIP_STATE_BEGIN_REV0", 16700000);
  25 define("GEOIP_STATE_BEGIN_REV1", 16000000);
  26 define("GEOIP_STANDARD", 0);
  27 define("GEOIP_MEMORY_CACHE", 1);
  28 define("GEOIP_SHARED_MEMORY", 2);
  29 define("STRUCTURE_INFO_MAX_SIZE", 20);
  30 define("DATABASE_INFO_MAX_SIZE", 100);
  31 define("GEOIP_COUNTRY_EDITION", 1);
  32 define("GEOIP_PROXY_EDITION", 8);
  33 define("GEOIP_ASNUM_EDITION", 9);
  34 define("GEOIP_NETSPEED_EDITION", 10);
  35 define("GEOIP_REGION_EDITION_REV0", 7);
  36 define("GEOIP_REGION_EDITION_REV1", 3);
  37 define("GEOIP_CITY_EDITION_REV0", 6);
  38 define("GEOIP_CITY_EDITION_REV1", 2);
  39 define("GEOIP_ORG_EDITION", 5);
  40 define("GEOIP_ISP_EDITION", 4);
  41 define("SEGMENT_RECORD_LENGTH", 3);
  42 define("STANDARD_RECORD_LENGTH", 3);
  43 define("ORG_RECORD_LENGTH", 4);
  44 define("MAX_RECORD_LENGTH", 4);
  45 define("MAX_ORG_RECORD_LENGTH", 300);
  46 define("GEOIP_SHM_KEY", 0x4f415401);
  47 define("US_OFFSET", 1);
  48 define("CANADA_OFFSET", 677);
  49 define("WORLD_OFFSET", 1353);
  50 define("FIPS_RANGE", 360);
  51 define("GEOIP_UNKNOWN_SPEED", 0);
  52 define("GEOIP_DIALUP_SPEED", 1);
  53 define("GEOIP_CABLEDSL_SPEED", 2);
  54 define("GEOIP_CORPORATE_SPEED", 3);
  55 define("GEOIP_DOMAIN_EDITION", 11);
  56 define("GEOIP_COUNTRY_EDITION_V6", 12);
  57 define("GEOIP_LOCATIONA_EDITION", 13);
  58 define("GEOIP_ACCURACYRADIUS_EDITION", 14);
  59 define("GEOIP_CITYCOMBINED_EDITION", 15);
  60 define("GEOIP_CITY_EDITION_REV1_V6", 30);
  61 define("GEOIP_CITY_EDITION_REV0_V6", 31);
  62 define("GEOIP_NETSPEED_EDITION_REV1", 32);
  63 define("GEOIP_NETSPEED_EDITION_REV1_V6", 33);
  64 define("GEOIP_USERTYPE_EDITION", 28);
  65 define("GEOIP_USERTYPE_EDITION_V6", 29);
  66 define("GEOIP_ASNUM_EDITION_V6", 21);
  67 define("GEOIP_ISP_EDITION_V6", 22);
  68 define("GEOIP_ORG_EDITION_V6", 23);
  69 define("GEOIP_DOMAIN_EDITION_V6", 24);
  70 
  71 define("CITYCOMBINED_FIXED_RECORD", 7);
  72 
  73 class GeoIP
  74 {
  75     public $flags;
  76     public $filehandle;
  77     public $memory_buffer;
  78     public $databaseType;
  79     public $databaseSegments;
  80     public $record_length;
  81     public $shmid;
  82     public $GEOIP_COUNTRY_CODE_TO_NUMBER = array(
  83         "" => 0,
  84         "AP" => 1,
  85         "EU" => 2,
  86         "AD" => 3,
  87         "AE" => 4,
  88         "AF" => 5,
  89         "AG" => 6,
  90         "AI" => 7,
  91         "AL" => 8,
  92         "AM" => 9,
  93         "CW" => 10,
  94         "AO" => 11,
  95         "AQ" => 12,
  96         "AR" => 13,
  97         "AS" => 14,
  98         "AT" => 15,
  99         "AU" => 16,
 100         "AW" => 17,
 101         "AZ" => 18,
 102         "BA" => 19,
 103         "BB" => 20,
 104         "BD" => 21,
 105         "BE" => 22,
 106         "BF" => 23,
 107         "BG" => 24,
 108         "BH" => 25,
 109         "BI" => 26,
 110         "BJ" => 27,
 111         "BM" => 28,
 112         "BN" => 29,
 113         "BO" => 30,
 114         "BR" => 31,
 115         "BS" => 32,
 116         "BT" => 33,
 117         "BV" => 34,
 118         "BW" => 35,
 119         "BY" => 36,
 120         "BZ" => 37,
 121         "CA" => 38,
 122         "CC" => 39,
 123         "CD" => 40,
 124         "CF" => 41,
 125         "CG" => 42,
 126         "CH" => 43,
 127         "CI" => 44,
 128         "CK" => 45,
 129         "CL" => 46,
 130         "CM" => 47,
 131         "CN" => 48,
 132         "CO" => 49,
 133         "CR" => 50,
 134         "CU" => 51,
 135         "CV" => 52,
 136         "CX" => 53,
 137         "CY" => 54,
 138         "CZ" => 55,
 139         "DE" => 56,
 140         "DJ" => 57,
 141         "DK" => 58,
 142         "DM" => 59,
 143         "DO" => 60,
 144         "DZ" => 61,
 145         "EC" => 62,
 146         "EE" => 63,
 147         "EG" => 64,
 148         "EH" => 65,
 149         "ER" => 66,
 150         "ES" => 67,
 151         "ET" => 68,
 152         "FI" => 69,
 153         "FJ" => 70,
 154         "FK" => 71,
 155         "FM" => 72,
 156         "FO" => 73,
 157         "FR" => 74,
 158         "SX" => 75,
 159         "GA" => 76,
 160         "GB" => 77,
 161         "GD" => 78,
 162         "GE" => 79,
 163         "GF" => 80,
 164         "GH" => 81,
 165         "GI" => 82,
 166         "GL" => 83,
 167         "GM" => 84,
 168         "GN" => 85,
 169         "GP" => 86,
 170         "GQ" => 87,
 171         "GR" => 88,
 172         "GS" => 89,
 173         "GT" => 90,
 174         "GU" => 91,
 175         "GW" => 92,
 176         "GY" => 93,
 177         "HK" => 94,
 178         "HM" => 95,
 179         "HN" => 96,
 180         "HR" => 97,
 181         "HT" => 98,
 182         "HU" => 99,
 183         "ID" => 100,
 184         "IE" => 101,
 185         "IL" => 102,
 186         "IN" => 103,
 187         "IO" => 104,
 188         "IQ" => 105,
 189         "IR" => 106,
 190         "IS" => 107,
 191         "IT" => 108,
 192         "JM" => 109,
 193         "JO" => 110,
 194         "JP" => 111,
 195         "KE" => 112,
 196         "KG" => 113,
 197         "KH" => 114,
 198         "KI" => 115,
 199         "KM" => 116,
 200         "KN" => 117,
 201         "KP" => 118,
 202         "KR" => 119,
 203         "KW" => 120,
 204         "KY" => 121,
 205         "KZ" => 122,
 206         "LA" => 123,
 207         "LB" => 124,
 208         "LC" => 125,
 209         "LI" => 126,
 210         "LK" => 127,
 211         "LR" => 128,
 212         "LS" => 129,
 213         "LT" => 130,
 214         "LU" => 131,
 215         "LV" => 132,
 216         "LY" => 133,
 217         "MA" => 134,
 218         "MC" => 135,
 219         "MD" => 136,
 220         "MG" => 137,
 221         "MH" => 138,
 222         "MK" => 139,
 223         "ML" => 140,
 224         "MM" => 141,
 225         "MN" => 142,
 226         "MO" => 143,
 227         "MP" => 144,
 228         "MQ" => 145,
 229         "MR" => 146,
 230         "MS" => 147,
 231         "MT" => 148,
 232         "MU" => 149,
 233         "MV" => 150,
 234         "MW" => 151,
 235         "MX" => 152,
 236         "MY" => 153,
 237         "MZ" => 154,
 238         "NA" => 155,
 239         "NC" => 156,
 240         "NE" => 157,
 241         "NF" => 158,
 242         "NG" => 159,
 243         "NI" => 160,
 244         "NL" => 161,
 245         "NO" => 162,
 246         "NP" => 163,
 247         "NR" => 164,
 248         "NU" => 165,
 249         "NZ" => 166,
 250         "OM" => 167,
 251         "PA" => 168,
 252         "PE" => 169,
 253         "PF" => 170,
 254         "PG" => 171,
 255         "PH" => 172,
 256         "PK" => 173,
 257         "PL" => 174,
 258         "PM" => 175,
 259         "PN" => 176,
 260         "PR" => 177,
 261         "PS" => 178,
 262         "PT" => 179,
 263         "PW" => 180,
 264         "PY" => 181,
 265         "QA" => 182,
 266         "RE" => 183,
 267         "RO" => 184,
 268         "RU" => 185,
 269         "RW" => 186,
 270         "SA" => 187,
 271         "SB" => 188,
 272         "SC" => 189,
 273         "SD" => 190,
 274         "SE" => 191,
 275         "SG" => 192,
 276         "SH" => 193,
 277         "SI" => 194,
 278         "SJ" => 195,
 279         "SK" => 196,
 280         "SL" => 197,
 281         "SM" => 198,
 282         "SN" => 199,
 283         "SO" => 200,
 284         "SR" => 201,
 285         "ST" => 202,
 286         "SV" => 203,
 287         "SY" => 204,
 288         "SZ" => 205,
 289         "TC" => 206,
 290         "TD" => 207,
 291         "TF" => 208,
 292         "TG" => 209,
 293         "TH" => 210,
 294         "TJ" => 211,
 295         "TK" => 212,
 296         "TM" => 213,
 297         "TN" => 214,
 298         "TO" => 215,
 299         "TL" => 216,
 300         "TR" => 217,
 301         "TT" => 218,
 302         "TV" => 219,
 303         "TW" => 220,
 304         "TZ" => 221,
 305         "UA" => 222,
 306         "UG" => 223,
 307         "UM" => 224,
 308         "US" => 225,
 309         "UY" => 226,
 310         "UZ" => 227,
 311         "VA" => 228,
 312         "VC" => 229,
 313         "VE" => 230,
 314         "VG" => 231,
 315         "VI" => 232,
 316         "VN" => 233,
 317         "VU" => 234,
 318         "WF" => 235,
 319         "WS" => 236,
 320         "YE" => 237,
 321         "YT" => 238,
 322         "RS" => 239,
 323         "ZA" => 240,
 324         "ZM" => 241,
 325         "ME" => 242,
 326         "ZW" => 243,
 327         "A1" => 244,
 328         "A2" => 245,
 329         "O1" => 246,
 330         "AX" => 247,
 331         "GG" => 248,
 332         "IM" => 249,
 333         "JE" => 250,
 334         "BL" => 251,
 335         "MF" => 252,
 336         "BQ" => 253,
 337         "SS" => 254
 338     );
 339 
 340     public $GEOIP_COUNTRY_CODES = array(
 341         "",
 342         "AP",
 343         "EU",
 344         "AD",
 345         "AE",
 346         "AF",
 347         "AG",
 348         "AI",
 349         "AL",
 350         "AM",
 351         "CW",
 352         "AO",
 353         "AQ",
 354         "AR",
 355         "AS",
 356         "AT",
 357         "AU",
 358         "AW",
 359         "AZ",
 360         "BA",
 361         "BB",
 362         "BD",
 363         "BE",
 364         "BF",
 365         "BG",
 366         "BH",
 367         "BI",
 368         "BJ",
 369         "BM",
 370         "BN",
 371         "BO",
 372         "BR",
 373         "BS",
 374         "BT",
 375         "BV",
 376         "BW",
 377         "BY",
 378         "BZ",
 379         "CA",
 380         "CC",
 381         "CD",
 382         "CF",
 383         "CG",
 384         "CH",
 385         "CI",
 386         "CK",
 387         "CL",
 388         "CM",
 389         "CN",
 390         "CO",
 391         "CR",
 392         "CU",
 393         "CV",
 394         "CX",
 395         "CY",
 396         "CZ",
 397         "DE",
 398         "DJ",
 399         "DK",
 400         "DM",
 401         "DO",
 402         "DZ",
 403         "EC",
 404         "EE",
 405         "EG",
 406         "EH",
 407         "ER",
 408         "ES",
 409         "ET",
 410         "FI",
 411         "FJ",
 412         "FK",
 413         "FM",
 414         "FO",
 415         "FR",
 416         "SX",
 417         "GA",
 418         "GB",
 419         "GD",
 420         "GE",
 421         "GF",
 422         "GH",
 423         "GI",
 424         "GL",
 425         "GM",
 426         "GN",
 427         "GP",
 428         "GQ",
 429         "GR",
 430         "GS",
 431         "GT",
 432         "GU",
 433         "GW",
 434         "GY",
 435         "HK",
 436         "HM",
 437         "HN",
 438         "HR",
 439         "HT",
 440         "HU",
 441         "ID",
 442         "IE",
 443         "IL",
 444         "IN",
 445         "IO",
 446         "IQ",
 447         "IR",
 448         "IS",
 449         "IT",
 450         "JM",
 451         "JO",
 452         "JP",
 453         "KE",
 454         "KG",
 455         "KH",
 456         "KI",
 457         "KM",
 458         "KN",
 459         "KP",
 460         "KR",
 461         "KW",
 462         "KY",
 463         "KZ",
 464         "LA",
 465         "LB",
 466         "LC",
 467         "LI",
 468         "LK",
 469         "LR",
 470         "LS",
 471         "LT",
 472         "LU",
 473         "LV",
 474         "LY",
 475         "MA",
 476         "MC",
 477         "MD",
 478         "MG",
 479         "MH",
 480         "MK",
 481         "ML",
 482         "MM",
 483         "MN",
 484         "MO",
 485         "MP",
 486         "MQ",
 487         "MR",
 488         "MS",
 489         "MT",
 490         "MU",
 491         "MV",
 492         "MW",
 493         "MX",
 494         "MY",
 495         "MZ",
 496         "NA",
 497         "NC",
 498         "NE",
 499         "NF",
 500         "NG",
 501         "NI",
 502         "NL",
 503         "NO",
 504         "NP",
 505         "NR",
 506         "NU",
 507         "NZ",
 508         "OM",
 509         "PA",
 510         "PE",
 511         "PF",
 512         "PG",
 513         "PH",
 514         "PK",
 515         "PL",
 516         "PM",
 517         "PN",
 518         "PR",
 519         "PS",
 520         "PT",
 521         "PW",
 522         "PY",
 523         "QA",
 524         "RE",
 525         "RO",
 526         "RU",
 527         "RW",
 528         "SA",
 529         "SB",
 530         "SC",
 531         "SD",
 532         "SE",
 533         "SG",
 534         "SH",
 535         "SI",
 536         "SJ",
 537         "SK",
 538         "SL",
 539         "SM",
 540         "SN",
 541         "SO",
 542         "SR",
 543         "ST",
 544         "SV",
 545         "SY",
 546         "SZ",
 547         "TC",
 548         "TD",
 549         "TF",
 550         "TG",
 551         "TH",
 552         "TJ",
 553         "TK",
 554         "TM",
 555         "TN",
 556         "TO",
 557         "TL",
 558         "TR",
 559         "TT",
 560         "TV",
 561         "TW",
 562         "TZ",
 563         "UA",
 564         "UG",
 565         "UM",
 566         "US",
 567         "UY",
 568         "UZ",
 569         "VA",
 570         "VC",
 571         "VE",
 572         "VG",
 573         "VI",
 574         "VN",
 575         "VU",
 576         "WF",
 577         "WS",
 578         "YE",
 579         "YT",
 580         "RS",
 581         "ZA",
 582         "ZM",
 583         "ME",
 584         "ZW",
 585         "A1",
 586         "A2",
 587         "O1",
 588         "AX",
 589         "GG",
 590         "IM",
 591         "JE",
 592         "BL",
 593         "MF",
 594         "BQ",
 595         "SS",
 596         "O1"
 597     );
 598 
 599     public $GEOIP_COUNTRY_CODES3 = array(
 600         "",
 601         "AP",
 602         "EU",
 603         "AND",
 604         "ARE",
 605         "AFG",
 606         "ATG",
 607         "AIA",
 608         "ALB",
 609         "ARM",
 610         "CUW",
 611         "AGO",
 612         "ATA",
 613         "ARG",
 614         "ASM",
 615         "AUT",
 616         "AUS",
 617         "ABW",
 618         "AZE",
 619         "BIH",
 620         "BRB",
 621         "BGD",
 622         "BEL",
 623         "BFA",
 624         "BGR",
 625         "BHR",
 626         "BDI",
 627         "BEN",
 628         "BMU",
 629         "BRN",
 630         "BOL",
 631         "BRA",
 632         "BHS",
 633         "BTN",
 634         "BVT",
 635         "BWA",
 636         "BLR",
 637         "BLZ",
 638         "CAN",
 639         "CCK",
 640         "COD",
 641         "CAF",
 642         "COG",
 643         "CHE",
 644         "CIV",
 645         "COK",
 646         "CHL",
 647         "CMR",
 648         "CHN",
 649         "COL",
 650         "CRI",
 651         "CUB",
 652         "CPV",
 653         "CXR",
 654         "CYP",
 655         "CZE",
 656         "DEU",
 657         "DJI",
 658         "DNK",
 659         "DMA",
 660         "DOM",
 661         "DZA",
 662         "ECU",
 663         "EST",
 664         "EGY",
 665         "ESH",
 666         "ERI",
 667         "ESP",
 668         "ETH",
 669         "FIN",
 670         "FJI",
 671         "FLK",
 672         "FSM",
 673         "FRO",
 674         "FRA",
 675         "SXM",
 676         "GAB",
 677         "GBR",
 678         "GRD",
 679         "GEO",
 680         "GUF",
 681         "GHA",
 682         "GIB",
 683         "GRL",
 684         "GMB",
 685         "GIN",
 686         "GLP",
 687         "GNQ",
 688         "GRC",
 689         "SGS",
 690         "GTM",
 691         "GUM",
 692         "GNB",
 693         "GUY",
 694         "HKG",
 695         "HMD",
 696         "HND",
 697         "HRV",
 698         "HTI",
 699         "HUN",
 700         "IDN",
 701         "IRL",
 702         "ISR",
 703         "IND",
 704         "IOT",
 705         "IRQ",
 706         "IRN",
 707         "ISL",
 708         "ITA",
 709         "JAM",
 710         "JOR",
 711         "JPN",
 712         "KEN",
 713         "KGZ",
 714         "KHM",
 715         "KIR",
 716         "COM",
 717         "KNA",
 718         "PRK",
 719         "KOR",
 720         "KWT",
 721         "CYM",
 722         "KAZ",
 723         "LAO",
 724         "LBN",
 725         "LCA",
 726         "LIE",
 727         "LKA",
 728         "LBR",
 729         "LSO",
 730         "LTU",
 731         "LUX",
 732         "LVA",
 733         "LBY",
 734         "MAR",
 735         "MCO",
 736         "MDA",
 737         "MDG",
 738         "MHL",
 739         "MKD",
 740         "MLI",
 741         "MMR",
 742         "MNG",
 743         "MAC",
 744         "MNP",
 745         "MTQ",
 746         "MRT",
 747         "MSR",
 748         "MLT",
 749         "MUS",
 750         "MDV",
 751         "MWI",
 752         "MEX",
 753         "MYS",
 754         "MOZ",
 755         "NAM",
 756         "NCL",
 757         "NER",
 758         "NFK",
 759         "NGA",
 760         "NIC",
 761         "NLD",
 762         "NOR",
 763         "NPL",
 764         "NRU",
 765         "NIU",
 766         "NZL",
 767         "OMN",
 768         "PAN",
 769         "PER",
 770         "PYF",
 771         "PNG",
 772         "PHL",
 773         "PAK",
 774         "POL",
 775         "SPM",
 776         "PCN",
 777         "PRI",
 778         "PSE",
 779         "PRT",
 780         "PLW",
 781         "PRY",
 782         "QAT",
 783         "REU",
 784         "ROU",
 785         "RUS",
 786         "RWA",
 787         "SAU",
 788         "SLB",
 789         "SYC",
 790         "SDN",
 791         "SWE",
 792         "SGP",
 793         "SHN",
 794         "SVN",
 795         "SJM",
 796         "SVK",
 797         "SLE",
 798         "SMR",
 799         "SEN",
 800         "SOM",
 801         "SUR",
 802         "STP",
 803         "SLV",
 804         "SYR",
 805         "SWZ",
 806         "TCA",
 807         "TCD",
 808         "ATF",
 809         "TGO",
 810         "THA",
 811         "TJK",
 812         "TKL",
 813         "TKM",
 814         "TUN",
 815         "TON",
 816         "TLS",
 817         "TUR",
 818         "TTO",
 819         "TUV",
 820         "TWN",
 821         "TZA",
 822         "UKR",
 823         "UGA",
 824         "UMI",
 825         "USA",
 826         "URY",
 827         "UZB",
 828         "VAT",
 829         "VCT",
 830         "VEN",
 831         "VGB",
 832         "VIR",
 833         "VNM",
 834         "VUT",
 835         "WLF",
 836         "WSM",
 837         "YEM",
 838         "MYT",
 839         "SRB",
 840         "ZAF",
 841         "ZMB",
 842         "MNE",
 843         "ZWE",
 844         "A1",
 845         "A2",
 846         "O1",
 847         "ALA",
 848         "GGY",
 849         "IMN",
 850         "JEY",
 851         "BLM",
 852         "MAF",
 853         "BES",
 854         "SSD",
 855         "O1"
 856     );
 857 
 858     public $GEOIP_COUNTRY_NAMES = array(
 859         "",
 860         "Asia/Pacific Region",
 861         "Europe",
 862         "Andorra",
 863         "United Arab Emirates",
 864         "Afghanistan",
 865         "Antigua and Barbuda",
 866         "Anguilla",
 867         "Albania",
 868         "Armenia",
 869         "Curacao",
 870         "Angola",
 871         "Antarctica",
 872         "Argentina",
 873         "American Samoa",
 874         "Austria",
 875         "Australia",
 876         "Aruba",
 877         "Azerbaijan",
 878         "Bosnia and Herzegovina",
 879         "Barbados",
 880         "Bangladesh",
 881         "Belgium",
 882         "Burkina Faso",
 883         "Bulgaria",
 884         "Bahrain",
 885         "Burundi",
 886         "Benin",
 887         "Bermuda",
 888         "Brunei Darussalam",
 889         "Bolivia",
 890         "Brazil",
 891         "Bahamas",
 892         "Bhutan",
 893         "Bouvet Island",
 894         "Botswana",
 895         "Belarus",
 896         "Belize",
 897         "Canada",
 898         "Cocos (Keeling) Islands",
 899         "Congo, The Democratic Republic of the",
 900         "Central African Republic",
 901         "Congo",
 902         "Switzerland",
 903         "Cote D'Ivoire",
 904         "Cook Islands",
 905         "Chile",
 906         "Cameroon",
 907         "China",
 908         "Colombia",
 909         "Costa Rica",
 910         "Cuba",
 911         "Cape Verde",
 912         "Christmas Island",
 913         "Cyprus",
 914         "Czech Republic",
 915         "Germany",
 916         "Djibouti",
 917         "Denmark",
 918         "Dominica",
 919         "Dominican Republic",
 920         "Algeria",
 921         "Ecuador",
 922         "Estonia",
 923         "Egypt",
 924         "Western Sahara",
 925         "Eritrea",
 926         "Spain",
 927         "Ethiopia",
 928         "Finland",
 929         "Fiji",
 930         "Falkland Islands (Malvinas)",
 931         "Micronesia, Federated States of",
 932         "Faroe Islands",
 933         "France",
 934         "Sint Maarten (Dutch part)",
 935         "Gabon",
 936         "United Kingdom",
 937         "Grenada",
 938         "Georgia",
 939         "French Guiana",
 940         "Ghana",
 941         "Gibraltar",
 942         "Greenland",
 943         "Gambia",
 944         "Guinea",
 945         "Guadeloupe",
 946         "Equatorial Guinea",
 947         "Greece",
 948         "South Georgia and the South Sandwich Islands",
 949         "Guatemala",
 950         "Guam",
 951         "Guinea-Bissau",
 952         "Guyana",
 953         "Hong Kong",
 954         "Heard Island and McDonald Islands",
 955         "Honduras",
 956         "Croatia",
 957         "Haiti",
 958         "Hungary",
 959         "Indonesia",
 960         "Ireland",
 961         "Israel",
 962         "India",
 963         "British Indian Ocean Territory",
 964         "Iraq",
 965         "Iran, Islamic Republic of",
 966         "Iceland",
 967         "Italy",
 968         "Jamaica",
 969         "Jordan",
 970         "Japan",
 971         "Kenya",
 972         "Kyrgyzstan",
 973         "Cambodia",
 974         "Kiribati",
 975         "Comoros",
 976         "Saint Kitts and Nevis",
 977         "Korea, Democratic People's Republic of",
 978         "Korea, Republic of",
 979         "Kuwait",
 980         "Cayman Islands",
 981         "Kazakhstan",
 982         "Lao People's Democratic Republic",
 983         "Lebanon",
 984         "Saint Lucia",
 985         "Liechtenstein",
 986         "Sri Lanka",
 987         "Liberia",
 988         "Lesotho",
 989         "Lithuania",
 990         "Luxembourg",
 991         "Latvia",
 992         "Libya",
 993         "Morocco",
 994         "Monaco",
 995         "Moldova, Republic of",
 996         "Madagascar",
 997         "Marshall Islands",
 998         "Macedonia",
 999         "Mali",
1000         "Myanmar",
1001         "Mongolia",
1002         "Macau",
1003         "Northern Mariana Islands",
1004         "Martinique",
1005         "Mauritania",
1006         "Montserrat",
1007         "Malta",
1008         "Mauritius",
1009         "Maldives",
1010         "Malawi",
1011         "Mexico",
1012         "Malaysia",
1013         "Mozambique",
1014         "Namibia",
1015         "New Caledonia",
1016         "Niger",
1017         "Norfolk Island",
1018         "Nigeria",
1019         "Nicaragua",
1020         "Netherlands",
1021         "Norway",
1022         "Nepal",
1023         "Nauru",
1024         "Niue",
1025         "New Zealand",
1026         "Oman",
1027         "Panama",
1028         "Peru",
1029         "French Polynesia",
1030         "Papua New Guinea",
1031         "Philippines",
1032         "Pakistan",
1033         "Poland",
1034         "Saint Pierre and Miquelon",
1035         "Pitcairn Islands",
1036         "Puerto Rico",
1037         "Palestinian Territory",
1038         "Portugal",
1039         "Palau",
1040         "Paraguay",
1041         "Qatar",
1042         "Reunion",
1043         "Romania",
1044         "Russian Federation",
1045         "Rwanda",
1046         "Saudi Arabia",
1047         "Solomon Islands",
1048         "Seychelles",
1049         "Sudan",
1050         "Sweden",
1051         "Singapore",
1052         "Saint Helena",
1053         "Slovenia",
1054         "Svalbard and Jan Mayen",
1055         "Slovakia",
1056         "Sierra Leone",
1057         "San Marino",
1058         "Senegal",
1059         "Somalia",
1060         "Suriname",
1061         "Sao Tome and Principe",
1062         "El Salvador",
1063         "Syrian Arab Republic",
1064         "Swaziland",
1065         "Turks and Caicos Islands",
1066         "Chad",
1067         "French Southern Territories",
1068         "Togo",
1069         "Thailand",
1070         "Tajikistan",
1071         "Tokelau",
1072         "Turkmenistan",
1073         "Tunisia",
1074         "Tonga",
1075         "Timor-Leste",
1076         "Turkey",
1077         "Trinidad and Tobago",
1078         "Tuvalu",
1079         "Taiwan",
1080         "Tanzania, United Republic of",
1081         "Ukraine",
1082         "Uganda",
1083         "United States Minor Outlying Islands",
1084         "United States",
1085         "Uruguay",
1086         "Uzbekistan",
1087         "Holy See (Vatican City State)",
1088         "Saint Vincent and the Grenadines",
1089         "Venezuela",
1090         "Virgin Islands, British",
1091         "Virgin Islands, U.S.",
1092         "Vietnam",
1093         "Vanuatu",
1094         "Wallis and Futuna",
1095         "Samoa",
1096         "Yemen",
1097         "Mayotte",
1098         "Serbia",
1099         "South Africa",
1100         "Zambia",
1101         "Montenegro",
1102         "Zimbabwe",
1103         "Anonymous Proxy",
1104         "Satellite Provider",
1105         "Other",
1106         "Aland Islands",
1107         "Guernsey",
1108         "Isle of Man",
1109         "Jersey",
1110         "Saint Barthelemy",
1111         "Saint Martin",
1112         "Bonaire, Saint Eustatius and Saba",
1113         "South Sudan",
1114         "Other"
1115     );
1116 
1117     public $GEOIP_CONTINENT_CODES = array(
1118         "--",
1119         "AS",
1120         "EU",
1121         "EU",
1122         "AS",
1123         "AS",
1124         "NA",
1125         "NA",
1126         "EU",
1127         "AS",
1128         "NA",
1129         "AF",
1130         "AN",
1131         "SA",
1132         "OC",
1133         "EU",
1134         "OC",
1135         "NA",
1136         "AS",
1137         "EU",
1138         "NA",
1139         "AS",
1140         "EU",
1141         "AF",
1142         "EU",
1143         "AS",
1144         "AF",
1145         "AF",
1146         "NA",
1147         "AS",
1148         "SA",
1149         "SA",
1150         "NA",
1151         "AS",
1152         "AN",
1153         "AF",
1154         "EU",
1155         "NA",
1156         "NA",
1157         "AS",
1158         "AF",
1159         "AF",
1160         "AF",
1161         "EU",
1162         "AF",
1163         "OC",
1164         "SA",
1165         "AF",
1166         "AS",
1167         "SA",
1168         "NA",
1169         "NA",
1170         "AF",
1171         "AS",
1172         "AS",
1173         "EU",
1174         "EU",
1175         "AF",
1176         "EU",
1177         "NA",
1178         "NA",
1179         "AF",
1180         "SA",
1181         "EU",
1182         "AF",
1183         "AF",
1184         "AF",
1185         "EU",
1186         "AF",
1187         "EU",
1188         "OC",
1189         "SA",
1190         "OC",
1191         "EU",
1192         "EU",
1193         "NA",
1194         "AF",
1195         "EU",
1196         "NA",
1197         "AS",
1198         "SA",
1199         "AF",
1200         "EU",
1201         "NA",
1202         "AF",
1203         "AF",
1204         "NA",
1205         "AF",
1206         "EU",
1207         "AN",
1208         "NA",
1209         "OC",
1210         "AF",
1211         "SA",
1212         "AS",
1213         "AN",
1214         "NA",
1215         "EU",
1216         "NA",
1217         "EU",
1218         "AS",
1219         "EU",
1220         "AS",
1221         "AS",
1222         "AS",
1223         "AS",
1224         "AS",
1225         "EU",
1226         "EU",
1227         "NA",
1228         "AS",
1229         "AS",
1230         "AF",
1231         "AS",
1232         "AS",
1233         "OC",
1234         "AF",
1235         "NA",
1236         "AS",
1237         "AS",
1238         "AS",
1239         "NA",
1240         "AS",
1241         "AS",
1242         "AS",
1243         "NA",
1244         "EU",
1245         "AS",
1246         "AF",
1247         "AF",
1248         "EU",
1249         "EU",
1250         "EU",
1251         "AF",
1252         "AF",
1253         "EU",
1254         "EU",
1255         "AF",
1256         "OC",
1257         "EU",
1258         "AF",
1259         "AS",
1260         "AS",
1261         "AS",
1262         "OC",
1263         "NA",
1264         "AF",
1265         "NA",
1266         "EU",
1267         "AF",
1268         "AS",
1269         "AF",
1270         "NA",
1271         "AS",
1272         "AF",
1273         "AF",
1274         "OC",
1275         "AF",
1276         "OC",
1277         "AF",
1278         "NA",
1279         "EU",
1280         "EU",
1281         "AS",
1282         "OC",
1283         "OC",
1284         "OC",
1285         "AS",
1286         "NA",
1287         "SA",
1288         "OC",
1289         "OC",
1290         "AS",
1291         "AS",
1292         "EU",
1293         "NA",
1294         "OC",
1295         "NA",
1296         "AS",
1297         "EU",
1298         "OC",
1299         "SA",
1300         "AS",
1301         "AF",
1302         "EU",
1303         "EU",
1304         "AF",
1305         "AS",
1306         "OC",
1307         "AF",
1308         "AF",
1309         "EU",
1310         "AS",
1311         "AF",
1312         "EU",
1313         "EU",
1314         "EU",
1315         "AF",
1316         "EU",
1317         "AF",
1318         "AF",
1319         "SA",
1320         "AF",
1321         "NA",
1322         "AS",
1323         "AF",
1324         "NA",
1325         "AF",
1326         "AN",
1327         "AF",
1328         "AS",
1329         "AS",
1330         "OC",
1331         "AS",
1332         "AF",
1333         "OC",
1334         "AS",
1335         "EU",
1336         "NA",
1337         "OC",
1338         "AS",
1339         "AF",
1340         "EU",
1341         "AF",
1342         "OC",
1343         "NA",
1344         "SA",
1345         "AS",
1346         "EU",
1347         "NA",
1348         "SA",
1349         "NA",
1350         "NA",
1351         "AS",
1352         "OC",
1353         "OC",
1354         "OC",
1355         "AS",
1356         "AF",
1357         "EU",
1358         "AF",
1359         "AF",
1360         "EU",
1361         "AF",
1362         "--",
1363         "--",
1364         "--",
1365         "EU",
1366         "EU",
1367         "EU",
1368         "EU",
1369         "NA",
1370         "NA",
1371         "NA",
1372         "AF",
1373         "--"
1374     );
1375 }
1376 
1377 function geoip_load_shared_mem($file)
1378 {
1379     $fp = fopen($file, "rb");
1380     if (!$fp) {
1381         print "error opening $file: $php_errormsg\n";
1382         exit;
1383     }
1384     $s_array = fstat($fp);
1385     $size = $s_array['size'];
1386     if (($shmid = @shmop_open(GEOIP_SHM_KEY, "w", 0, 0))) {
1387         shmop_delete($shmid);
1388         shmop_close($shmid);
1389     }
1390     $shmid = shmop_open(GEOIP_SHM_KEY, "c", 0644, $size);
1391     shmop_write($shmid, fread($fp, $size), 0);
1392     shmop_close($shmid);
1393 }
1394 
1395 function _setup_segments($gi)
1396 {
1397     $gi->databaseType = GEOIP_COUNTRY_EDITION;
1398     $gi->record_length = STANDARD_RECORD_LENGTH;
1399     if ($gi->flags & GEOIP_SHARED_MEMORY) {
1400         $offset = @shmop_size($gi->shmid) - 3;
1401         for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
1402             $delim = @shmop_read($gi->shmid, $offset, 3);
1403             $offset += 3;
1404             if ($delim == (chr(255) . chr(255) . chr(255))) {
1405                 $gi->databaseType = ord(@shmop_read($gi->shmid, $offset, 1));
1406                 if ($gi->databaseType >= 106) {
1407                     $gi->databaseType -= 105;
1408                 }
1409                 $offset++;
1410 
1411                 if ($gi->databaseType == GEOIP_REGION_EDITION_REV0) {
1412                     $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
1413                 } elseif ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
1414                     $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
1415                 } elseif (($gi->databaseType == GEOIP_CITY_EDITION_REV0)
1416                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
1417                     || ($gi->databaseType == GEOIP_ORG_EDITION)
1418                     || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
1419                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
1420                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
1421                     || ($gi->databaseType == GEOIP_ISP_EDITION)
1422                     || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
1423                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
1424                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
1425                     || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
1426                     || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
1427                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
1428                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
1429                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
1430                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
1431                     || ($gi->databaseType == GEOIP_ASNUM_EDITION)
1432                     || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)
1433                 ) {
1434                     $gi->databaseSegments = 0;
1435                     $buf = @shmop_read($gi->shmid, $offset, SEGMENT_RECORD_LENGTH);
1436                     for ($j = 0; $j < SEGMENT_RECORD_LENGTH; $j++) {
1437                         $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
1438                     }
1439                     if (($gi->databaseType == GEOIP_ORG_EDITION)
1440                         || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
1441                         || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
1442                         || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
1443                         || ($gi->databaseType == GEOIP_ISP_EDITION)
1444                         || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
1445                     ) {
1446                         $gi->record_length = ORG_RECORD_LENGTH;
1447                     }
1448                 }
1449                 break;
1450             } else {
1451                 $offset -= 4;
1452             }
1453         }
1454         if (($gi->databaseType == GEOIP_COUNTRY_EDITION) ||
1455             ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6) ||
1456             ($gi->databaseType == GEOIP_PROXY_EDITION) ||
1457             ($gi->databaseType == GEOIP_NETSPEED_EDITION)
1458         ) {
1459             $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
1460         }
1461     } else {
1462         $filepos = ftell($gi->filehandle);
1463         fseek($gi->filehandle, -3, SEEK_END);
1464         for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) {
1465             $delim = fread($gi->filehandle, 3);
1466             if ($delim == (chr(255) . chr(255) . chr(255))) {
1467                 $gi->databaseType = ord(fread($gi->filehandle, 1));
1468                 if ($gi->databaseType >= 106) {
1469                     $gi->databaseType -= 105;
1470                 }
1471                 if ($gi->databaseType == GEOIP_REGION_EDITION_REV0) {
1472                     $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0;
1473                 } elseif ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
1474                     $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1;
1475                 } elseif (($gi->databaseType == GEOIP_CITY_EDITION_REV0)
1476                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1)
1477                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
1478                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
1479                     || ($gi->databaseType == GEOIP_ORG_EDITION)
1480                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
1481                     || ($gi->databaseType == GEOIP_ISP_EDITION)
1482                     || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
1483                     || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
1484                     || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
1485                     || ($gi->databaseType == GEOIP_LOCATIONA_EDITION)
1486                     || ($gi->databaseType == GEOIP_ACCURACYRADIUS_EDITION)
1487                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV0_V6)
1488                     || ($gi->databaseType == GEOIP_CITY_EDITION_REV1_V6)
1489                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1)
1490                     || ($gi->databaseType == GEOIP_NETSPEED_EDITION_REV1_V6)
1491                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION)
1492                     || ($gi->databaseType == GEOIP_USERTYPE_EDITION_V6)
1493                     || ($gi->databaseType == GEOIP_ASNUM_EDITION)
1494                     || ($gi->databaseType == GEOIP_ASNUM_EDITION_V6)
1495                 ) {
1496                     $gi->databaseSegments = 0;
1497                     $buf = fread($gi->filehandle, SEGMENT_RECORD_LENGTH);
1498                     for ($j = 0; $j < SEGMENT_RECORD_LENGTH; $j++) {
1499                         $gi->databaseSegments += (ord($buf[$j]) << ($j * 8));
1500                     }
1501                     if (($gi->databaseType == GEOIP_ORG_EDITION)
1502                         || ($gi->databaseType == GEOIP_DOMAIN_EDITION)
1503                         || ($gi->databaseType == GEOIP_ISP_EDITION)
1504                         || ($gi->databaseType == GEOIP_ORG_EDITION_V6)
1505                         || ($gi->databaseType == GEOIP_DOMAIN_EDITION_V6)
1506                         || ($gi->databaseType == GEOIP_ISP_EDITION_V6)
1507                     ) {
1508                         $gi->record_length = ORG_RECORD_LENGTH;
1509                     }
1510                 }
1511                 break;
1512             } else {
1513                 fseek($gi->filehandle, -4, SEEK_CUR);
1514             }
1515         }
1516         if (($gi->databaseType == GEOIP_COUNTRY_EDITION) ||
1517             ($gi->databaseType == GEOIP_COUNTRY_EDITION_V6) ||
1518             ($gi->databaseType == GEOIP_PROXY_EDITION) ||
1519             ($gi->databaseType == GEOIP_NETSPEED_EDITION)
1520         ) {
1521             $gi->databaseSegments = GEOIP_COUNTRY_BEGIN;
1522         }
1523         fseek($gi->filehandle, $filepos, SEEK_SET);
1524     }
1525     return $gi;
1526 }
1527 
1528 function geoip_open($filename, $flags)
1529 {
1530     $gi = new GeoIP;
1531     $gi->flags = $flags;
1532     if ($gi->flags & GEOIP_SHARED_MEMORY) {
1533         $gi->shmid = @shmop_open(GEOIP_SHM_KEY, "a", 0, 0);
1534     } else {
1535         $gi->filehandle = fopen($filename, "rb") or trigger_error("GeoIP API: Can not open $filename\n", E_USER_ERROR);
1536         if ($gi->flags & GEOIP_MEMORY_CACHE) {
1537             $s_array = fstat($gi->filehandle);
1538             $gi->memory_buffer = fread($gi->filehandle, $s_array['size']);
1539         }
1540     }
1541 
1542     $gi = _setup_segments($gi);
1543     return $gi;
1544 }
1545 
1546 function geoip_close($gi)
1547 {
1548     if ($gi->flags & GEOIP_SHARED_MEMORY) {
1549         return true;
1550     }
1551 
1552     return fclose($gi->filehandle);
1553 }
1554 
1555 function geoip_country_id_by_name_v6($gi, $name)
1556 {
1557     $rec = dns_get_record($name, DNS_AAAA);
1558     if (!$rec) {
1559         return false;
1560     }
1561     $addr = $rec[0]["ipv6"];
1562     if (!$addr || $addr == $name) {
1563         return false;
1564     }
1565     return geoip_country_id_by_addr_v6($gi, $addr);
1566 }
1567 
1568 function geoip_country_id_by_name($gi, $name)
1569 {
1570     $addr = gethostbyname($name);
1571     if (!$addr || $addr == $name) {
1572         return false;
1573     }
1574     return geoip_country_id_by_addr($gi, $addr);
1575 }
1576 
1577 function geoip_country_code_by_name_v6($gi, $name)
1578 {
1579     $country_id = geoip_country_id_by_name_v6($gi, $name);
1580     if ($country_id !== false) {
1581         return $gi->GEOIP_COUNTRY_CODES[$country_id];
1582     }
1583     return false;
1584 }
1585 
1586 function geoip_country_code_by_name($gi, $name)
1587 {
1588     $country_id = geoip_country_id_by_name($gi, $name);
1589     if ($country_id !== false) {
1590         return $gi->GEOIP_COUNTRY_CODES[$country_id];
1591     }
1592     return false;
1593 }
1594 
1595 function geoip_country_name_by_name_v6($gi, $name)
1596 {
1597     $country_id = geoip_country_id_by_name_v6($gi, $name);
1598     if ($country_id !== false) {
1599         return $gi->GEOIP_COUNTRY_NAMES[$country_id];
1600     }
1601     return false;
1602 }
1603 
1604 function geoip_country_name_by_name($gi, $name)
1605 {
1606     $country_id = geoip_country_id_by_name($gi, $name);
1607     if ($country_id !== false) {
1608         return $gi->GEOIP_COUNTRY_NAMES[$country_id];
1609     }
1610     return false;
1611 }
1612 
1613 function geoip_country_id_by_addr_v6($gi, $addr)
1614 {
1615     $ipnum = inet_pton($addr);
1616     return _geoip_seek_country_v6($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
1617 }
1618 
1619 function geoip_country_id_by_addr($gi, $addr)
1620 {
1621     $ipnum = ip2long($addr);
1622     return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN;
1623 }
1624 
1625 function geoip_country_code_by_addr_v6($gi, $addr)
1626 {
1627     $country_id = geoip_country_id_by_addr_v6($gi, $addr);
1628     if ($country_id !== false) {
1629         return $gi->GEOIP_COUNTRY_CODES[$country_id];
1630     }
1631     return false;
1632 }
1633 
1634 function geoip_country_code_by_addr($gi, $addr)
1635 {
1636     if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
1637         $record = geoip_record_by_addr($gi, $addr);
1638         if ($record !== false) {
1639             return $record->country_code;
1640         }
1641     } else {
1642         $country_id = geoip_country_id_by_addr($gi, $addr);
1643         if ($country_id !== false) {
1644             return $gi->GEOIP_COUNTRY_CODES[$country_id];
1645         }
1646     }
1647     return false;
1648 }
1649 
1650 function geoip_country_name_by_addr_v6($gi, $addr)
1651 {
1652     $country_id = geoip_country_id_by_addr_v6($gi, $addr);
1653     if ($country_id !== false) {
1654         return $gi->GEOIP_COUNTRY_NAMES[$country_id];
1655     }
1656     return false;
1657 }
1658 
1659 function geoip_country_name_by_addr($gi, $addr)
1660 {
1661     if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) {
1662         $record = geoip_record_by_addr($gi, $addr);
1663         return $record->country_name;
1664     } else {
1665         $country_id = geoip_country_id_by_addr($gi, $addr);
1666         if ($country_id !== false) {
1667             return $gi->GEOIP_COUNTRY_NAMES[$country_id];
1668         }
1669     }
1670     return false;
1671 }
1672 
1673 function _geoip_seek_country_v6($gi, $ipnum)
1674 {
1675     # arrays from unpack start with offset 1
1676     # yet another php mystery. array_merge work around
1677     # this broken behaviour
1678     $v6vec = array_merge(unpack("C16", $ipnum));
1679 
1680     $offset = 0;
1681     for ($depth = 127; $depth >= 0; --$depth) {
1682         if ($gi->flags & GEOIP_MEMORY_CACHE) {
1683             $buf = _safe_substr(
1684                 $gi->memory_buffer,
1685                 2 * $gi->record_length * $offset,
1686                 2 * $gi->record_length
1687             );
1688         } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
1689             $buf = @shmop_read(
1690                 $gi->shmid,
1691                 2 * $gi->record_length * $offset,
1692                 2 * $gi->record_length
1693             );
1694         } else {
1695             fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
1696             or trigger_error("GeoIP API: fseek failed", E_USER_ERROR);
1697             $buf = fread($gi->filehandle, 2 * $gi->record_length);
1698         }
1699         $x = array(0, 0);
1700         for ($i = 0; $i < 2; ++$i) {
1701             for ($j = 0; $j < $gi->record_length; ++$j) {
1702                 $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
1703             }
1704         }
1705 
1706         $bnum = 127 - $depth;
1707         $idx = $bnum >> 3;
1708         $b_mask = 1 << ($bnum & 7 ^ 7);
1709         if (($v6vec[$idx] & $b_mask) > 0) {
1710             if ($x[1] >= $gi->databaseSegments) {
1711                 return $x[1];
1712             }
1713             $offset = $x[1];
1714         } else {
1715             if ($x[0] >= $gi->databaseSegments) {
1716                 return $x[0];
1717             }
1718             $offset = $x[0];
1719         }
1720     }
1721     trigger_error("GeoIP API: Error traversing database - perhaps it is corrupt?", E_USER_ERROR);
1722     return false;
1723 }
1724 
1725 function _geoip_seek_country($gi, $ipnum)
1726 {
1727     $offset = 0;
1728     for ($depth = 31; $depth >= 0; --$depth) {
1729         if ($gi->flags & GEOIP_MEMORY_CACHE) {
1730             $buf = _safe_substr(
1731                 $gi->memory_buffer,
1732                 2 * $gi->record_length * $offset,
1733                 2 * $gi->record_length
1734             );
1735         } elseif ($gi->flags & GEOIP_SHARED_MEMORY) {
1736             $buf = @shmop_read(
1737                 $gi->shmid,
1738                 2 * $gi->record_length * $offset,
1739                 2 * $gi->record_length
1740             );
1741         } else {
1742             fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0
1743             or trigger_error("GeoIP API: fseek failed", E_USER_ERROR);
1744             $buf = fread($gi->filehandle, 2 * $gi->record_length);
1745         }
1746         $x = array(0, 0);
1747         for ($i = 0; $i < 2; ++$i) {
1748             for ($j = 0; $j < $gi->record_length; ++$j) {
1749                 $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8);
1750             }
1751         }
1752         if ($ipnum & (1 << $depth)) {
1753             if ($x[1] >= $gi->databaseSegments) {
1754                 return $x[1];
1755             }
1756             $offset = $x[1];
1757         } else {
1758             if ($x[0] >= $gi->databaseSegments) {
1759                 return $x[0];
1760             }
1761             $offset = $x[0];
1762         }
1763     }
1764     trigger_error("GeoIP API: Error traversing database - perhaps it is corrupt?", E_USER_ERROR);
1765     return false;
1766 }
1767 
1768 function _common_get_org($gi, $seek_org)
1769 {
1770     $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments;
1771     if ($gi->flags & GEOIP_SHARED_MEMORY) {
1772         $org_buf = @shmop_read($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH);
1773     } else {
1774         fseek($gi->filehandle, $record_pointer, SEEK_SET);
1775         $org_buf = fread($gi->filehandle, MAX_ORG_RECORD_LENGTH);
1776     }
1777     $org_buf = _safe_substr($org_buf, 0, strpos($org_buf, "\0"));
1778     return $org_buf;
1779 }
1780 
1781 function _get_org_v6($gi, $ipnum)
1782 {
1783     $seek_org = _geoip_seek_country_v6($gi, $ipnum);
1784     if ($seek_org == $gi->databaseSegments) {
1785         return null;
1786     }
1787     return _common_get_org($gi, $seek_org);
1788 }
1789 
1790 function _get_org($gi, $ipnum)
1791 {
1792     $seek_org = _geoip_seek_country($gi, $ipnum);
1793     if ($seek_org == $gi->databaseSegments) {
1794         return null;
1795     }
1796     return _common_get_org($gi, $seek_org);
1797 }
1798 
1799 
1800 function geoip_name_by_addr_v6($gi, $addr)
1801 {
1802     if ($addr == null) {
1803         return 0;
1804     }
1805     $ipnum = inet_pton($addr);
1806     return _get_org_v6($gi, $ipnum);
1807 }
1808 
1809 function geoip_name_by_addr($gi, $addr)
1810 {
1811     if ($addr == null) {
1812         return 0;
1813     }
1814     $ipnum = ip2long($addr);
1815     return _get_org($gi, $ipnum);
1816 }
1817 
1818 function geoip_org_by_addr($gi, $addr)
1819 {
1820     return geoip_name_by_addr($gi, $addr);
1821 }
1822 
1823 function _get_region($gi, $ipnum)
1824 {
1825     if ($gi->databaseType == GEOIP_REGION_EDITION_REV0) {
1826         $seek_region = _geoip_seek_country($gi, $ipnum) - GEOIP_STATE_BEGIN_REV0;
1827         if ($seek_region >= 1000) {
1828             $country_code = "US";
1829             $region = chr(($seek_region - 1000) / 26 + 65) . chr(($seek_region - 1000) % 26 + 65);
1830         } else {
1831             $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region];
1832             $region = "";
1833         }
1834         return array($country_code, $region);
1835     } elseif ($gi->databaseType == GEOIP_REGION_EDITION_REV1) {
1836         $seek_region = _geoip_seek_country($gi, $ipnum) - GEOIP_STATE_BEGIN_REV1;
1837         if ($seek_region < US_OFFSET) {
1838             $country_code = "";
1839             $region = "";
1840         } elseif ($seek_region < CANADA_OFFSET) {
1841             $country_code = "US";
1842             $region = chr(($seek_region - US_OFFSET) / 26 + 65) . chr(($seek_region - US_OFFSET) % 26 + 65);
1843         } elseif ($seek_region < WORLD_OFFSET) {
1844             $country_code = "CA";
1845             $region = chr(($seek_region - CANADA_OFFSET) / 26 + 65) . chr(($seek_region - CANADA_OFFSET) % 26 + 65);
1846         } else {
1847             $country_code = $gi->GEOIP_COUNTRY_CODES[(int) (($seek_region - WORLD_OFFSET) / FIPS_RANGE)];
1848             $region = "";
1849         }
1850         return array($country_code, $region);
1851     }
1852     return null;
1853 }
1854 
1855 function geoip_region_by_addr($gi, $addr)
1856 {
1857     if ($addr == null) {
1858         return 0;
1859     }
1860     $ipnum = ip2long($addr);
1861     return _get_region($gi, $ipnum);
1862 }
1863 
1864 function _safe_substr($string, $start, $length)
1865 {
1866     // workaround php's broken substr, strpos, etc handling with
1867     // mbstring.func_overload and mbstring.internal_encoding
1868     $mbExists = extension_loaded('mbstring');
1869 
1870     if ($mbExists) {
1871         $enc = mb_internal_encoding();
1872         mb_internal_encoding('ISO-8859-1');
1873     }
1874 
1875     $buf = substr($string, $start, $length);
1876 
1877     if ($mbExists) {
1878         mb_internal_encoding($enc);
1879     }
1880 
1881     return $buf;
1882 }
1883 
1884 function getIPaddress(){
1885     $IPaddress='';
1886     if (isset($_SERVER)){
1887         if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
1888             $IPaddress = $_SERVER["HTTP_X_FORWARDED_FOR"];
1889         } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
1890             $IPaddress = $_SERVER["HTTP_CLIENT_IP"];
1891         } else {
1892             $IPaddress = $_SERVER["REMOTE_ADDR"];
1893         }
1894     } else {
1895         if (getenv("HTTP_X_FORWARDED_FOR")){
1896             $IPaddress = getenv("HTTP_X_FORWARDED_FOR");
1897         } else if (getenv("HTTP_CLIENT_IP")) {
1898             $IPaddress = getenv("HTTP_CLIENT_IP");
1899         } else {
1900             $IPaddress = getenv("REMOTE_ADDR");
1901         }
1902     }
1903     return $IPaddress;
1904 }
1905 
1906 ?>

 

3、然后在php文件中写入如下代码

<?php 
require('geoip.inc');
$gi = geoip_open('GeoIP.dat',0);
$ip = getIPaddress(); echo geoip_country_code_by_addr(
$gi, $ip); ?>

 具体还可参考http://php.net/geoip/

posted @ 2015-06-02 17:57  神马和浮云  阅读(5506)  评论(0编辑  收藏  举报