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