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/

时间: 2024-09-30 10:03:39

PHP如何使用GeoIP数据库的相关文章

利用GeoIP数据库及API进行地理定位查询

GeoIP数据库下载地址:http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz. 首先,在MaxMind官网下载所需资源 下载后,我们将其解压到d盘,具体的安装文档参看 GeoIP Legacy City数据库安装说明 MaxMind提供多种api接口,如:perl, java, python, c, php, c#等,我们这里使用c#(https://github.com/maxmind/g

Nginx结合GeoIP库

1. 编译nginx时带上geoip模块 # wget http://nginx.org/download/nginx-x.x.x.tar.gz # tar zxvf nginx-x.x.x.tar.gz # cd nginx-x.x.x # ./configure --with-http_geoip_module 其余编译选项请自行填补 # make; make install 2. 下载可以读取GeoIP数据库的工具 # wget http://geolite.maxmind.com/dow

ELK监控日志nginx(集成Geoip)

实验环境:之前ELK已经初步安装完毕了,只需要将nginx的日志发送过来就可以了,nginx的IP为:192.168.137.101.因为服务端只是收集日志的所以下面的操作完全是在nginx机器上面完成的.在这里感谢<ELK stack权威指南>这本书,下面配置的内容都是借鉴的这本书. #/opt/logstash/bin/logstash-plugin install logstash-filter-geoip 安装这个插件,以前的老版本需要自己下载GeoIP还有这个插件的数据库,现在都不需

geoip+php示例:通过ip,获取国家名称和代码

GeoIP + PHP的使用 方法一: 下载 GeoIP 的 PHP 文件geoip.inc,保存为 geoip.inc.php http://sjolzy.cn/php/GeoIP/bak/geoip.inc php使用代码 <?php include("geoip.inc.php"); $gi = geoip_open("GeoIP.dat",GEOIP_STANDARD); $country_code = geoip_country_code_by_ad

Logstash利用GeoIP库显示地图以及通过useragent显示浏览器(四)

我们通过Logstash收集的Nginx Access log中已经包含了客户端IP的数据(remote_addr),但是只有这个IP还不够,要在Kibana的显示请求来源的地理位置还需要借助GeoIP数据库来实现.GeoIP 是最常见的免费 IP 地址归类查询库,同时也有收费版可以采购.GeoIP 库可以根据 IP 地址提供对应的地域信息,包括国别,省市,经纬度等,对于可视化地图和区域统计非常有用. 另外GeoIP数据文件的准确性和geoip插件的性能还是比较头疼,对性能有要求的可以看下@三斗

客户端灰度发布,NGINX+GeoIP2+GeoIP Database

需求的产生 (分地区更新) 我们公司呢是做电商平台的,其主打商品里有一款智能饮水机产品,而每台智能饮水机产品都是装在全国客户的家里.为了售后维护需要服务端如何保存数据并传回这块实现较简单,而在远程展示水机的余额.归属地.出水的质量等功能这块是由水机自身所镶嵌的一块智能PAD屏所完成,其PAD内部安装的是安卓系统:在由开发完成新功能的开发后需迭代智能PAD屏内部安卓系统APK版本时,在更新版本这块我们一直做的方法是全量更新不做任何更新上的限制.但随着业务量的增加全国大概有30万台水机版本需要更新,

关于 Wireshark3 中 GeoIP 的问题

本文首发:https://www.somata.work/2019/AboutWireshark3GeoIPQ.html 之前在用 Wireshark 书里面讲到了 GeoIP 反解地址信息的用法,但是我用 Wireshark 找了半天也没找到 GeoIP 设置数据库的配置选项,网上查了很久,全是针对 有 GenIP 的解释.我自己去查了 Wireshark 的 releases 之后才知道,在 Wireshark 2.5.1 的时候已经剔除了 GeoIP 的数据库支持了,改而使用的MaxMin

如何自己构建一个小型的Zoomeye----从技术细节探讨到实现

 0.概述 Zoomeye是个网络空间的搜索引擎,它不同于传统意义上的搜索引擎,而是一种可以搜索网络组件和网络设备的搜索引擎. 这种以各大组件指纹作为识别基础的数据平台,更多的是为了使得安全研究人员更好地评估漏洞的影响范围与其中隐含的数据模式. 1.架构分析 这是从网上搜索到的一张Zoomeye的后端架构图,主要分为调度框架.ES存储.UI呈现等模块.对于一次漏洞的评估,启动调度框架分配域名或者IP列表给扫描节点,节点完成任务后执行回调,做出自动化的效果其实也不是很难,从网上找个开源消息队列

ELK系统分析nginx日志

ELK系统在安装完成后需要处理相关的日志文件,本文主要对nginx日志文件进行处理并进行可视化操作,来满足日常的业务需求,长话短说,接下来介绍我的环境 具体的网络拓扑图如下: 具体配置如下: server OS Version IP 备注 logstash  CentOS release 6.4 (Final) logstash 2.2.2 192.168.180.2 logstash客户端用来收集日志 elasticsearch CentOS release 6.4 (Final) elast