├── README ├── config.m4 ├── geoip.c └── php_geoip.h /README: -------------------------------------------------------------------------------- 1 | == ABOUT == 2 | This PHP extension allows you to find the location of an IP address - City, State, 3 | Country, Longitude, Latitude, and other information as all, such as ISP and connection type. 4 | 5 | To compile it, you will need to have the GeoIP c library installed. 6 | 7 | Forked from pecl.php.net/package/geoip (1.0.7) 8 | 9 | 10 | == CHANGELOG == 11 | * Added geoip_country_code_by_addr 12 | * Added geoip_country_code3_by_addr 13 | * Removed NOTICE errors when adress isn't found, returning FALSE is enough 14 | * Added geoip_setup_custom_directory 15 | * PHP 5.4 compatibility 16 | * Added PHP 7 compatibility 17 | 18 | 19 | == INSTALL == 20 | 21 | OSX (MacPorts): 22 | sudo port install libgeoip 23 | 24 | Then after unpacking: 25 | phpize 26 | ./configure --prefix=/opt/local --with-php-config=/opt/local/bin/php-config 27 | make 28 | sudo make install 29 | 30 | Ubuntu: 31 | sudo apt-get install libgeoip-dev 32 | 33 | Then after unpacking: 34 | phpize 35 | ./configure --with-php-config=/usr/bin/php-config 36 | make 37 | sudo make install 38 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id: config.m4,v 1.10 2009/03/05 12:52:25 ohill Exp $ 2 | dnl config.m4 for extension geoip 3 | 4 | dnl Base file contributed by Jonathan Whiteman of cyberflowsolutions.com 5 | 6 | PHP_ARG_WITH(geoip, for geoip support, 7 | dnl Make sure that the comment is aligned: 8 | [ --with-geoip Include GeoIP support]) 9 | 10 | if test "$PHP_GEOIP" != "no"; then 11 | 12 | # --with-geoip -> check with-path 13 | SEARCH_PATH="/usr/local /usr /sw /opt/local" 14 | SEARCH_FOR="/include/GeoIP.h" 15 | if test -r $PHP_GEOIP/$SEARCH_FOR; then 16 | GEOIP_DIR=$PHP_GEOIP 17 | else # search default path list 18 | AC_MSG_CHECKING([for geoip files in default path]) 19 | for i in $SEARCH_PATH ; do 20 | if test -r $i/$SEARCH_FOR; then 21 | GEOIP_DIR=$i 22 | AC_MSG_RESULT([found in $i]) 23 | fi 24 | done 25 | fi 26 | 27 | if test -z "$GEOIP_DIR"; then 28 | AC_MSG_RESULT([not found]) 29 | AC_MSG_ERROR([Please reinstall the geoip distribution]) 30 | fi 31 | 32 | # --with-geoip -> add include path 33 | PHP_ADD_INCLUDE($GEOIP_DIR/include) 34 | 35 | # odd PHP4 fix 36 | if test "x$PHP_LIBDIR" = "x"; then 37 | PHP_LIBDIR=lib 38 | fi 39 | 40 | # --with-geoip -> check for lib and symbol presence 41 | LIBNAME=GeoIP # you may want to change this 42 | LIBSYMBOL=GeoIP_open # you most likely want to change this 43 | 44 | PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 45 | [ 46 | PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $GEOIP_DIR/lib, GEOIP_SHARED_LIBADD) 47 | AC_DEFINE(HAVE_GEOIPLIB,1,[ ]) 48 | ],[ 49 | AC_MSG_ERROR([wrong geoip lib version or lib not found]) 50 | ],[ 51 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 52 | ]) 53 | 54 | # Checking for GeoIP_setup_custom_directory in newer lib 55 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_setup_custom_directory, 56 | [ 57 | AC_DEFINE(HAVE_CUSTOM_DIRECTORY,1,[ ]) 58 | MIN_GEOIP_VERSION=1004001 59 | ],[ 60 | ],[ 61 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 62 | ]) 63 | 64 | # Checking for GeoIP_set_charset in newer lib 65 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_set_charset, 66 | [ 67 | AC_DEFINE(HAVE_SET_CHARSET,1,[ ]) 68 | MIN_GEOIP_VERSION=1004003 69 | ],[ 70 | ],[ 71 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 72 | ]) 73 | 74 | # Checking for GeoIP_continent_by_id in newer lib 75 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_continent_by_id, 76 | [ 77 | AC_DEFINE(HAVE_CONTINENT_BY_ID,1,[ ]) 78 | MIN_GEOIP_VERSION=1004005 79 | ],[ 80 | ],[ 81 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 82 | ]) 83 | 84 | # Check to see if we are using the LGPL library (version 1.4.0 and newer) 85 | AC_MSG_CHECKING([for LGPL compatible GeoIP libs]) 86 | libgeoip_full_version=`find $GEOIP_DIR/$PHP_LIBDIR/ -name libGeoIP.\*.\*.\*.\* | cut -d . -f 2-5 | sort` 87 | for lines in $libgeoip_full_version; do 88 | ac_IFS=$IFS 89 | IFS="." 90 | set $lines 91 | IFS=$ac_IFS 92 | done 93 | 94 | # Version after the suffix (eg: .so.1.4.0) 95 | if test "[$]1" = "$SHLIB_SUFFIX_NAME"; then 96 | LIBGEOIP_VERSION=`expr [$]2 \* 1000000 + [$]3 \* 1000 + [$]4` 97 | # Version before the suffix (eg: 1.4.0.dylib on OS X) 98 | else 99 | LIBGEOIP_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` 100 | fi 101 | 102 | # Just in case it didn't work, try alternate method, or fail 103 | if test "x$LIBGEOIP_VERSION" = "x"; then 104 | AC_MSG_RESULT([cannot detect]) 105 | 106 | # Alternate method based on library capabilities (not 100% acurate) 107 | AC_MSG_CHECKING([library features to determine version (not acurate)]) 108 | if test "x$MIN_GEOIP_VERSION" = "x"; then 109 | AC_MSG_ERROR([For some reason, libGeoIP is installed, but I cannot determine the version used]) 110 | else 111 | LIBGEOIP_VERSION=$MIN_GEOIP_VERSION 112 | fi 113 | fi 114 | 115 | if test "$LIBGEOIP_VERSION" -lt "1004000"; then 116 | AC_MSG_RESULT([wrong version]) 117 | AC_MSG_ERROR([You need version 1.4.0 or higher of the C API]) 118 | else 119 | AC_MSG_RESULT([found $LIBGEOIP_VERSION]) 120 | AC_DEFINE_UNQUOTED(LIBGEOIP_VERSION, $LIBGEOIP_VERSION, [ ]) 121 | fi 122 | 123 | PHP_SUBST(GEOIP_SHARED_LIBADD) 124 | 125 | PHP_NEW_EXTENSION(geoip, geoip.c, $ext_shared) 126 | fi 127 | 128 | -------------------------------------------------------------------------------- /geoip.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2009 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Olivier Hill | 16 | | Matthew Fonda | 17 | +----------------------------------------------------------------------+ 18 | Please contact support@maxmind.com with any comments 19 | */ 20 | 21 | 22 | #ifdef HAVE_CONFIG_H 23 | #include "config.h" 24 | #endif 25 | 26 | #include 27 | #include 28 | 29 | #include "php.h" 30 | #include "php_ini.h" 31 | #include "ext/standard/info.h" 32 | #include "php_geoip.h" 33 | 34 | 35 | #if PHP_MAJOR_VERSION < 7 36 | #define ZSTR_VAL(str) str 37 | #endif 38 | 39 | #if PHP_MAJOR_VERSION < 7 40 | #define _RETURN_STRING(str) RETURN_STRING(str, 1) 41 | #define _RETVAL_STRING(str) RETVAL_STRING(str, 1) 42 | #else 43 | #define _RETURN_STRING(str) RETURN_STRING(str) 44 | #define _RETVAL_STRING(str) RETVAL_STRING(str) 45 | #endif 46 | 47 | #if PHP_MAJOR_VERSION < 7 48 | #define _add_assoc_string(zv, key, str) add_assoc_string(zv, key, str, 1) 49 | #else 50 | #define _add_assoc_string(zv, key, str) add_assoc_string(zv, key, str) 51 | #endif 52 | 53 | 54 | 55 | #if PHP_MAJOR_VERSION < 7 56 | typedef long zend_long; 57 | typedef int strsize_t; 58 | #else 59 | typedef size_t strsize_t; 60 | #endif 61 | 62 | #if PHP_MAJOR_VERSION < 7 63 | #define _DECLARE_ZVAL(name) zval * name 64 | #define _ALLOC_INIT_ZVAL(name) ALLOC_INIT_ZVAL(name) 65 | #define hp_ptr_dtor(val) zval_ptr_dtor(&val); 66 | #else 67 | #define _DECLARE_ZVAL(name) zval name ## _v; zval * name = &name ## _v 68 | #define _ALLOC_INIT_ZVAL(name) ZVAL_NULL(name) 69 | #define hp_ptr_dtor(val) zval_ptr_dtor(val); 70 | #endif 71 | 72 | 73 | ZEND_DECLARE_MODULE_GLOBALS(geoip) 74 | 75 | static int le_geoip; 76 | 77 | /* {{{ */ 78 | zend_function_entry geoip_functions[] = { 79 | PHP_FE(geoip_database_info, NULL) 80 | PHP_FE(geoip_country_code_by_name, NULL) 81 | PHP_FE(geoip_country_code3_by_name, NULL) 82 | PHP_FE(geoip_country_name_by_name, NULL) 83 | PHP_FE(geoip_continent_code_by_name, NULL) 84 | PHP_FE(geoip_org_by_name, NULL) 85 | PHP_FE(geoip_record_by_name, NULL) 86 | PHP_FE(geoip_id_by_name, NULL) 87 | PHP_FE(geoip_region_by_name, NULL) 88 | PHP_FE(geoip_isp_by_name, NULL) 89 | PHP_FE(geoip_db_avail, NULL) 90 | PHP_FE(geoip_db_get_all_info, NULL) 91 | PHP_FE(geoip_db_filename, NULL) 92 | #if LIBGEOIP_VERSION >= 1004001 93 | PHP_FE(geoip_region_name_by_code, NULL) 94 | PHP_FE(geoip_time_zone_by_country_and_region, NULL) 95 | #endif 96 | PHP_FE(geoip_country_code_by_addr, NULL) 97 | PHP_FE(geoip_country_code3_by_addr, NULL) 98 | PHP_FE(geoip_setup_custom_directory, NULL) 99 | {NULL, NULL, NULL} 100 | }; 101 | /* }}} */ 102 | 103 | /* {{{ geoip_module_entry 104 | */ 105 | zend_module_entry geoip_module_entry = { 106 | #if ZEND_MODULE_API_NO >= 20010901 107 | STANDARD_MODULE_HEADER, 108 | #endif 109 | "geoip", 110 | geoip_functions, 111 | PHP_MINIT(geoip), 112 | PHP_MSHUTDOWN(geoip), 113 | PHP_RINIT(geoip), 114 | PHP_RSHUTDOWN(geoip), 115 | PHP_MINFO(geoip), 116 | #if ZEND_MODULE_API_NO >= 20010901 117 | PHP_GEOIP_VERSION, /* version number of the extension */ 118 | #endif 119 | STANDARD_MODULE_PROPERTIES 120 | }; 121 | /* }}} */ 122 | 123 | #ifdef COMPILE_DL_GEOIP 124 | ZEND_GET_MODULE(geoip) 125 | #endif 126 | 127 | /* {{{ PHP_INI 128 | */ 129 | PHP_INI_BEGIN() 130 | #ifdef HAVE_CUSTOM_DIRECTORY 131 | STD_PHP_INI_ENTRY("geoip.custom_directory", NULL, PHP_INI_ALL, OnUpdateString, custom_directory, zend_geoip_globals, geoip_globals) 132 | #endif 133 | PHP_INI_END() 134 | /* }}} */ 135 | 136 | /* {{{ php_geoip_init_globals 137 | */ 138 | static void php_geoip_init_globals(zend_geoip_globals *geoip_globals) 139 | { 140 | geoip_globals->custom_directory = NULL; 141 | geoip_globals->set_runtime_custom_directory = 0; 142 | } 143 | /* }}} */ 144 | 145 | /* {{{ PHP_MINIT_FUNCTION 146 | */ 147 | PHP_MINIT_FUNCTION(geoip) 148 | { 149 | ZEND_INIT_MODULE_GLOBALS(geoip, php_geoip_init_globals, NULL); 150 | REGISTER_INI_ENTRIES(); 151 | 152 | /* @TODO: Do something for custom_directory before initialization here */ 153 | 154 | #ifdef HAVE_CUSTOM_DIRECTORY 155 | GeoIP_setup_custom_directory(GEOIP_G(custom_directory)); 156 | #endif 157 | 158 | _GeoIP_setup_dbfilename(); 159 | 160 | /* For database type constants */ 161 | REGISTER_LONG_CONSTANT("GEOIP_COUNTRY_EDITION", GEOIP_COUNTRY_EDITION, CONST_CS | CONST_PERSISTENT); 162 | REGISTER_LONG_CONSTANT("GEOIP_REGION_EDITION_REV0", GEOIP_REGION_EDITION_REV0, CONST_CS | CONST_PERSISTENT); 163 | REGISTER_LONG_CONSTANT("GEOIP_CITY_EDITION_REV0", GEOIP_CITY_EDITION_REV0, CONST_CS | CONST_PERSISTENT); 164 | REGISTER_LONG_CONSTANT("GEOIP_ORG_EDITION", GEOIP_ORG_EDITION, CONST_CS | CONST_PERSISTENT); 165 | REGISTER_LONG_CONSTANT("GEOIP_ISP_EDITION", GEOIP_ISP_EDITION, CONST_CS | CONST_PERSISTENT); 166 | REGISTER_LONG_CONSTANT("GEOIP_CITY_EDITION_REV1", GEOIP_CITY_EDITION_REV1, CONST_CS | CONST_PERSISTENT); 167 | REGISTER_LONG_CONSTANT("GEOIP_REGION_EDITION_REV1", GEOIP_REGION_EDITION_REV1, CONST_CS | CONST_PERSISTENT); 168 | REGISTER_LONG_CONSTANT("GEOIP_PROXY_EDITION", GEOIP_PROXY_EDITION, CONST_CS | CONST_PERSISTENT); 169 | REGISTER_LONG_CONSTANT("GEOIP_ASNUM_EDITION", GEOIP_ASNUM_EDITION, CONST_CS | CONST_PERSISTENT); 170 | REGISTER_LONG_CONSTANT("GEOIP_NETSPEED_EDITION", GEOIP_NETSPEED_EDITION, CONST_CS | CONST_PERSISTENT); 171 | REGISTER_LONG_CONSTANT("GEOIP_DOMAIN_EDITION", GEOIP_DOMAIN_EDITION, CONST_CS | CONST_PERSISTENT); 172 | 173 | /* For netspeed constants */ 174 | REGISTER_LONG_CONSTANT("GEOIP_UNKNOWN_SPEED", GEOIP_UNKNOWN_SPEED, CONST_CS | CONST_PERSISTENT); 175 | REGISTER_LONG_CONSTANT("GEOIP_DIALUP_SPEED", GEOIP_DIALUP_SPEED, CONST_CS | CONST_PERSISTENT); 176 | REGISTER_LONG_CONSTANT("GEOIP_CABLEDSL_SPEED", GEOIP_CABLEDSL_SPEED, CONST_CS | CONST_PERSISTENT); 177 | REGISTER_LONG_CONSTANT("GEOIP_CORPORATE_SPEED", GEOIP_CORPORATE_SPEED, CONST_CS | CONST_PERSISTENT); 178 | 179 | return SUCCESS; 180 | } 181 | /* }}} */ 182 | 183 | /* {{{ PHP_MSHUTDOWN_FUNCTION 184 | */ 185 | PHP_MSHUTDOWN_FUNCTION(geoip) 186 | { 187 | return SUCCESS; 188 | } 189 | /* }}} */ 190 | 191 | 192 | /* {{{ PHP_RINIT_FUNCTION 193 | */ 194 | PHP_RINIT_FUNCTION(geoip) 195 | { 196 | return SUCCESS; 197 | } 198 | /* }}} */ 199 | 200 | 201 | /* {{{ PHP_RSHUTDOWN_FUNCTION 202 | */ 203 | PHP_RSHUTDOWN_FUNCTION(geoip) 204 | { 205 | if (GEOIP_G(set_runtime_custom_directory)) { 206 | if (GeoIPDBFileName != NULL) { 207 | free(GeoIPDBFileName); 208 | GeoIPDBFileName = NULL; 209 | } 210 | 211 | #ifdef HAVE_CUSTOM_DIRECTORY 212 | GeoIP_setup_custom_directory(GEOIP_G(custom_directory)); 213 | #else 214 | GeoIP_setup_custom_directory(NULL); 215 | #endif 216 | 217 | _GeoIP_setup_dbfilename(); 218 | } 219 | 220 | return SUCCESS; 221 | } 222 | /* }}} */ 223 | 224 | /* {{{ PHP_MINFO_FUNCTION 225 | */ 226 | PHP_MINFO_FUNCTION(geoip) 227 | { 228 | char buf[32]; 229 | 230 | php_info_print_table_start(); 231 | php_info_print_table_header(2, "geoip support", "enabled"); 232 | php_info_print_table_row(2, "geoip extension version", PHP_GEOIP_VERSION); 233 | snprintf(buf, sizeof(buf), "%d", LIBGEOIP_VERSION); 234 | php_info_print_table_row(2, "geoip library version", buf); 235 | php_info_print_table_end(); 236 | DISPLAY_INI_ENTRIES(); 237 | } 238 | /* }}} */ 239 | 240 | /* {{{ proto boolean geoip_db_avail( [ int database ] ) */ 241 | PHP_FUNCTION(geoip_db_avail) 242 | { 243 | zend_long edition; 244 | 245 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &edition) == FAILURE) { 246 | return; 247 | } 248 | 249 | if (edition < 0 || edition >= NUM_DB_TYPES) 250 | { 251 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 252 | return; 253 | } 254 | 255 | RETURN_BOOL(GeoIP_db_avail(edition)); 256 | } 257 | /* }}} */ 258 | 259 | /* {{{ proto string geoip_db_filename( [ int database ] ) */ 260 | PHP_FUNCTION(geoip_db_filename) 261 | { 262 | zend_long edition; 263 | 264 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &edition) == FAILURE) { 265 | return; 266 | } 267 | 268 | if (edition < 0 || edition >= NUM_DB_TYPES) 269 | { 270 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 271 | return; 272 | } 273 | 274 | if (NULL != GeoIPDBFileName[edition]) 275 | _RETURN_STRING(GeoIPDBFileName[edition]); 276 | } 277 | /* }}} */ 278 | 279 | /* {{{ proto array geoip_db_get_all_info( ) */ 280 | PHP_FUNCTION(geoip_db_get_all_info) 281 | { 282 | int i; 283 | 284 | array_init(return_value); 285 | 286 | for (i=0; i < NUM_DB_TYPES; i++) 287 | { 288 | if ((NULL != GeoIPDBDescription[i]) && (NULL != GeoIPDBFileName[i])) 289 | { 290 | _DECLARE_ZVAL(row); 291 | array_init(row); 292 | 293 | add_assoc_bool(row, "available", GeoIP_db_avail(i)); 294 | _add_assoc_string(row, "description", (char *)GeoIPDBDescription[i]); 295 | _add_assoc_string(row, "filename", GeoIPDBFileName[i]); 296 | 297 | add_index_zval(return_value, i, row); 298 | } 299 | } 300 | } 301 | /* }}} */ 302 | 303 | /* {{{ proto string geoip_database_info( [ int database ] ) 304 | Returns GeoIP Database information */ 305 | PHP_FUNCTION(geoip_database_info) 306 | { 307 | GeoIP * gi; 308 | char * db_info; 309 | zend_long edition = GEOIP_COUNTRY_EDITION; 310 | 311 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &edition) == FAILURE) { 312 | return; 313 | } 314 | 315 | if (edition < 0 || edition >= NUM_DB_TYPES) 316 | { 317 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 318 | return; 319 | } 320 | 321 | if (GeoIP_db_avail(edition)) { 322 | gi = GeoIP_open_type(edition, GEOIP_STANDARD); 323 | } else { 324 | if (NULL != GeoIPDBFileName[edition]) 325 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 326 | else 327 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available."); 328 | return; 329 | } 330 | 331 | db_info = GeoIP_database_info(gi); 332 | GeoIP_delete(gi); 333 | 334 | _RETVAL_STRING(db_info); 335 | free(db_info); 336 | } 337 | /* }}} */ 338 | 339 | /* {{{ proto string geoip_country_code_by_name( string hostname ) 340 | Return the Country Code found in the GeoIP Database */ 341 | PHP_FUNCTION(geoip_country_code_by_name) 342 | { 343 | GeoIP * gi; 344 | const char * country_code; 345 | 346 | #if PHP_MAJOR_VERSION < 7 347 | char * hostname = NULL; 348 | int arglen; 349 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 350 | return; 351 | } 352 | #else 353 | zend_string *hostname = NULL; 354 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 355 | return; 356 | } 357 | #endif 358 | 359 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 360 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 361 | } else { 362 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 363 | return; 364 | } 365 | 366 | country_code = GeoIP_country_code_by_name(gi, ZSTR_VAL(hostname)); 367 | GeoIP_delete(gi); 368 | if (country_code == NULL) { 369 | RETURN_FALSE; 370 | } 371 | _RETURN_STRING((char*)country_code); 372 | } 373 | /* }}} */ 374 | 375 | /* {{{ proto string geoip_country_code_by_name( string hostname ) 376 | Return the Country Code found in the GeoIP Database */ 377 | PHP_FUNCTION(geoip_country_code3_by_name) 378 | { 379 | GeoIP * gi; 380 | const char * country_code; 381 | 382 | #if PHP_MAJOR_VERSION < 7 383 | char * hostname = NULL; 384 | int arglen; 385 | 386 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 387 | return; 388 | } 389 | #else 390 | zend_string *hostname = NULL; 391 | 392 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 393 | return; 394 | } 395 | #endif 396 | 397 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 398 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 399 | } else { 400 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 401 | return; 402 | } 403 | 404 | country_code = GeoIP_country_code3_by_name(gi, ZSTR_VAL(hostname)); 405 | GeoIP_delete(gi); 406 | if (country_code == NULL) { 407 | RETURN_FALSE; 408 | } 409 | _RETURN_STRING((char*)country_code); 410 | } 411 | /* }}} */ 412 | 413 | /* {{{ proto string geoip_country_name_by_name( string hostname ) 414 | Returns the Country name found in the GeoIP Database */ 415 | PHP_FUNCTION(geoip_country_name_by_name) 416 | { 417 | GeoIP * gi; 418 | const char * country_name; 419 | 420 | #if PHP_MAJOR_VERSION < 7 421 | char * hostname = NULL; 422 | int arglen; 423 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 424 | return; 425 | } 426 | #else 427 | zend_string * hostname = NULL; 428 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 429 | return; 430 | } 431 | #endif 432 | 433 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 434 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 435 | } else { 436 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 437 | return; 438 | } 439 | 440 | country_name = GeoIP_country_name_by_name(gi, ZSTR_VAL(hostname)); 441 | GeoIP_delete(gi); 442 | if (country_name == NULL) { 443 | RETURN_FALSE; 444 | } 445 | _RETURN_STRING((char*)country_name); 446 | } 447 | /* }}} */ 448 | 449 | /* {{{ proto string geoip_continent_code_by_name( string hostname ) 450 | Returns the Continent name found in the GeoIP Database */ 451 | PHP_FUNCTION(geoip_continent_code_by_name) 452 | { 453 | GeoIP * gi; 454 | int id; 455 | 456 | #if PHP_MAJOR_VERSION < 7 457 | char * hostname = NULL; 458 | int arglen; 459 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 460 | return; 461 | } 462 | #else 463 | zend_string * hostname = NULL; 464 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 465 | return; 466 | } 467 | #endif 468 | 469 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 470 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 471 | } else { 472 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 473 | return; 474 | } 475 | 476 | id = GeoIP_id_by_name(gi, ZSTR_VAL(hostname)); 477 | GeoIP_delete(gi); 478 | if (id == 0) { 479 | RETURN_FALSE; 480 | } 481 | _RETURN_STRING((char *)GeoIP_country_continent[id]); 482 | } 483 | /* }}} */ 484 | 485 | /* {{{ proto string geoip_org_by_name( string hostname ) 486 | Returns the Organization Name found in the GeoIP Database */ 487 | PHP_FUNCTION(geoip_org_by_name) 488 | { 489 | GeoIP * gi; 490 | char * org; 491 | 492 | #if PHP_MAJOR_VERSION < 7 493 | char * hostname = NULL; 494 | int arglen; 495 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 496 | return; 497 | } 498 | #else 499 | zend_string * hostname = NULL; 500 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 501 | return; 502 | } 503 | #endif 504 | 505 | if (GeoIP_db_avail(GEOIP_ORG_EDITION)) { 506 | gi = GeoIP_open_type(GEOIP_ORG_EDITION, GEOIP_STANDARD); 507 | } else { 508 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ORG_EDITION]); 509 | return; 510 | } 511 | 512 | org = GeoIP_org_by_name(gi, ZSTR_VAL(hostname)); 513 | GeoIP_delete(gi); 514 | if (org == NULL) { 515 | RETURN_FALSE; 516 | } 517 | _RETVAL_STRING(org); 518 | free(org); 519 | } 520 | /* }}} */ 521 | 522 | /* {{{ proto array geoip_record_by_name( string hostname ) 523 | Returns the detailed City information found in the GeoIP Database */ 524 | PHP_FUNCTION(geoip_record_by_name) 525 | { 526 | GeoIP * gi; 527 | GeoIPRecord * gir; 528 | 529 | #if PHP_MAJOR_VERSION < 7 530 | char * hostname = NULL; 531 | int arglen; 532 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 533 | return; 534 | } 535 | #else 536 | zend_string * hostname = NULL; 537 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 538 | return; 539 | } 540 | #endif 541 | 542 | if (GeoIP_db_avail(GEOIP_CITY_EDITION_REV1) || GeoIP_db_avail(GEOIP_CITY_EDITION_REV0)) { 543 | if (GeoIP_db_avail(GEOIP_CITY_EDITION_REV1)) { 544 | gi = GeoIP_open_type(GEOIP_CITY_EDITION_REV1, GEOIP_STANDARD); 545 | } else { 546 | gi = GeoIP_open_type(GEOIP_CITY_EDITION_REV0, GEOIP_STANDARD); 547 | } 548 | } else { 549 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_CITY_EDITION_REV0]); 550 | return; 551 | } 552 | gir = GeoIP_record_by_name(gi, ZSTR_VAL(hostname)); 553 | 554 | GeoIP_delete(gi); 555 | 556 | if (NULL == gir) { 557 | RETURN_FALSE; 558 | } 559 | 560 | array_init(return_value); 561 | #if LIBGEOIP_VERSION >= 1004003 562 | _add_assoc_string(return_value, "continent_code", (gir->continent_code == NULL) ? "" : gir->continent_code); 563 | #endif 564 | _add_assoc_string(return_value, "country_code", (gir->country_code == NULL) ? "" : gir->country_code); 565 | _add_assoc_string(return_value, "country_code3", (gir->country_code3 == NULL) ? "" : gir->country_code3); 566 | _add_assoc_string(return_value, "country_name", (gir->country_name == NULL) ? "" : gir->country_name); 567 | _add_assoc_string(return_value, "region", (gir->region == NULL) ? "" : gir->region); 568 | _add_assoc_string(return_value, "city", (gir->city == NULL) ? "" : gir->city); 569 | _add_assoc_string(return_value, "postal_code", (gir->postal_code == NULL) ? "" : gir->postal_code); 570 | add_assoc_double(return_value, "latitude", gir->latitude); 571 | add_assoc_double(return_value, "longitude", gir->longitude); 572 | #if LIBGEOIP_VERSION >= 1004005 573 | add_assoc_long(return_value, "dma_code", gir->metro_code); 574 | #else 575 | add_assoc_long(return_value, "dma_code", gir->dma_code); 576 | #endif 577 | add_assoc_long(return_value, "area_code", gir->area_code); 578 | 579 | GeoIPRecord_delete(gir); 580 | } 581 | /* }}} */ 582 | 583 | /* {{{ proto integer geoip_id_by_name( string hostname ) 584 | Returns the Net Speed found in the GeoIP Database */ 585 | PHP_FUNCTION(geoip_id_by_name) 586 | { 587 | GeoIP * gi; 588 | int netspeed; 589 | 590 | #if PHP_MAJOR_VERSION < 7 591 | char * hostname = NULL; 592 | int arglen; 593 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 594 | return; 595 | } 596 | #else 597 | zend_string * hostname = NULL; 598 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 599 | return; 600 | } 601 | #endif 602 | 603 | if (GeoIP_db_avail(GEOIP_NETSPEED_EDITION)) { 604 | gi = GeoIP_open_type(GEOIP_NETSPEED_EDITION, GEOIP_STANDARD); 605 | } else { 606 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_NETSPEED_EDITION]); 607 | return; 608 | } 609 | 610 | netspeed = GeoIP_id_by_name(gi, ZSTR_VAL(hostname)); 611 | GeoIP_delete(gi); 612 | RETURN_LONG(netspeed); 613 | } 614 | /* }}} */ 615 | 616 | /* {{{ proto array geoip_region_by_name( string hostname ) 617 | Returns the Country Code and region found in the GeoIP Database */ 618 | PHP_FUNCTION(geoip_region_by_name) 619 | { 620 | GeoIP * gi; 621 | GeoIPRegion * region; 622 | 623 | #if PHP_MAJOR_VERSION < 7 624 | char * hostname = NULL; 625 | int arglen; 626 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 627 | return; 628 | } 629 | #else 630 | zend_string * hostname = NULL; 631 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 632 | return; 633 | } 634 | #endif 635 | 636 | if (GeoIP_db_avail(GEOIP_REGION_EDITION_REV0) || GeoIP_db_avail(GEOIP_REGION_EDITION_REV1)) { 637 | if (GeoIP_db_avail(GEOIP_REGION_EDITION_REV1)) { 638 | gi = GeoIP_open_type(GEOIP_REGION_EDITION_REV1, GEOIP_STANDARD); 639 | } else { 640 | gi = GeoIP_open_type(GEOIP_REGION_EDITION_REV0, GEOIP_STANDARD); 641 | } 642 | } else { 643 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_REGION_EDITION_REV0]); 644 | return; 645 | } 646 | 647 | region = GeoIP_region_by_name(gi, ZSTR_VAL(hostname)); 648 | GeoIP_delete(gi); 649 | 650 | if (NULL == region) { 651 | RETURN_FALSE; 652 | } 653 | 654 | array_init(return_value); 655 | _add_assoc_string(return_value, "country_code", region->country_code); 656 | _add_assoc_string(return_value, "region", region->region); 657 | 658 | GeoIPRegion_delete(region); 659 | } 660 | /* }}} */ 661 | 662 | /* {{{ proto string geoip_isp_by_name( string hostname ) 663 | Returns the ISP Name found in the GeoIP Database */ 664 | PHP_FUNCTION(geoip_isp_by_name) 665 | { 666 | GeoIP * gi; 667 | char * isp; 668 | 669 | #if PHP_MAJOR_VERSION < 7 670 | char * hostname = NULL; 671 | int arglen; 672 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 673 | return; 674 | } 675 | #else 676 | zend_string * hostname = NULL; 677 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &hostname) == FAILURE) { 678 | return; 679 | } 680 | #endif 681 | 682 | if (GeoIP_db_avail(GEOIP_ISP_EDITION)) { 683 | gi = GeoIP_open_type(GEOIP_ISP_EDITION, GEOIP_STANDARD); 684 | } else { 685 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ISP_EDITION]); 686 | return; 687 | } 688 | 689 | isp = GeoIP_name_by_name(gi, ZSTR_VAL(hostname)); 690 | GeoIP_delete(gi); 691 | if (isp == NULL) { 692 | RETURN_FALSE; 693 | } 694 | _RETVAL_STRING(isp); 695 | free(isp); 696 | } 697 | 698 | #if LIBGEOIP_VERSION >= 1004001 699 | /* {{{ proto string geoip_region_name_by_code( string country_code, string region_code ) 700 | Returns the region name for some country code and region code combo */ 701 | PHP_FUNCTION(geoip_region_name_by_code) 702 | { 703 | GeoIP * gi; 704 | const char * region_name; 705 | 706 | #if PHP_MAJOR_VERSION < 7 707 | char * country_code = NULL; 708 | char * region_code = NULL; 709 | int countrylen, regionlen; 710 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &country_code, &countrylen, ®ion_code, ®ionlen) == FAILURE) { 711 | return; 712 | } 713 | #else 714 | zend_string * country_code = NULL; 715 | zend_string * region_code = NULL; 716 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SS", &country_code, ®ion_code) == FAILURE) { 717 | return; 718 | } 719 | int countrylen = ZSTR_LEN(country_code); 720 | int regionlen = ZSTR_LEN(region_code); 721 | #endif 722 | 723 | if (!countrylen || !regionlen) { 724 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "You need to specify the country and region codes."); 725 | RETURN_FALSE; 726 | } 727 | 728 | region_name = GeoIP_region_name_by_code(ZSTR_VAL(country_code), ZSTR_VAL(region_code)); 729 | if (region_name == NULL) { 730 | RETURN_FALSE; 731 | } 732 | _RETURN_STRING((char*)region_name); 733 | } 734 | /* }}} */ 735 | #endif 736 | 737 | #if LIBGEOIP_VERSION >= 1004001 738 | /* {{{ proto string geoip_time_zone_by_country_and_region( string country, string region ) 739 | Returns the time zone for some country code and region code combo */ 740 | PHP_FUNCTION(geoip_time_zone_by_country_and_region) 741 | { 742 | GeoIP * gi; 743 | const char * timezone; 744 | 745 | #if PHP_MAJOR_VERSION < 7 746 | char * country = NULL; 747 | char * region = NULL; 748 | int countrylen, arg2len; 749 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &country, &countrylen, ®ion, &arg2len) == FAILURE) { 750 | return; 751 | } 752 | #else 753 | zend_string * country = NULL; 754 | zend_string * region = NULL; 755 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S|S", &country, ®ion) == FAILURE) { 756 | return; 757 | } 758 | int countrylen = ZSTR_LEN(country); 759 | #endif 760 | 761 | if (!countrylen) { 762 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "You need to specify at least the country code."); 763 | RETURN_FALSE; 764 | } 765 | 766 | timezone = GeoIP_time_zone_by_country_and_region(ZSTR_VAL(country), ZSTR_VAL(region)); 767 | if (timezone == NULL) { 768 | RETURN_FALSE; 769 | } 770 | _RETURN_STRING((char*)timezone); 771 | } 772 | /* }}} */ 773 | #endif 774 | 775 | 776 | /* {{{ proto string geoip_country_code_by_addr( string addr ) 777 | Return the Country Code found in the GeoIP Database */ 778 | PHP_FUNCTION(geoip_country_code_by_addr) 779 | { 780 | GeoIP * gi; 781 | const char * country_code; 782 | 783 | #if PHP_MAJOR_VERSION < 7 784 | char * addr = NULL; 785 | int arglen; 786 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &arglen) == FAILURE) { 787 | return; 788 | } 789 | #else 790 | zend_string *addr; 791 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &addr) == FAILURE) { 792 | return; 793 | } 794 | #endif 795 | 796 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 797 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 798 | } else { 799 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 800 | return; 801 | } 802 | 803 | country_code = GeoIP_country_code_by_addr(gi, ZSTR_VAL(addr)); 804 | GeoIP_delete(gi); 805 | if (country_code == NULL) { 806 | RETURN_FALSE; 807 | } 808 | _RETURN_STRING((char*)country_code); 809 | } 810 | /* }}} */ 811 | 812 | /* {{{ proto string geoip_country_code3_by_addr( string addr ) 813 | Return the Country Code found in the GeoIP Database */ 814 | PHP_FUNCTION(geoip_country_code3_by_addr) 815 | { 816 | GeoIP * gi; 817 | 818 | #if PHP_MAJOR_VERSION < 7 819 | char * addr; 820 | int arglen; 821 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &addr, &arglen) == FAILURE) { 822 | return; 823 | } 824 | #else 825 | zend_string * addr; 826 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &addr) == FAILURE) { 827 | return; 828 | } 829 | #endif 830 | 831 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 832 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 833 | } else { 834 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 835 | return; 836 | } 837 | 838 | const char *country_code = GeoIP_country_code3_by_addr(gi, ZSTR_VAL(addr)); 839 | GeoIP_delete(gi); 840 | if (country_code == NULL) { 841 | RETURN_FALSE; 842 | } 843 | _RETURN_STRING((char*)country_code); 844 | } 845 | /* }}} */ 846 | 847 | /* {{{ proto void geoip_setup_custom_directory( string directory ) 848 | Sets the custom directory for GeoIP databases */ 849 | PHP_FUNCTION(geoip_setup_custom_directory) 850 | { 851 | 852 | #if PHP_MAJOR_VERSION < 7 853 | char * dir = NULL; 854 | int arglen; 855 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &dir, &arglen) == FAILURE) { 856 | return; 857 | } 858 | #else 859 | zend_string * dir = NULL; 860 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &dir) == FAILURE) { 861 | return; 862 | } 863 | #endif 864 | 865 | GEOIP_G(set_runtime_custom_directory) = 1; 866 | 867 | if (GeoIPDBFileName != NULL) { 868 | free(GeoIPDBFileName); 869 | GeoIPDBFileName = NULL; 870 | } 871 | 872 | GeoIP_setup_custom_directory(ZSTR_VAL(dir)); 873 | _GeoIP_setup_dbfilename(); 874 | } 875 | /* }}} */ 876 | 877 | /* 878 | * Local variables: 879 | * tab-width: 4 880 | * c-basic-offset: 4 881 | * End: 882 | * vim600: noet sw=4 ts=4 fdm=marker 883 | * vim<600: noet sw=4 ts=4 884 | */ 885 | -------------------------------------------------------------------------------- /php_geoip.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2009 The PHP Group | 6 | +----------------------------------------------------------------------+ 7 | | This source file is subject to version 3.01 of the PHP license, | 8 | | that is bundled with this package in the file LICENSE, and is | 9 | | available through the world-wide-web at the following url: | 10 | | http://www.php.net/license/3_01.txt. | 11 | | If you did not receive a copy of the PHP license and are unable to | 12 | | obtain it through the world-wide-web, please send a note to | 13 | | license@php.net so we can mail you a copy immediately. | 14 | +----------------------------------------------------------------------+ 15 | | Author: Olivier Hill | 16 | | Matthew Fonda | 17 | +----------------------------------------------------------------------+ 18 | Please contact support@maxmind.com with any comments 19 | */ 20 | 21 | #ifndef PHP_GEOIP_H 22 | #define PHP_GEOIP_H 23 | 24 | extern zend_module_entry geoip_module_entry; 25 | #define phpext_geoip_ptr &geoip_module_entry 26 | 27 | #define PHP_GEOIP_VERSION "1.0.7" 28 | 29 | #ifdef PHP_WIN32 30 | #define PHP_GEOIP_API __declspec(dllexport) 31 | #else 32 | #define PHP_GEOIP_API 33 | #endif 34 | 35 | #ifdef ZTS 36 | #include "TSRM.h" 37 | #endif 38 | 39 | #include 40 | #include 41 | 42 | PHP_MINIT_FUNCTION(geoip); 43 | PHP_MSHUTDOWN_FUNCTION(geoip); 44 | PHP_RINIT_FUNCTION(geoip); 45 | PHP_RSHUTDOWN_FUNCTION(geoip); 46 | PHP_MINFO_FUNCTION(geoip); 47 | 48 | 49 | PHP_FUNCTION(geoip_database_info); 50 | PHP_FUNCTION(geoip_country_code_by_name); 51 | PHP_FUNCTION(geoip_country_code3_by_name); 52 | PHP_FUNCTION(geoip_country_name_by_name); 53 | PHP_FUNCTION(geoip_continent_code_by_name); 54 | PHP_FUNCTION(geoip_org_by_name); 55 | PHP_FUNCTION(geoip_record_by_name); 56 | PHP_FUNCTION(geoip_id_by_name); 57 | PHP_FUNCTION(geoip_region_by_name); 58 | PHP_FUNCTION(geoip_isp_by_name); 59 | PHP_FUNCTION(geoip_db_avail); 60 | PHP_FUNCTION(geoip_db_get_all_info); 61 | PHP_FUNCTION(geoip_db_filename); 62 | #if LIBGEOIP_VERSION >= 1004001 63 | PHP_FUNCTION(geoip_region_name_by_code); 64 | PHP_FUNCTION(geoip_time_zone_by_country_and_region); 65 | #endif 66 | PHP_FUNCTION(geoip_country_code_by_addr); 67 | PHP_FUNCTION(geoip_country_code3_by_addr); 68 | PHP_FUNCTION(geoip_setup_custom_directory); 69 | 70 | ZEND_BEGIN_MODULE_GLOBALS(geoip) 71 | char* custom_directory; 72 | int set_runtime_custom_directory; 73 | ZEND_END_MODULE_GLOBALS(geoip) 74 | 75 | #ifdef ZTS 76 | #define GEOIP_G(v) TSRMG(geoip_globals_id, zend_geoip_globals *, v) 77 | #else 78 | #define GEOIP_G(v) (geoip_globals.v) 79 | #endif 80 | 81 | #endif /* PHP_GEOIP_H */ 82 | 83 | 84 | /* 85 | * Local variables: 86 | * tab-width: 4 87 | * c-basic-offset: 4 88 | * End: 89 | * vim600: noet sw=4 ts=4 fdm=marker 90 | * vim<600: noet sw=4 ts=4 91 | */ 92 | --------------------------------------------------------------------------------