├── tests ├── 003.phpt ├── 008.phpt ├── 009.phpt ├── 001.phpt ├── 015.phpt ├── 006.phpt ├── 011.phpt ├── 007.phpt ├── 013.phpt ├── 019.phpt ├── 005.phpt ├── 004.phpt ├── 010.phpt ├── 017.phpt ├── 018.phpt ├── 014.phpt ├── 016.phpt └── 002.phpt ├── README ├── config.w32 ├── geoip.def ├── LICENSE ├── php_geoip.h ├── ChangeLog ├── config.m4 ├── package.xml └── geoip.c /tests/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for database filename 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECTF-- 12 | string(%d) "%sGeoIP.dat" 13 | -------------------------------------------------------------------------------- /tests/008.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Calling geoip_db_filename() with a non-existant database type within bound. 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | NULL 13 | -------------------------------------------------------------------------------- /tests/009.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Calling geoip_db_avail() with a non-existant database type within bound. 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECT-- 12 | bool(false) 13 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking Country (Free) DB availability 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | bool(true) 15 | -------------------------------------------------------------------------------- /tests/015.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_region_name_by_code for Canada/Quebec 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(6) "Quebec" 15 | -------------------------------------------------------------------------------- /tests/006.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for custom directory INI entry 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test" 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(15) "/test/GeoIP.dat" 15 | -------------------------------------------------------------------------------- /tests/011.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Calling geoip_database_info() with a non-existant database type within bound. 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 11 | --EXPECTF-- 12 | Warning: geoip_database_info(): Required database not available. in %s on line %d 13 | -------------------------------------------------------------------------------- /tests/007.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for custom directory INI entry (with trailing slash) 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test/" 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(15) "/test/GeoIP.dat" 15 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This PHP extension allows you to find the location of an IP address - City, State, 2 | Country, Longitude, Latitude, and other information as all, such as ISP and connection type. 3 | 4 | To compile it, you will need to have the GeoIP c library installed. 5 | 6 | For installation instructions for PHP extensions, see: 7 | http://www.php.net/manual/en/install.pecl.php 8 | -------------------------------------------------------------------------------- /tests/013.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking timezone info 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 13 | --EXPECT-- 14 | string(17) "America/Vancouver" 15 | string(10) "Asia/Tokyo" 16 | -------------------------------------------------------------------------------- /tests/019.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_country_code_by_name_v6 (if IPv6 DB installed) 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | --FILE-- 7 | 12 | --EXPECT-- 13 | string(2) "US" 14 | -------------------------------------------------------------------------------- /tests/005.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for out of bound type with geoip_db_avail() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECTF-- 13 | Warning: geoip_db_avail(): Database type given is out of bound. in %s on line %d 14 | 15 | Warning: geoip_db_avail(): Database type given is out of bound. in %s on line %d 16 | 17 | -------------------------------------------------------------------------------- /tests/004.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for out of bound type with geoip_db_filename() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECTF-- 13 | Warning: geoip_db_filename(): Database type given is out of bound. in %s on line %d 14 | 15 | Warning: geoip_db_filename(): Database type given is out of bound. in %s on line %d 16 | 17 | -------------------------------------------------------------------------------- /tests/010.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking for out of bound type with geoip_database_info() 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 12 | --EXPECTF-- 13 | Warning: geoip_database_info(): Database type given is out of bound. in %s on line %d 14 | 15 | Warning: geoip_database_info(): Database type given is out of bound. in %s on line %d 16 | 17 | -------------------------------------------------------------------------------- /tests/017.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_setup_custom_directory() 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test" 7 | --FILE-- 8 | 15 | --EXPECT-- 16 | string(27) "/some/other/place/GeoIP.dat" 17 | string(5) "/test" -------------------------------------------------------------------------------- /tests/018.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_setup_custom_directory() (with trailing slash) 3 | --SKIPIF-- 4 | 5 | --INI-- 6 | geoip.custom_directory="/test/" 7 | --FILE-- 8 | 15 | --EXPECT-- 16 | string(27) "/some/other/place/GeoIP.dat" 17 | string(6) "/test/" -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | ARG_WITH("geoip", "GeoIP Support", "no"); 5 | 6 | if (PHP_GEOIP == "yes") { 7 | if (CHECK_HEADER_ADD_INCLUDE("geoip.h", "CFLAGS_GEOIP", PHP_GEOIP + ";" + PHP_PHP_BUILD + "\\include\\geoip") && 8 | CHECK_LIB("geoip_a.lib;GeoIP.lib", "geoip", PHP_GEOIP)) { 9 | AC_DEFINE('HAVE_GEOIP', 1, 'Have GeoIP support', false); 10 | AC_DEFINE('LIBGEOIP_VERSION', 1006009, 'GeoIP Version'); 11 | AC_DEFINE('HAVE_CUSTOM_DIRECTORY', 1, 'Support for custom database directory'); 12 | EXTENSION("geoip", "geoip.c"); 13 | } else { 14 | WARNING('Could not find geoip.h or geoip lib; skipping'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/014.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking timezone info with (some) empty fields 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 16 | --EXPECTF-- 17 | string(%d) "America/%s" 18 | bool(false) 19 | string(%d) "Europe/%s" 20 | 21 | Warning: geoip_time_zone_by_country_and_region(): You need to specify at least the country code. in %s on line %d 22 | bool(false) 23 | -------------------------------------------------------------------------------- /tests/016.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking geoip_region_name_by_code with (some) empty fields 3 | --SKIPIF-- 4 | 5 | --POST-- 6 | --GET-- 7 | --FILE-- 8 | 16 | --EXPECTF-- 17 | 18 | Warning: geoip_region_name_by_code(): You need to specify the country and region codes. in %s on line %d 19 | bool(false) 20 | bool(false) 21 | 22 | Warning: geoip_region_name_by_code(): You need to specify the country and region codes. in %s on line %d 23 | bool(false) 24 | bool(false) 25 | -------------------------------------------------------------------------------- /tests/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Checking if all db info and name match 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 23 | --EXPECT-- 24 | string(21) "GeoIP Country Edition" 25 | string(27) "GeoIP Region Edition, Rev 0" 26 | string(25) "GeoIP City Edition, Rev 0" 27 | string(26) "GeoIP Organization Edition" 28 | string(17) "GeoIP ISP Edition" 29 | string(25) "GeoIP City Edition, Rev 1" 30 | string(27) "GeoIP Region Edition, Rev 1" 31 | string(19) "GeoIP Proxy Edition" 32 | string(19) "GeoIP ASNum Edition" 33 | string(22) "GeoIP Netspeed Edition" 34 | string(25) "GeoIP Domain Name Edition" 35 | -------------------------------------------------------------------------------- /geoip.def: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 2002-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 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* GEOIPDEF(php_func, c_func, db_type) */ 20 | GEOIPDEF(geoip_country_code_by_name, GeoIP_country_code_by_name, GEOIP_COUNTRY_EDITION) 21 | GEOIPDEF(geoip_country_code3_by_name, GeoIP_country_code3_by_name, GEOIP_COUNTRY_EDITION) 22 | GEOIPDEF(geoip_country_name_by_name, GeoIP_country_name_by_name, GEOIP_COUNTRY_EDITION) 23 | 24 | #if LIBGEOIP_VERSION >= 1004005 25 | GEOIPDEF(geoip_country_code_by_name_v6, GeoIP_country_code_by_name_v6, GEOIP_COUNTRY_EDITION_V6) 26 | GEOIPDEF(geoip_country_code3_by_name_v6, GeoIP_country_code3_by_name_v6, GEOIP_COUNTRY_EDITION_V6) 27 | GEOIPDEF(geoip_country_name_by_name_v6, GeoIP_country_name_by_name_v6, GEOIP_COUNTRY_EDITION_V6) 28 | #endif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------- 2 | The PHP License, version 3.01 3 | Copyright (c) 1999 - 2014 The PHP Group. All rights reserved. 4 | -------------------------------------------------------------------- 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, is permitted provided that the following conditions 8 | are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | 13 | 2. Redistributions in binary form must reproduce the above copyright 14 | notice, this list of conditions and the following disclaimer in 15 | the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | 3. The name "PHP" must not be used to endorse or promote products 19 | derived from this software without prior written permission. For 20 | written permission, please contact group@php.net. 21 | 22 | 4. Products derived from this software may not be called "PHP", nor 23 | may "PHP" appear in their name, without prior written permission 24 | from group@php.net. You may indicate that your software works in 25 | conjunction with PHP by saying "Foo for PHP" instead of calling 26 | it "PHP Foo" or "phpfoo" 27 | 28 | 5. The PHP Group may publish revised and/or new versions of the 29 | license from time to time. Each version will be given a 30 | distinguishing version number. 31 | Once covered code has been published under a particular version 32 | of the license, you may always continue to use it under the terms 33 | of that version. You may also choose to use such covered code 34 | under the terms of any subsequent version of the license 35 | published by the PHP Group. No one other than the PHP Group has 36 | the right to modify the terms applicable to covered code created 37 | under this License. 38 | 39 | 6. Redistributions of any form whatsoever must retain the following 40 | acknowledgment: 41 | "This product includes PHP software, freely available from 42 | ". 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND 45 | ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 47 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP 48 | DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 49 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 50 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 51 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 53 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 54 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 55 | OF THE POSSIBILITY OF SUCH DAMAGE. 56 | 57 | -------------------------------------------------------------------- 58 | 59 | This software consists of voluntary contributions made by many 60 | individuals on behalf of the PHP Group. 61 | 62 | The PHP Group can be contacted via Email at group@php.net. 63 | 64 | For more information on the PHP Group and the PHP project, 65 | please see . 66 | 67 | PHP includes the Zend Engine, freely available at 68 | . 69 | -------------------------------------------------------------------------------- /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.1.2-dev" 28 | 29 | #if PHP_MAJOR_VERSION < 7 30 | typedef long zend_long; 31 | #endif 32 | 33 | #ifdef PHP_WIN32 34 | #define PHP_GEOIP_API __declspec(dllexport) 35 | #else 36 | #define PHP_GEOIP_API 37 | #endif 38 | 39 | #ifdef ZTS 40 | #include "TSRM.h" 41 | #endif 42 | 43 | #include 44 | #include 45 | 46 | PHP_MINIT_FUNCTION(geoip); 47 | PHP_MSHUTDOWN_FUNCTION(geoip); 48 | PHP_RINIT_FUNCTION(geoip); 49 | PHP_RSHUTDOWN_FUNCTION(geoip); 50 | PHP_MINFO_FUNCTION(geoip); 51 | 52 | 53 | PHP_FUNCTION(geoip_database_info); 54 | #define GEOIPDEF(php_func, c_func, db_type) \ 55 | PHP_FUNCTION(php_func); 56 | #include "geoip.def" 57 | #undef GEOIPDEF 58 | PHP_FUNCTION(geoip_continent_code_by_name); 59 | PHP_FUNCTION(geoip_org_by_name); 60 | PHP_FUNCTION(geoip_record_by_name); 61 | PHP_FUNCTION(geoip_id_by_name); 62 | PHP_FUNCTION(geoip_region_by_name); 63 | PHP_FUNCTION(geoip_isp_by_name); 64 | PHP_FUNCTION(geoip_db_avail); 65 | PHP_FUNCTION(geoip_db_get_all_info); 66 | PHP_FUNCTION(geoip_db_filename); 67 | #if LIBGEOIP_VERSION >= 1004001 68 | PHP_FUNCTION(geoip_region_name_by_code); 69 | PHP_FUNCTION(geoip_time_zone_by_country_and_region); 70 | #endif 71 | #ifdef HAVE_CUSTOM_DIRECTORY 72 | PHP_FUNCTION(geoip_setup_custom_directory); 73 | #endif 74 | PHP_FUNCTION(geoip_asnum_by_name); 75 | PHP_FUNCTION(geoip_domain_by_name); 76 | #if LIBGEOIP_VERSION >= 1004008 77 | PHP_FUNCTION(geoip_netspeedcell_by_name); 78 | #endif 79 | 80 | ZEND_BEGIN_MODULE_GLOBALS(geoip) 81 | char* custom_directory; 82 | int set_runtime_custom_directory; 83 | ZEND_END_MODULE_GLOBALS(geoip) 84 | 85 | #ifdef ZTS 86 | #define GEOIP_G(v) TSRMG(geoip_globals_id, zend_geoip_globals *, v) 87 | #else 88 | #define GEOIP_G(v) (geoip_globals.v) 89 | #endif 90 | 91 | #endif /* PHP_GEOIP_H */ 92 | 93 | 94 | /* 95 | * Local variables: 96 | * tab-width: 4 97 | * c-basic-offset: 4 98 | * End: 99 | * vim600: noet sw=4 ts=4 fdm=marker 100 | * vim<600: noet sw=4 ts=4 101 | */ 102 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 1.1.0-dev 2012-xx-xx 2 | 3 | * Add geoip_setup_custom_directory() to setup custom directories per request. 4 | * Remove E_NOTICES for IPs not found in database. 5 | * Fix a segfault with geoip_db_get_all_info() on newer libs (bug #64692). 6 | * Add support for geoip_netspeedcell_by_name(), geoip_asnum_by_name() and geoip_domain_by_name() (bug #67121). 7 | * Fix memory leak with custom directories (bug #67138). 8 | * Support changing custom directory via ini_set() (bug #61607). 9 | 10 | 1.0.8 2011-10-23 11 | 12 | * Windows support 13 | * Fix segfault with newer geoip libraries and geoip_db_get_all_info() (bug #60066) 14 | * Use X-Macros for repeated code 15 | * Updated tests 16 | 17 | 1.0.7 2009-03-11 18 | 19 | * Do not issue a NOTICE when values don't exist for timezone and region name (as added in 1.0.4) 20 | * Fix a compile issue on FreeBSD 21 | * Try to be bulletproof on library features detection. 22 | 23 | 1.0.6 2009-01-20 24 | 25 | * Fixing compile bug when multiple GeoIP libs are installed, bug #15372 26 | 27 | 1.0.5 2008-12-19 28 | 29 | * Small bug in phpinfo() when printing version number could crash PHP. 30 | 31 | 1.0.4 2008-12-19 32 | 33 | * Fix memleaks, bug #14851 34 | * Small patch for MacPorts by jhohle 35 | * Add geoip_time_zone_by_country_and_region() and geoip_region_name_by_code() (thanks to Sid Dunayer) 36 | * Add continent_code field for City Database, only if using GeoIP lib 1.4.3 or newer 37 | 38 | 1.0.3 2008-06-12 39 | 40 | * Change license from PHP 3.0 to PHP 3.01 for Debian? 41 | * Added geoip_continent_code_by_name() to get continent instead of country 42 | * Fixing a small casting issue (compiler warning) 43 | * Fixing missing entries in geoip_record_by_name, bug #14131 44 | 45 | 1.0.2 2007-11-20 46 | 47 | * Added geoip_isp_by_name (patch by Yannick Gard) 48 | 49 | 1.0.1 2007-08-22 50 | 51 | * Added geoip_db_avail() to check for DB availability (file found) 52 | * Added geoip_db_filename() to get the internal file name of the library 53 | * Added geoip_db_get_all_info() to fetch all info about all database types 54 | * Added some tests so that make test can crunch something. 55 | * Added database file path and name in warning when DB is not found. 56 | * Added geoip.custom_directory php.ini option to change default path for DBs 57 | 58 | 1.0.0 2007-08-14 59 | 60 | * Marked as stable 61 | * Fixing wrong version number inside extension 62 | 63 | 0.2.0 2006-08-22 64 | 65 | * Initial PECL Release 66 | * Fixing various memory leaks 67 | * Registering the C API constants in PHP 68 | 69 | 0.1.3 2006-7-10 70 | 71 | Following changes made by Olivier Hill 72 | * Missing PHP function prototypes 73 | * Fixing code foldings in Emacs 74 | * Outputting E_NOTICES instead of E_WARNING when non fatal errors 75 | * Return type of longitude/latitude should be DOUBLE and not LONG 76 | 77 | 0.1.2 2006-5-19 78 | * Following changes all contributed by Guenter Knauf 79 | - moved argument parsing up at various places before we create a GeoIP. 80 | - moved GeoIP_delete() call at various places up to get it called before we error out. 81 | - fixed one place where a missing return caused a segfault on all platforms because 82 | RETURN_STRING() was called with NULL when GeoIP lookup failed. 83 | - added php.ini entry parsing; prepared for usage of geoip.database_standard var. 84 | This works fine so far as you can test with the geoip_database_info() call which uses 85 | the database configured with the geoip.database_standard var; if not set it defaults 86 | to the usual place specified during compile time with GEOIPDATADIR. All other functions 87 | currently still ignore the geoip.database_standard setting, but default usually also 88 | to GEOIPDATADIR from what I see. Search for the dirty '//' comments .... 89 | * Added config.m4, contributed by Jonathan Whiteman of cyberflowsolutions.com 90 | 91 | 0.1.1 2005-9-21 92 | * Initial release, contributed by Matthew Fonda 93 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 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/$PHP_LIBDIR, 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 | # Checking for GeoIP_addr_to_num in newer lib 85 | PHP_CHECK_LIBRARY($LIBNAME,GeoIP_addr_to_num, 86 | [ 87 | AC_DEFINE(HAVE_ADDR_TO_NUM,1,[ ]) 88 | MIN_GEOIP_VERSION=1004007 89 | ],[ 90 | ],[ 91 | -L$GEOIP_DIR/$PHP_LIBDIR -lm 92 | ]) 93 | 94 | # Checking for GEOIP_NETSPEED_EDITION_REV1 95 | AC_CHECK_DECL(GEOIP_NETSPEED_EDITION_REV1, 96 | [ 97 | MIN_GEOIP_VERSION=1004008 98 | ],[],[ 99 | #include 100 | ]) 101 | 102 | # Checking for GEOIP_ACCURACYRADIUS_EDITION 103 | AC_CHECK_DECL(GEOIP_ACCURACYRADIUS_EDITION, 104 | [ 105 | MIN_GEOIP_VERSION=1005000 106 | ],[],[ 107 | #include 108 | ]) 109 | 110 | # Check to see if we are using the LGPL library (version 1.4.0 and newer) 111 | AC_MSG_CHECKING([for LGPL compatible GeoIP libs]) 112 | libgeoip_full_version=`find $GEOIP_DIR/$PHP_LIBDIR/ -name libGeoIP.\*.\*.\*.\* | cut -d . -f 2-5 | sort` 113 | for lines in $libgeoip_full_version; do 114 | ac_IFS=$IFS 115 | IFS="." 116 | set $lines 117 | IFS=$ac_IFS 118 | done 119 | 120 | # Version after the suffix (eg: .so.1.4.0) 121 | if test "[$]1" = "$SHLIB_SUFFIX_NAME"; then 122 | LIBGEOIP_VERSION=`expr [$]2 \* 1000000 + [$]3 \* 1000 + [$]4` 123 | # Version before the suffix (eg: 1.4.0.dylib on OS X) 124 | else 125 | LIBGEOIP_VERSION=`expr [$]1 \* 1000000 + [$]2 \* 1000 + [$]3` 126 | fi 127 | 128 | # Just in case it didn't work, try alternate method, or fail 129 | if test "x$LIBGEOIP_VERSION" = "x"; then 130 | AC_MSG_RESULT([cannot detect]) 131 | 132 | # Alternate method based on library capabilities (not 100% acurate) 133 | AC_MSG_CHECKING([library features to determine version (not acurate)]) 134 | if test "x$MIN_GEOIP_VERSION" = "x"; then 135 | AC_MSG_ERROR([For some reason, libGeoIP is installed, but I cannot determine the version used]) 136 | else 137 | LIBGEOIP_VERSION=$MIN_GEOIP_VERSION 138 | fi 139 | fi 140 | 141 | if test "$LIBGEOIP_VERSION" -lt "1004000"; then 142 | AC_MSG_RESULT([wrong version]) 143 | AC_MSG_ERROR([You need version 1.4.0 or higher of the C API]) 144 | else 145 | AC_MSG_RESULT([found $LIBGEOIP_VERSION]) 146 | AC_DEFINE_UNQUOTED(LIBGEOIP_VERSION, $LIBGEOIP_VERSION, [ ]) 147 | fi 148 | 149 | PHP_SUBST(GEOIP_SHARED_LIBADD) 150 | 151 | PHP_NEW_EXTENSION(geoip, geoip.c, $ext_shared) 152 | fi 153 | 154 | -------------------------------------------------------------------------------- /package.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | geoip 7 | pecl.php.net 8 | Map IP address to geographic places 9 | This PHP extension allows you to find the location of an IP address - City, State, Country, Longitude, Latitude, and other information as all, such as ISP and connection type. For more info, please visit Maxmind's website. 10 | 11 | 12 | 13 | Olivier Hill 14 | ohill 15 | ohill@php.net 16 | yes 17 | 18 | 2016-08-18 19 | 20 | 21 | 1.1.2-dev 22 | 1.0.3 23 | 24 | 25 | beta 26 | stable 27 | 28 | PHP License 29 | * Add IPv6 support (geoip_country_code_by_*_v6) 30 | * PHP7 support (thanks to Adam and Dan Ackroyd) 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 4.3.0 67 | 68 | 69 | 1.4.0b1 70 | 71 | 72 | 73 | geoip 74 | 75 | 76 | 77 | 78 | 1.1.0 79 | 1.0.3 80 | 81 | 82 | beta 83 | stable 84 | 85 | 2014-05-01 86 | PHP License 87 | * Add geoip_setup_custom_directory() to setup custom directories per request. 88 | * Remove E_NOTICES for IPs not found in database. 89 | * Fix a segfault with geoip_db_get_all_info() on newer libs (bug #64692). 90 | * Add support for geoip_netspeedcell_by_name(), geoip_asnum_by_name() and geoip_domain_by_name() (bug #67121). 91 | * Fix memory leak with custom directories (bug #67138). 92 | * Support changing custom directory via ini_set() (bug #61607). 93 | 94 | 95 | 96 | 97 | 1.0.8 98 | 1.0.3 99 | 100 | 101 | stable 102 | stable 103 | 104 | 2011-10-23 105 | PHP License 106 | * Windows support 107 | * Fix segfault with newer geoip libraries and geoip_db_get_all_info() (bug #60066) 108 | * Use X-Macros for repeated code 109 | * Updated tests 110 | 111 | 112 | 113 | 114 | 1.0.7 115 | 1.0.3 116 | 117 | 118 | stable 119 | stable 120 | 121 | 2009-03-11 122 | PHP License 123 | * Do not issue a NOTICE when values don't exist for timezone and region name (as added in 1.0.4) 124 | * Fix a compile issue on FreeBSD 125 | * Try to be bulletproof on library features detection. 126 | 127 | 128 | 129 | 130 | 1.0.6 131 | 1.0.3 132 | 133 | 134 | stable 135 | stable 136 | 137 | 2009-01-20 138 | PHP License 139 | * Fixing compile bug when multiple GeoIP libs are installed, bug #15372. 140 | 141 | 142 | 143 | 144 | 1.0.5 145 | 1.0.3 146 | 147 | 148 | stable 149 | stable 150 | 151 | 2008-12-19 152 | PHP License 153 | * Small bug in phpinfo() when printing version number could crash PHP. 154 | 155 | 156 | 157 | 158 | 1.0.4 159 | 1.0.3 160 | 161 | 162 | stable 163 | stable 164 | 165 | 2008-12-19 166 | PHP License 167 | * Fix memleaks, bug #14851 168 | * Small patch for MacPorts by jhohle 169 | * Add geoip_time_zone_by_country_and_region() and geoip_region_name_by_code() (thanks to Sid Dunayer) 170 | * Add continent_code field for City Database, only if using GeoIP lib 1.4.3 or newer 171 | 172 | 173 | 174 | 175 | 1.0.3 176 | 1.0.3 177 | 178 | 179 | stable 180 | stable 181 | 182 | 2008-06-12 183 | PHP License 184 | * Change license from PHP 3.0 to PHP 3.01 for Debian? 185 | * Added geoip_continent_code_by_name() to get continent instead of country 186 | * Fixing a small casting issue (compiler warning) 187 | * Fixing missing entries in geoip_record_by_name(), bug #14131 188 | 189 | 190 | 191 | 192 | 1.0.2 193 | 1.0.2 194 | 195 | 196 | stable 197 | stable 198 | 199 | 2007-11-20 200 | PHP 201 | * Added geoip_isp_by_name (patch by Yannick Gard) 202 | 203 | 204 | 205 | 206 | 1.0.1 207 | 1.0.1 208 | 209 | 210 | stable 211 | stable 212 | 213 | 2007-08-22 214 | PHP 215 | * Added geoip_db_avail() to check for DB availability (file found) 216 | * Added geoip_db_filename() to get the internal file name of the library 217 | * Added geoip_db_get_all_info() to fetch all info about all database types 218 | * Added some tests so that make test can crunch something. 219 | * Added database file path and name in warning when DB is not found. 220 | * Added geoip.custom_directory php.ini option to change default path for DBs 221 | 222 | 223 | 224 | 225 | 1.0.0 226 | 1.0.0 227 | 228 | 229 | stable 230 | stable 231 | 232 | 2007-08-14 233 | PHP 234 | * Marked as stable 235 | * Fixing wrong version number inside extension 236 | 237 | 238 | 239 | 240 | 0.2.0 241 | 0.2.0 242 | 243 | 244 | beta 245 | beta 246 | 247 | 2006-08-22 248 | PHP 249 | Initial PECL release 250 | 251 | 252 | 253 | 254 | -------------------------------------------------------------------------------- /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 | #ifdef PHP_WIN32 29 | #include 30 | #endif 31 | 32 | #include "php.h" 33 | #include "php_ini.h" 34 | #include "ext/standard/info.h" 35 | #include "php_geoip.h" 36 | 37 | /* For PHP 8 */ 38 | #ifndef TSRMLS_CC 39 | #define TSRMLS_CC 40 | #endif 41 | 42 | ZEND_DECLARE_MODULE_GLOBALS(geoip) 43 | 44 | ZEND_BEGIN_ARG_INFO_EX(arginfo_geoip_void, 0, 0, 0) 45 | ZEND_END_ARG_INFO() 46 | 47 | ZEND_BEGIN_ARG_INFO_EX(arginfo_geoip_database_opt, 0, 0, 0) 48 | ZEND_ARG_INFO(0, database) 49 | ZEND_END_ARG_INFO() 50 | 51 | ZEND_BEGIN_ARG_INFO_EX(arginfo_geoip_database, 0, 0, 1) 52 | ZEND_ARG_INFO(0, database) 53 | ZEND_END_ARG_INFO() 54 | 55 | ZEND_BEGIN_ARG_INFO_EX(arginfo_geoip_host, 0, 0, 1) 56 | ZEND_ARG_INFO(0, host) 57 | ZEND_END_ARG_INFO() 58 | 59 | ZEND_BEGIN_ARG_INFO_EX(arginfo_geoip_region, 0, 0, 2) 60 | ZEND_ARG_INFO(0, country_code) 61 | ZEND_ARG_INFO(0, region_code) 62 | ZEND_END_ARG_INFO() 63 | 64 | ZEND_BEGIN_ARG_INFO_EX(arginfo_geoip_directory, 0, 0, 1) 65 | ZEND_ARG_INFO(0, directory) 66 | ZEND_END_ARG_INFO() 67 | 68 | static int le_geoip; 69 | 70 | /* {{{ */ 71 | zend_function_entry geoip_functions[] = { 72 | PHP_FE(geoip_database_info, arginfo_geoip_database_opt) 73 | #define GEOIPDEF(php_func, c_func, db_type) \ 74 | PHP_FE(php_func, arginfo_geoip_host) 75 | #include "geoip.def" 76 | #undef GEOIPDEF 77 | PHP_FE(geoip_continent_code_by_name, arginfo_geoip_host) 78 | PHP_FE(geoip_org_by_name, arginfo_geoip_host) 79 | PHP_FE(geoip_record_by_name, arginfo_geoip_host) 80 | PHP_FE(geoip_id_by_name, arginfo_geoip_host) 81 | PHP_FE(geoip_region_by_name, arginfo_geoip_host) 82 | PHP_FE(geoip_isp_by_name, arginfo_geoip_host) 83 | PHP_FE(geoip_db_avail, arginfo_geoip_database) 84 | PHP_FE(geoip_db_get_all_info, arginfo_geoip_void) 85 | PHP_FE(geoip_db_filename, arginfo_geoip_database) 86 | #if LIBGEOIP_VERSION >= 1004001 87 | PHP_FE(geoip_region_name_by_code, arginfo_geoip_region) 88 | PHP_FE(geoip_time_zone_by_country_and_region, arginfo_geoip_region) 89 | #endif 90 | #ifdef HAVE_CUSTOM_DIRECTORY 91 | PHP_FE(geoip_setup_custom_directory, arginfo_geoip_directory) 92 | #endif 93 | PHP_FE(geoip_asnum_by_name, arginfo_geoip_host) 94 | PHP_FE(geoip_domain_by_name, arginfo_geoip_host) 95 | #if LIBGEOIP_VERSION >= 1004008 96 | PHP_FE(geoip_netspeedcell_by_name, arginfo_geoip_host) 97 | #endif 98 | #ifdef PHP_FE_END 99 | PHP_FE_END 100 | #else 101 | {NULL, NULL, NULL} 102 | #endif 103 | }; 104 | /* }}} */ 105 | 106 | /* {{{ geoip_module_entry 107 | */ 108 | zend_module_entry geoip_module_entry = { 109 | #if ZEND_MODULE_API_NO >= 20010901 110 | STANDARD_MODULE_HEADER, 111 | #endif 112 | "geoip", 113 | geoip_functions, 114 | PHP_MINIT(geoip), 115 | PHP_MSHUTDOWN(geoip), 116 | PHP_RINIT(geoip), 117 | PHP_RSHUTDOWN(geoip), 118 | PHP_MINFO(geoip), 119 | #if ZEND_MODULE_API_NO >= 20010901 120 | PHP_GEOIP_VERSION, /* version number of the extension */ 121 | #endif 122 | STANDARD_MODULE_PROPERTIES 123 | }; 124 | /* }}} */ 125 | 126 | #ifdef COMPILE_DL_GEOIP 127 | ZEND_GET_MODULE(geoip) 128 | #endif 129 | 130 | #ifdef HAVE_CUSTOM_DIRECTORY 131 | /* {{{ geoip_change_custom_directory() helper function 132 | */ 133 | static void geoip_change_custom_directory(char *value) 134 | { 135 | #if LIBGEOIP_VERSION >= 1004007 136 | GeoIP_cleanup(); 137 | #else 138 | int i; 139 | if (GeoIPDBFileName != NULL) { 140 | for (i = 0; i < NUM_DB_TYPES; i++) { 141 | if (GeoIPDBFileName[i]) { 142 | free(GeoIPDBFileName[i]); 143 | } 144 | } 145 | free(GeoIPDBFileName); 146 | GeoIPDBFileName = NULL; 147 | } 148 | #endif 149 | 150 | GeoIP_setup_custom_directory(value); 151 | GeoIP_db_avail(GEOIP_COUNTRY_EDITION); 152 | } 153 | /* }}} */ 154 | #endif 155 | 156 | #ifdef HAVE_CUSTOM_DIRECTORY 157 | /* {{{ PHP_INI_MH 158 | + */ 159 | static PHP_INI_MH(OnUpdateDirectory) 160 | { 161 | if (stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) { 162 | GEOIP_G(set_runtime_custom_directory) = 1; 163 | #if PHP_MAJOR_VERSION >= 7 164 | geoip_change_custom_directory(new_value->val); 165 | #else 166 | geoip_change_custom_directory(new_value); 167 | #endif 168 | return SUCCESS; 169 | } 170 | 171 | #if PHP_MAJOR_VERSION >= 7 172 | return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); 173 | #else 174 | return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); 175 | #endif 176 | } 177 | /* }}} */ 178 | #endif 179 | 180 | /* {{{ PHP_INI 181 | */ 182 | PHP_INI_BEGIN() 183 | #ifdef HAVE_CUSTOM_DIRECTORY 184 | STD_PHP_INI_ENTRY("geoip.custom_directory", NULL, PHP_INI_ALL, OnUpdateDirectory, custom_directory, zend_geoip_globals, geoip_globals) 185 | #endif 186 | PHP_INI_END() 187 | /* }}} */ 188 | 189 | /* {{{ php_geoip_init_globals 190 | */ 191 | static void php_geoip_init_globals(zend_geoip_globals *geoip_globals) 192 | { 193 | geoip_globals->custom_directory = NULL; 194 | geoip_globals->set_runtime_custom_directory = 0; 195 | } 196 | /* }}} */ 197 | 198 | /* {{{ PHP_MINIT_FUNCTION 199 | */ 200 | PHP_MINIT_FUNCTION(geoip) 201 | { 202 | ZEND_INIT_MODULE_GLOBALS(geoip, php_geoip_init_globals, NULL); 203 | REGISTER_INI_ENTRIES(); 204 | 205 | /* @TODO: Do something for custom_directory before initialization here */ 206 | 207 | #ifdef HAVE_CUSTOM_DIRECTORY 208 | GeoIP_setup_custom_directory(GEOIP_G(custom_directory)); 209 | #endif 210 | /* This will initialize file structure */ 211 | GeoIP_db_avail(GEOIP_COUNTRY_EDITION); 212 | 213 | /* For database type constants */ 214 | REGISTER_LONG_CONSTANT("GEOIP_COUNTRY_EDITION", GEOIP_COUNTRY_EDITION, CONST_CS | CONST_PERSISTENT); 215 | REGISTER_LONG_CONSTANT("GEOIP_REGION_EDITION_REV0", GEOIP_REGION_EDITION_REV0, CONST_CS | CONST_PERSISTENT); 216 | REGISTER_LONG_CONSTANT("GEOIP_CITY_EDITION_REV0", GEOIP_CITY_EDITION_REV0, CONST_CS | CONST_PERSISTENT); 217 | REGISTER_LONG_CONSTANT("GEOIP_ORG_EDITION", GEOIP_ORG_EDITION, CONST_CS | CONST_PERSISTENT); 218 | REGISTER_LONG_CONSTANT("GEOIP_ISP_EDITION", GEOIP_ISP_EDITION, CONST_CS | CONST_PERSISTENT); 219 | REGISTER_LONG_CONSTANT("GEOIP_CITY_EDITION_REV1", GEOIP_CITY_EDITION_REV1, CONST_CS | CONST_PERSISTENT); 220 | REGISTER_LONG_CONSTANT("GEOIP_REGION_EDITION_REV1", GEOIP_REGION_EDITION_REV1, CONST_CS | CONST_PERSISTENT); 221 | REGISTER_LONG_CONSTANT("GEOIP_PROXY_EDITION", GEOIP_PROXY_EDITION, CONST_CS | CONST_PERSISTENT); 222 | REGISTER_LONG_CONSTANT("GEOIP_ASNUM_EDITION", GEOIP_ASNUM_EDITION, CONST_CS | CONST_PERSISTENT); 223 | REGISTER_LONG_CONSTANT("GEOIP_NETSPEED_EDITION", GEOIP_NETSPEED_EDITION, CONST_CS | CONST_PERSISTENT); 224 | REGISTER_LONG_CONSTANT("GEOIP_DOMAIN_EDITION", GEOIP_DOMAIN_EDITION, CONST_CS | CONST_PERSISTENT); 225 | #if LIBGEOIP_VERSION >= 1004008 226 | REGISTER_LONG_CONSTANT("GEOIP_NETSPEED_EDITION_REV1",GEOIP_NETSPEED_EDITION_REV1,CONST_CS | CONST_PERSISTENT); 227 | #endif 228 | 229 | /* For netspeed constants */ 230 | REGISTER_LONG_CONSTANT("GEOIP_UNKNOWN_SPEED", GEOIP_UNKNOWN_SPEED, CONST_CS | CONST_PERSISTENT); 231 | REGISTER_LONG_CONSTANT("GEOIP_DIALUP_SPEED", GEOIP_DIALUP_SPEED, CONST_CS | CONST_PERSISTENT); 232 | REGISTER_LONG_CONSTANT("GEOIP_CABLEDSL_SPEED", GEOIP_CABLEDSL_SPEED, CONST_CS | CONST_PERSISTENT); 233 | REGISTER_LONG_CONSTANT("GEOIP_CORPORATE_SPEED", GEOIP_CORPORATE_SPEED, CONST_CS | CONST_PERSISTENT); 234 | 235 | return SUCCESS; 236 | } 237 | /* }}} */ 238 | 239 | /* {{{ PHP_MSHUTDOWN_FUNCTION 240 | */ 241 | PHP_MSHUTDOWN_FUNCTION(geoip) 242 | { 243 | return SUCCESS; 244 | } 245 | /* }}} */ 246 | 247 | 248 | /* {{{ PHP_RINIT_FUNCTION 249 | */ 250 | PHP_RINIT_FUNCTION(geoip) 251 | { 252 | return SUCCESS; 253 | } 254 | /* }}} */ 255 | 256 | 257 | /* {{{ PHP_RSHUTDOWN_FUNCTION 258 | */ 259 | PHP_RSHUTDOWN_FUNCTION(geoip) 260 | { 261 | #ifdef HAVE_CUSTOM_DIRECTORY 262 | /* If we have a custom directory (and have support from */ 263 | /* libgeoip, we reset the extension to default directory) */ 264 | if (GEOIP_G(set_runtime_custom_directory)) { 265 | geoip_change_custom_directory(GEOIP_G(custom_directory)); 266 | GEOIP_G(set_runtime_custom_directory) = 0; 267 | } 268 | #endif 269 | 270 | return SUCCESS; 271 | } 272 | /* }}} */ 273 | 274 | /* {{{ PHP_MINFO_FUNCTION 275 | */ 276 | PHP_MINFO_FUNCTION(geoip) 277 | { 278 | char buf[32]; 279 | 280 | php_info_print_table_start(); 281 | php_info_print_table_header(2, "geoip support", "enabled"); 282 | php_info_print_table_row(2, "geoip extension version", PHP_GEOIP_VERSION); 283 | snprintf(buf, sizeof(buf), "%d", LIBGEOIP_VERSION); 284 | php_info_print_table_row(2, "geoip library version", buf); 285 | php_info_print_table_end(); 286 | DISPLAY_INI_ENTRIES(); 287 | } 288 | /* }}} */ 289 | 290 | /* {{{ proto boolean geoip_db_avail( [ int database ] ) */ 291 | PHP_FUNCTION(geoip_db_avail) 292 | { 293 | zend_long edition; 294 | 295 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &edition) == FAILURE) { 296 | return; 297 | } 298 | 299 | if (edition < 0 || edition >= NUM_DB_TYPES) 300 | { 301 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 302 | return; 303 | } 304 | 305 | RETURN_BOOL(GeoIP_db_avail(edition)); 306 | } 307 | /* }}} */ 308 | 309 | /* {{{ proto string geoip_db_filename( [ int database ] ) */ 310 | PHP_FUNCTION(geoip_db_filename) 311 | { 312 | zend_long edition; 313 | 314 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &edition) == FAILURE) { 315 | return; 316 | } 317 | 318 | if (edition < 0 || edition >= NUM_DB_TYPES) 319 | { 320 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 321 | return; 322 | } 323 | 324 | if (NULL != GeoIPDBFileName[edition]) 325 | #if PHP_MAJOR_VERSION >= 7 326 | RETURN_STRING(GeoIPDBFileName[edition]); 327 | #else 328 | RETURN_STRING(GeoIPDBFileName[edition], 1); 329 | #endif 330 | } 331 | /* }}} */ 332 | 333 | /* {{{ proto array geoip_db_get_all_info( ) */ 334 | PHP_FUNCTION(geoip_db_get_all_info) 335 | { 336 | int i; 337 | 338 | array_init(return_value); 339 | 340 | for (i=0; i < NUM_DB_TYPES; i++) 341 | { 342 | if (NULL != GeoIPDBDescription[i]) 343 | { 344 | #if PHP_MAJOR_VERSION >= 7 345 | zval real_row; 346 | zval *row = &real_row; 347 | 348 | array_init(row); 349 | #else 350 | zval *row; 351 | ALLOC_INIT_ZVAL(row); 352 | array_init(row); 353 | #endif 354 | 355 | add_assoc_bool(row, "available", GeoIP_db_avail(i)); 356 | if (GeoIPDBDescription[i]) { 357 | #if PHP_MAJOR_VERSION >= 7 358 | add_assoc_string(row, "description", (char *)GeoIPDBDescription[i]); 359 | #else 360 | add_assoc_string(row, "description", (char *)GeoIPDBDescription[i], 1); 361 | #endif 362 | } 363 | if (GeoIPDBFileName[i]) { 364 | #if PHP_MAJOR_VERSION >= 7 365 | add_assoc_string(row, "filename", GeoIPDBFileName[i]); 366 | #else 367 | add_assoc_string(row, "filename", GeoIPDBFileName[i], 1); 368 | #endif 369 | } 370 | 371 | add_index_zval(return_value, i, row); 372 | } 373 | } 374 | } 375 | /* }}} */ 376 | 377 | /* {{{ proto string geoip_database_info( [ int database ] ) 378 | Returns GeoIP Database information */ 379 | PHP_FUNCTION(geoip_database_info) 380 | { 381 | GeoIP * gi; 382 | char * db_info; 383 | zend_long edition = GEOIP_COUNTRY_EDITION; 384 | 385 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &edition) == FAILURE) { 386 | return; 387 | } 388 | 389 | if (edition < 0 || edition >= NUM_DB_TYPES) 390 | { 391 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Database type given is out of bound."); 392 | return; 393 | } 394 | 395 | if (GeoIP_db_avail(edition)) { 396 | gi = GeoIP_open_type(edition, GEOIP_STANDARD); 397 | } else { 398 | if (NULL != GeoIPDBFileName[edition]) 399 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[edition]); 400 | else 401 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available."); 402 | return; 403 | } 404 | 405 | db_info = GeoIP_database_info(gi); 406 | GeoIP_delete(gi); 407 | 408 | #if PHP_MAJOR_VERSION >= 7 409 | RETVAL_STRING(db_info); 410 | #else 411 | RETVAL_STRING(db_info, 1); 412 | #endif 413 | free(db_info); 414 | } 415 | /* }}} */ 416 | 417 | /* {{{ */ 418 | #if PHP_MAJOR_VERSION >= 7 419 | #define GEOIPDEF(php_func, c_func, db_type) \ 420 | PHP_FUNCTION(php_func) \ 421 | { \ 422 | GeoIP * gi; \ 423 | char * hostname = NULL; \ 424 | const char * return_code; \ 425 | size_t arglen; \ 426 | \ 427 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { \ 428 | return; \ 429 | } \ 430 | \ 431 | if (GeoIP_db_avail(db_type)) { \ 432 | gi = GeoIP_open_type(db_type, GEOIP_STANDARD); \ 433 | } else { \ 434 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[db_type]); \ 435 | return; \ 436 | } \ 437 | \ 438 | return_code = c_func(gi, hostname); \ 439 | GeoIP_delete(gi); \ 440 | if (return_code == NULL) { \ 441 | RETURN_FALSE; \ 442 | } \ 443 | RETURN_STRING((char*)return_code); \ 444 | \ 445 | } 446 | #else 447 | #define GEOIPDEF(php_func, c_func, db_type) \ 448 | PHP_FUNCTION(php_func) \ 449 | { \ 450 | GeoIP * gi; \ 451 | char * hostname = NULL; \ 452 | const char * return_code; \ 453 | int arglen; \ 454 | \ 455 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { \ 456 | return; \ 457 | } \ 458 | \ 459 | if (GeoIP_db_avail(db_type)) { \ 460 | gi = GeoIP_open_type(db_type, GEOIP_STANDARD); \ 461 | } else { \ 462 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[db_type]); \ 463 | return; \ 464 | } \ 465 | \ 466 | return_code = c_func(gi, hostname); \ 467 | GeoIP_delete(gi); \ 468 | if (return_code == NULL) { \ 469 | RETURN_FALSE; \ 470 | } \ 471 | RETURN_STRING((char*)return_code, 1); \ 472 | \ 473 | } 474 | #endif 475 | #include "geoip.def" 476 | #undef GEOIPDEF 477 | /* }}} */ 478 | 479 | /* {{{ proto string geoip_continent_code_by_name( string hostname ) 480 | Returns the Continent name found in the GeoIP Database */ 481 | PHP_FUNCTION(geoip_continent_code_by_name) 482 | { 483 | GeoIP * gi; 484 | char * hostname = NULL; 485 | int id; 486 | #if PHP_MAJOR_VERSION >= 7 487 | size_t arglen; 488 | #else 489 | int arglen; 490 | #endif 491 | 492 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 493 | return; 494 | } 495 | 496 | if (GeoIP_db_avail(GEOIP_COUNTRY_EDITION)) { 497 | gi = GeoIP_open_type(GEOIP_COUNTRY_EDITION, GEOIP_STANDARD); 498 | } else { 499 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_COUNTRY_EDITION]); 500 | return; 501 | } 502 | 503 | id = GeoIP_id_by_name(gi, hostname); 504 | GeoIP_delete(gi); 505 | if (id == 0) { 506 | RETURN_FALSE; 507 | } 508 | #if PHP_MAJOR_VERSION >= 7 509 | RETURN_STRING((char *)GeoIP_country_continent[id]); 510 | #else 511 | RETURN_STRING((char *)GeoIP_country_continent[id], 1); 512 | #endif 513 | } 514 | /* }}} */ 515 | 516 | /* {{{ proto string geoip_org_by_name( string hostname ) 517 | Returns the Organization Name found in the GeoIP Database */ 518 | PHP_FUNCTION(geoip_org_by_name) 519 | { 520 | GeoIP * gi; 521 | char * hostname = NULL; 522 | char * org; 523 | #if PHP_MAJOR_VERSION >= 7 524 | size_t arglen; 525 | #else 526 | int arglen; 527 | #endif 528 | 529 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 530 | return; 531 | } 532 | 533 | if (GeoIP_db_avail(GEOIP_ORG_EDITION)) { 534 | gi = GeoIP_open_type(GEOIP_ORG_EDITION, GEOIP_STANDARD); 535 | } else { 536 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ORG_EDITION]); 537 | return; 538 | } 539 | 540 | org = GeoIP_org_by_name(gi, hostname); 541 | GeoIP_delete(gi); 542 | if (org == NULL) { 543 | RETURN_FALSE; 544 | } 545 | #if PHP_MAJOR_VERSION >= 7 546 | RETVAL_STRING(org); 547 | #else 548 | RETVAL_STRING(org, 1); 549 | #endif 550 | free(org); 551 | } 552 | /* }}} */ 553 | 554 | /* {{{ proto string geoip_asnum_by_name( string hostname ) 555 | Returns the Domain Name found in the GeoIP Database */ 556 | PHP_FUNCTION(geoip_asnum_by_name) 557 | { 558 | GeoIP * gi; 559 | char * hostname = NULL; 560 | char * org; 561 | #if PHP_MAJOR_VERSION >= 7 562 | size_t arglen; 563 | #else 564 | int arglen; 565 | #endif 566 | 567 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 568 | return; 569 | } 570 | 571 | if (GeoIP_db_avail(GEOIP_ASNUM_EDITION)) { 572 | gi = GeoIP_open_type(GEOIP_ASNUM_EDITION, GEOIP_STANDARD); 573 | } else { 574 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ASNUM_EDITION]); 575 | return; 576 | } 577 | 578 | org = GeoIP_name_by_name(gi, hostname); 579 | GeoIP_delete(gi); 580 | if (org == NULL) { 581 | RETURN_FALSE; 582 | } 583 | #if PHP_MAJOR_VERSION >= 7 584 | RETVAL_STRING(org); 585 | #else 586 | RETVAL_STRING(org, 1); 587 | #endif 588 | free(org); 589 | } 590 | /* }}} */ 591 | 592 | /* {{{ proto string geoip_domain_by_name( string hostname ) 593 | Returns the Domain Name found in the GeoIP Database */ 594 | PHP_FUNCTION(geoip_domain_by_name) 595 | { 596 | GeoIP * gi; 597 | char * hostname = NULL; 598 | char * org; 599 | #if PHP_MAJOR_VERSION >= 7 600 | size_t arglen; 601 | #else 602 | int arglen; 603 | #endif 604 | 605 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 606 | return; 607 | } 608 | 609 | if (GeoIP_db_avail(GEOIP_DOMAIN_EDITION)) { 610 | gi = GeoIP_open_type(GEOIP_DOMAIN_EDITION, GEOIP_STANDARD); 611 | } else { 612 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_DOMAIN_EDITION]); 613 | return; 614 | } 615 | 616 | org = GeoIP_name_by_name(gi, hostname); 617 | GeoIP_delete(gi); 618 | if (org == NULL) { 619 | RETURN_FALSE; 620 | } 621 | #if PHP_MAJOR_VERSION >= 7 622 | RETVAL_STRING(org); 623 | #else 624 | RETVAL_STRING(org, 1); 625 | #endif 626 | free(org); 627 | } 628 | /* }}} */ 629 | 630 | #if LIBGEOIP_VERSION >= 1004008 631 | /* {{{ proto string geoip_netspeedcell_by_name( string hostname ) 632 | Returns the Net Speed found in the GeoIP Database */ 633 | PHP_FUNCTION(geoip_netspeedcell_by_name) 634 | { 635 | GeoIP * gi; 636 | char * hostname = NULL; 637 | char * org; 638 | #if PHP_MAJOR_VERSION >= 7 639 | size_t arglen; 640 | #else 641 | int arglen; 642 | #endif 643 | 644 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 645 | return; 646 | } 647 | 648 | if (GeoIP_db_avail(GEOIP_NETSPEED_EDITION_REV1)) { 649 | gi = GeoIP_open_type(GEOIP_NETSPEED_EDITION_REV1, GEOIP_STANDARD); 650 | } else { 651 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_NETSPEED_EDITION_REV1]); 652 | return; 653 | } 654 | 655 | org = GeoIP_name_by_name(gi, hostname); 656 | GeoIP_delete(gi); 657 | if (org == NULL) { 658 | RETURN_FALSE; 659 | } 660 | #if PHP_MAJOR_VERSION >= 7 661 | RETVAL_STRING(org); 662 | #else 663 | RETVAL_STRING(org, 1); 664 | #endif 665 | free(org); 666 | } 667 | /* }}} */ 668 | #endif 669 | 670 | /* {{{ proto array geoip_record_by_name( string hostname ) 671 | Returns the detailed City information found in the GeoIP Database */ 672 | PHP_FUNCTION(geoip_record_by_name) 673 | { 674 | GeoIP * gi; 675 | char * hostname = NULL; 676 | #if PHP_MAJOR_VERSION >= 7 677 | size_t arglen; 678 | #else 679 | int arglen; 680 | #endif 681 | GeoIPRecord * gir; 682 | 683 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 684 | return; 685 | } 686 | 687 | if (GeoIP_db_avail(GEOIP_CITY_EDITION_REV1) || GeoIP_db_avail(GEOIP_CITY_EDITION_REV0)) { 688 | if (GeoIP_db_avail(GEOIP_CITY_EDITION_REV1)) { 689 | gi = GeoIP_open_type(GEOIP_CITY_EDITION_REV1, GEOIP_STANDARD); 690 | } else { 691 | gi = GeoIP_open_type(GEOIP_CITY_EDITION_REV0, GEOIP_STANDARD); 692 | } 693 | } else { 694 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_CITY_EDITION_REV0]); 695 | return; 696 | } 697 | gir = GeoIP_record_by_name(gi, hostname); 698 | 699 | GeoIP_delete(gi); 700 | 701 | if (NULL == gir) { 702 | RETURN_FALSE; 703 | } 704 | 705 | array_init(return_value); 706 | #if PHP_MAJOR_VERSION >= 7 707 | # if LIBGEOIP_VERSION >= 1004003 708 | add_assoc_string(return_value, "continent_code", (gir->continent_code == NULL) ? "" : gir->continent_code); 709 | # endif 710 | add_assoc_string(return_value, "country_code", (gir->country_code == NULL) ? "" : gir->country_code); 711 | add_assoc_string(return_value, "country_code3", (gir->country_code3 == NULL) ? "" : gir->country_code3); 712 | add_assoc_string(return_value, "country_name", (gir->country_name == NULL) ? "" : gir->country_name); 713 | add_assoc_string(return_value, "region", (gir->region == NULL) ? "" : gir->region); 714 | add_assoc_string(return_value, "city", (gir->city == NULL) ? "" : gir->city); 715 | add_assoc_string(return_value, "postal_code", (gir->postal_code == NULL) ? "" : gir->postal_code); 716 | #else 717 | # if LIBGEOIP_VERSION >= 1004003 718 | add_assoc_string(return_value, "continent_code", (gir->continent_code == NULL) ? "" : gir->continent_code, 1); 719 | # endif 720 | add_assoc_string(return_value, "country_code", (gir->country_code == NULL) ? "" : gir->country_code, 1); 721 | add_assoc_string(return_value, "country_code3", (gir->country_code3 == NULL) ? "" : gir->country_code3, 1); 722 | add_assoc_string(return_value, "country_name", (gir->country_name == NULL) ? "" : gir->country_name, 1); 723 | add_assoc_string(return_value, "region", (gir->region == NULL) ? "" : gir->region, 1); 724 | add_assoc_string(return_value, "city", (gir->city == NULL) ? "" : gir->city, 1); 725 | add_assoc_string(return_value, "postal_code", (gir->postal_code == NULL) ? "" : gir->postal_code, 1); 726 | #endif 727 | add_assoc_double(return_value, "latitude", gir->latitude); 728 | add_assoc_double(return_value, "longitude", gir->longitude); 729 | #if LIBGEOIP_VERSION >= 1004005 730 | add_assoc_long(return_value, "dma_code", gir->metro_code); 731 | #else 732 | add_assoc_long(return_value, "dma_code", gir->dma_code); 733 | #endif 734 | add_assoc_long(return_value, "area_code", gir->area_code); 735 | 736 | GeoIPRecord_delete(gir); 737 | } 738 | /* }}} */ 739 | 740 | /* {{{ proto integer geoip_id_by_name( string hostname ) 741 | Returns the Net Speed found in the GeoIP Database */ 742 | PHP_FUNCTION(geoip_id_by_name) 743 | { 744 | GeoIP * gi; 745 | char * hostname = NULL; 746 | #if PHP_MAJOR_VERSION >= 7 747 | size_t arglen; 748 | #else 749 | int arglen; 750 | #endif 751 | int netspeed; 752 | 753 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 754 | return; 755 | } 756 | 757 | if (GeoIP_db_avail(GEOIP_NETSPEED_EDITION)) { 758 | gi = GeoIP_open_type(GEOIP_NETSPEED_EDITION, GEOIP_STANDARD); 759 | } else { 760 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_NETSPEED_EDITION]); 761 | return; 762 | } 763 | 764 | netspeed = GeoIP_id_by_name(gi, hostname); 765 | GeoIP_delete(gi); 766 | RETURN_LONG(netspeed); 767 | } 768 | /* }}} */ 769 | 770 | /* {{{ proto array geoip_region_by_name( string hostname ) 771 | Returns the Country Code and region found in the GeoIP Database */ 772 | PHP_FUNCTION(geoip_region_by_name) 773 | { 774 | GeoIP * gi; 775 | char * hostname = NULL; 776 | #if PHP_MAJOR_VERSION >= 7 777 | size_t arglen; 778 | #else 779 | int arglen; 780 | #endif 781 | GeoIPRegion * region; 782 | 783 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 784 | return; 785 | } 786 | 787 | if (GeoIP_db_avail(GEOIP_REGION_EDITION_REV0) || GeoIP_db_avail(GEOIP_REGION_EDITION_REV1)) { 788 | if (GeoIP_db_avail(GEOIP_REGION_EDITION_REV1)) { 789 | gi = GeoIP_open_type(GEOIP_REGION_EDITION_REV1, GEOIP_STANDARD); 790 | } else { 791 | gi = GeoIP_open_type(GEOIP_REGION_EDITION_REV0, GEOIP_STANDARD); 792 | } 793 | } else { 794 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_REGION_EDITION_REV0]); 795 | return; 796 | } 797 | 798 | region = GeoIP_region_by_name(gi, hostname); 799 | GeoIP_delete(gi); 800 | 801 | if (NULL == region) { 802 | RETURN_FALSE; 803 | } 804 | 805 | array_init(return_value); 806 | #if PHP_MAJOR_VERSION >= 7 807 | add_assoc_string(return_value, "country_code", region->country_code); 808 | add_assoc_string(return_value, "region", region->region); 809 | #else 810 | add_assoc_string(return_value, "country_code", region->country_code, 1); 811 | add_assoc_string(return_value, "region", region->region, 1); 812 | #endif 813 | 814 | GeoIPRegion_delete(region); 815 | } 816 | /* }}} */ 817 | 818 | /* {{{ proto string geoip_isp_by_name( string hostname ) 819 | Returns the ISP Name found in the GeoIP Database */ 820 | PHP_FUNCTION(geoip_isp_by_name) 821 | { 822 | GeoIP * gi; 823 | char * hostname = NULL; 824 | char * isp; 825 | #if PHP_MAJOR_VERSION >= 7 826 | size_t arglen; 827 | #else 828 | int arglen; 829 | #endif 830 | 831 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hostname, &arglen) == FAILURE) { 832 | return; 833 | } 834 | 835 | if (GeoIP_db_avail(GEOIP_ISP_EDITION)) { 836 | gi = GeoIP_open_type(GEOIP_ISP_EDITION, GEOIP_STANDARD); 837 | } else { 838 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Required database not available at %s.", GeoIPDBFileName[GEOIP_ISP_EDITION]); 839 | return; 840 | } 841 | 842 | isp = GeoIP_name_by_name(gi, hostname); 843 | GeoIP_delete(gi); 844 | if (isp == NULL) { 845 | RETURN_FALSE; 846 | } 847 | #if PHP_MAJOR_VERSION >= 7 848 | RETVAL_STRING(isp); 849 | #else 850 | RETVAL_STRING(isp, 1); 851 | #endif 852 | free(isp); 853 | } 854 | 855 | #if LIBGEOIP_VERSION >= 1004001 856 | /* {{{ proto string geoip_region_name_by_code( string country_code, string region_code ) 857 | Returns the region name for some country code and region code combo */ 858 | PHP_FUNCTION(geoip_region_name_by_code) 859 | { 860 | char * country_code = NULL; 861 | char * region_code = NULL; 862 | const char * region_name; 863 | #if PHP_MAJOR_VERSION >= 7 864 | size_t countrylen, regionlen; 865 | #else 866 | int countrylen, regionlen; 867 | #endif 868 | 869 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &country_code, &countrylen, ®ion_code, ®ionlen) == FAILURE) { 870 | return; 871 | } 872 | 873 | if (!countrylen || !regionlen) { 874 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "You need to specify the country and region codes."); 875 | RETURN_FALSE; 876 | } 877 | 878 | region_name = GeoIP_region_name_by_code(country_code, region_code); 879 | if (region_name == NULL) { 880 | RETURN_FALSE; 881 | } 882 | #if PHP_MAJOR_VERSION >= 7 883 | RETURN_STRING((char*)region_name); 884 | #else 885 | RETURN_STRING((char*)region_name, 1); 886 | #endif 887 | } 888 | /* }}} */ 889 | #endif 890 | 891 | #if LIBGEOIP_VERSION >= 1004001 892 | /* {{{ proto string geoip_time_zone_by_country_and_region( string country, string region ) 893 | Returns the time zone for some country code and region code combo */ 894 | PHP_FUNCTION(geoip_time_zone_by_country_and_region) 895 | { 896 | char * country = NULL; 897 | char * region = NULL; 898 | const char * timezone; 899 | #if PHP_MAJOR_VERSION >= 7 900 | size_t countrylen, arg2len; 901 | #else 902 | int countrylen, arg2len; 903 | #endif 904 | 905 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &country, &countrylen, ®ion, &arg2len) == FAILURE) { 906 | return; 907 | } 908 | 909 | if (!countrylen) { 910 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "You need to specify at least the country code."); 911 | RETURN_FALSE; 912 | } 913 | 914 | timezone = GeoIP_time_zone_by_country_and_region(country, region); 915 | if (timezone == NULL) { 916 | RETURN_FALSE; 917 | } 918 | #if PHP_MAJOR_VERSION >= 7 919 | RETURN_STRING((char*)timezone); 920 | #else 921 | RETURN_STRING((char*)timezone, 1); 922 | #endif 923 | } 924 | /* }}} */ 925 | #endif 926 | 927 | #ifdef HAVE_CUSTOM_DIRECTORY 928 | /* {{{ proto void geoip_setup_custom_directory( string directory ) 929 | Sets the custom directory for GeoIP databases */ 930 | PHP_FUNCTION(geoip_setup_custom_directory) 931 | { 932 | char * dir = NULL; 933 | #if PHP_MAJOR_VERSION >= 7 934 | size_t dirlen; 935 | #else 936 | int dirlen; 937 | #endif 938 | 939 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &dir, &dirlen) == FAILURE) { 940 | return; 941 | } 942 | 943 | GEOIP_G(set_runtime_custom_directory) = 1; 944 | geoip_change_custom_directory(dir); 945 | } 946 | /* }}} */ 947 | #endif 948 | 949 | 950 | /* 951 | * Local variables: 952 | * tab-width: 4 953 | * c-basic-offset: 4 954 | * End: 955 | * vim600: noet sw=4 ts=4 fdm=marker 956 | * vim<600: noet sw=4 ts=4 957 | */ 958 | --------------------------------------------------------------------------------