From 7e4801df22a4eb23abd8909c42d45676eb2fceeb Mon Sep 17 00:00:00 2001 From: dongyado Date: Thu, 16 Jun 2016 16:28:50 +0800 Subject: [PATCH] ip2region extension for php7 --- .../php_extension/php7/ip2region/.gitignore | 37 ++ binding/php_extension/php7/ip2region/CREDITS | 2 + .../php_extension/php7/ip2region/README.md | 29 ++ .../php_extension/php7/ip2region/config.m4 | 63 ++++ .../php_extension/php7/ip2region/config.w32 | 12 + .../php_extension/php7/ip2region/ip2region.c | 315 ++++++++++++++++++ .../php7/ip2region/ip2region.php | 67 ++++ .../php7/ip2region/lib/README.md | 4 + .../php7/ip2region/php_ip2region.h | 78 +++++ .../php7/ip2region/tests/001.phpt | 22 ++ 10 files changed, 629 insertions(+) create mode 100644 binding/php_extension/php7/ip2region/.gitignore create mode 100644 binding/php_extension/php7/ip2region/CREDITS create mode 100644 binding/php_extension/php7/ip2region/README.md create mode 100644 binding/php_extension/php7/ip2region/config.m4 create mode 100644 binding/php_extension/php7/ip2region/config.w32 create mode 100644 binding/php_extension/php7/ip2region/ip2region.c create mode 100644 binding/php_extension/php7/ip2region/ip2region.php create mode 100644 binding/php_extension/php7/ip2region/lib/README.md create mode 100644 binding/php_extension/php7/ip2region/php_ip2region.h create mode 100644 binding/php_extension/php7/ip2region/tests/001.phpt diff --git a/binding/php_extension/php7/ip2region/.gitignore b/binding/php_extension/php7/ip2region/.gitignore new file mode 100644 index 0000000..4a8300f --- /dev/null +++ b/binding/php_extension/php7/ip2region/.gitignore @@ -0,0 +1,37 @@ +.deps +*.lo +*.la +*.swp +*~ +.libs +acinclude.m4 +aclocal.m4 +autom4te.cache +build +config.guess +config.h +config.h.in +config.log +config.nice +config.status +config.sub +configure +configure.in +include +install-sh +libtool +ltmain.sh +Makefile +Makefile.fragments +Makefile.global +Makefile.objects +missing +mkinstalldirs +modules +run-tests.php +tests/*/*.diff +tests/*/*.out +tests/*/*.php +tests/*/*.exp +tests/*/*.log +tests/*/*.sh diff --git a/binding/php_extension/php7/ip2region/CREDITS b/binding/php_extension/php7/ip2region/CREDITS new file mode 100644 index 0000000..8c85c6f --- /dev/null +++ b/binding/php_extension/php7/ip2region/CREDITS @@ -0,0 +1,2 @@ +ip2region + diff --git a/binding/php_extension/php7/ip2region/README.md b/binding/php_extension/php7/ip2region/README.md new file mode 100644 index 0000000..f1a1583 --- /dev/null +++ b/binding/php_extension/php7/ip2region/README.md @@ -0,0 +1,29 @@ +# ip2region 的PHP拓展(php7版本) + +### 安装步骤 +* git clone https://github.com/lionsoul2016/ip2region.git +* cd ip2region +* cp binding/php_extension/php5/ip2region 到 php source code 的ext目录下 +* cp binding/c/下面所有的文件到 php source code 的ext/ip2region/lib 目录下 +* 在ext/ip2region下,运行 + + phpize + ./configure + make && sudo make install + +* 配置ip2region.ini 指定db_file路径,(cli/fpm) + + extension=ip2region.so + ip2region.db_file=/path/to/ip2region.db + +ip2region.db 在项目根目录下的data文件夹下 + +* 测试 + +在ext/ip2region/下运行 + + php ip2region.php + +### 使用 + +参考ip2region/ip2region.php diff --git a/binding/php_extension/php7/ip2region/config.m4 b/binding/php_extension/php7/ip2region/config.m4 new file mode 100644 index 0000000..2679eef --- /dev/null +++ b/binding/php_extension/php7/ip2region/config.m4 @@ -0,0 +1,63 @@ +dnl $Id$ +dnl config.m4 for extension ip2region + +dnl Comments in this file start with the string 'dnl'. +dnl Remove where necessary. This file will not work +dnl without editing. + +dnl If your extension references something external, use with: + +dnl PHP_ARG_WITH(ip2region, for ip2region support, +dnl Make sure that the comment is aligned: +dnl [ --with-ip2region Include ip2region support]) + +dnl Otherwise use enable: + +PHP_ARG_ENABLE(ip2region, whether to enable ip2region support, +Make sure that the comment is aligned: +[ --enable-ip2region Enable ip2region support]) + +if test "$PHP_IP2REGION" != "no"; then +dnl dnl Write more examples of tests here... +dnl +dnl dnl # --with-ip2region -> check with-path +dnl SEARCH_PATH="/home/slayer/code/php-5.6.7/ext/ip2region/lib " # you might want to change this +dnl SEARCH_FOR="ip2region.h" # you most likely want to change this +dnl if test -r $PHP_IP2REGION/$SEARCH_FOR; then # path given as parameter +dnl IP2REGION_DIR=$PHP_IP2REGION +dnl else # search default path list +dnl AC_MSG_CHECKING([for ip2region files in default path]) +dnl for i in $SEARCH_PATH ; do +dnl if test -r $i/$SEARCH_FOR; then +dnl IP2REGION_DIR=$i +dnl AC_MSG_RESULT(found in $i) +dnl fi +dnl done +dnl fi +dnl +dnl if test -z "$IP2REGION_DIR"; then +dnl AC_MSG_RESULT([not found]) +dnl AC_MSG_ERROR([Please reinstall the ip2region distribution]) +dnl fi +dnl +dnl dnl # --with-ip2region -> add include path +dnl PHP_ADD_INCLUDE($IP2REGION_DIR/include) +dnl +dnl dnl # --with-ip2region -> check for lib and symbol presence +dnl LIBNAME=ip2region # you may want to change this +dnl LIBSYMBOL=ip2region # you most likely want to change this +dnl +dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, +dnl [ +dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $IP2REGION_DIR/$PHP_LIBDIR, IP2REGION_SHARED_LIBADD) +dnl AC_DEFINE(HAVE_IP2REGIONLIB,1,[ ]) +dnl ],[ +dnl AC_MSG_ERROR([wrong ip2region lib version or lib not found]) +dnl ],[ +dnl -L$IP2REGION_DIR/$PHP_LIBDIR -lm +dnl ]) +dnl +dnl PHP_SUBST(IP2REGION_SHARED_LIBADD) +dnl + PHP_NEW_EXTENSION(ip2region, ip2region.c lib/ip2region.c , $ext_shared) +fi diff --git a/binding/php_extension/php7/ip2region/config.w32 b/binding/php_extension/php7/ip2region/config.w32 new file mode 100644 index 0000000..e09686c --- /dev/null +++ b/binding/php_extension/php7/ip2region/config.w32 @@ -0,0 +1,12 @@ +// $Id$ +// +// If your extension references something external, use ARG_WITH +// ARG_WITH("ip2region", "for ip2region support", "no"); + +// Otherwise, use ARG_ENABLE +// ARG_ENABLE("ip2region", "enable ip2region support", "no"); + +if (PHP_IP2REGION != "no") { + EXTENSION("ip2region", "ip2region.c"); +} + diff --git a/binding/php_extension/php7/ip2region/ip2region.c b/binding/php_extension/php7/ip2region/ip2region.c new file mode 100644 index 0000000..60d389d --- /dev/null +++ b/binding/php_extension/php7/ip2region/ip2region.c @@ -0,0 +1,315 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: dongyado | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "ext/standard/info.h" +#include "lib/ip2region.h" +#include "php_ip2region.h" +#include + +ZEND_DECLARE_MODULE_GLOBALS(ip2region) + +/* True global resources - no need for thread safety here */ +static int le_ip2region; +static ip2region_t g_resource_ptr; +static ip2region_entry g_resource; + +// class +static zend_class_entry *ip2region_class_entry_ptr; + + +//static double getTime() +//{ +// struct timeval tv; +// struct timezone tz; +// gettimeofday(&tv, &tz); +// +// return (tv.tv_sec * 1000 + ((double)tv.tv_usec)/1000); +//} + + +void search( + ip2region_t g_resouce_ptr, + uint_t (*func_ptr) (ip2region_t, uint_t, datablock_t), + long ip, + zval ** return_value, + datablock_t _block) +{ + int res = 0; + + if (g_resource_ptr != NULL){ + res = (*func_ptr)(g_resouce_ptr, (uint_t) ip, _block); + } + + array_init( *return_value ); + + if ( res == 1 ) + { + add_assoc_long( *return_value, "cityId", (*_block).city_id); + //add_assoc_string( *return_value, "region", (*_block).region, 1); + // for phpng + add_assoc_string( *return_value, "region", (*_block).region); + } else { + add_assoc_long( *return_value, "cityId", 0); + //add_assoc_string( *return_value, "region", "[Error] Search Failed! Please check the path of ip2region db file.", 1); + // for phpng + add_assoc_string( *return_value, "region", "[Error] Search Failed! Please check the path of ip2region db file."); + } +} + + +/* {{{ php_ip2region_init_globals + */ +static void php_ip2region_init_globals(zend_ip2region_globals *ip2region_globals) +{ + ip2region_globals->db_file = NULL; +} +/* }}} */ + + +/* {{{ PHP_INI + */ +PHP_INI_BEGIN() + STD_PHP_INI_ENTRY("ip2region.db_file", NULL, PHP_INI_ALL, OnUpdateString, db_file, zend_ip2region_globals, ip2region_globals) +PHP_INI_END() +/* }}} */ + + +/* {{{ + * btree search string + * */ +PHP_METHOD(ip2region_class_entry_ptr, btreeSearchString) +{ + char *ip = NULL; + size_t arg_len; + datablock_entry _block; + uint_t (*func_ptr) (ip2region_t, uint_t, datablock_t); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ip, &arg_len) == FAILURE) { + return; + } + + func_ptr = ip2region_btree_search; + + search(g_resource_ptr, func_ptr, ip2long(ip), &return_value, &_block); +} +/* }}} */ + + + +/* {{{ + * btree search + * */ +PHP_METHOD(ip2region_class_entry_ptr, btreeSearch) +{ + long ip; + datablock_entry _block; + uint_t (*func_ptr) (ip2region_t, uint_t, datablock_t); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ip) == FAILURE) { + return; + } + + func_ptr = ip2region_btree_search; + + search(g_resource_ptr, func_ptr, ip, &return_value, &_block); +} +/* }}} */ + + +/* {{{ + * binary search string + * */ +PHP_METHOD(ip2region_class_entry_ptr, binarySearchString) +{ + char *ip = NULL; + //int arg_len; + // for phpng + size_t arg_len; + datablock_entry _block; + uint_t (*func_ptr) (ip2region_t, uint_t, datablock_t); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ip, &arg_len) == FAILURE) { + return; + } + + func_ptr = ip2region_binary_search; + + search(g_resource_ptr, func_ptr, ip2long(ip), &return_value, &_block); +} +/* }}} */ + + +/* {{{ + * binary search + * */ +PHP_METHOD(ip2region_class_entry_ptr, binarySearch) +{ + long ip; + datablock_entry _block; + uint_t (*func_ptr) (ip2region_t, uint_t, datablock_t); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ip) == FAILURE) { + return; + } + + func_ptr = ip2region_binary_search; + search(g_resource_ptr, func_ptr, ip, &return_value, &_block); +} +/* }}} */ + + + + +/* {{{ PHP_MSHUTDOWN_FUNCTION + */ +PHP_MSHUTDOWN_FUNCTION(ip2region) +{ + UNREGISTER_INI_ENTRIES(); + ip2region_destroy(&g_resource); + return SUCCESS; +} +/* }}} */ + + +/* Remove if there's nothing to do at request start */ +/* {{{ PHP_RINIT_FUNCTION + */ +PHP_RINIT_FUNCTION(ip2region) +{ + return SUCCESS; +} +/* }}} */ + + +/* Remove if there's nothing to do at request end */ +/* {{{ PHP_RSHUTDOWN_FUNCTION + */ +PHP_RSHUTDOWN_FUNCTION(ip2region) +{ + return SUCCESS; +} +/* }}} */ + + +/* {{{ PHP_MINFO_FUNCTION + */ +PHP_MINFO_FUNCTION(ip2region) +{ + php_info_print_table_start(); + php_info_print_table_header(2, "ip2region support", "enabled"); + php_info_print_table_end(); + + DISPLAY_INI_ENTRIES(); +} +/* }}} */ + + +/* {{{ ip2region_class_functions[] + * + * Every user visible function must have an entry in ip2region_functions[]. + */ +const zend_function_entry ip2region_class_functions[] = { + PHP_ME( ip2region_class_entry_ptr, btreeSearchString, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME( ip2region_class_entry_ptr, binarySearchString, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC ) + PHP_ME( ip2region_class_entry_ptr, btreeSearch, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) + PHP_ME( ip2region_class_entry_ptr, binarySearch, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC ) + PHP_FE_END /* Must be the last line in ip2region_functions[] */ +}; +/* }}} */ + + +/* {{{ ip2region_functions[] + * + * Every user visible function must have an entry in ip2region_functions[]. + */ +const zend_function_entry ip2region_functions[] = { + PHP_FE_END /* Must be the last line in ip2region_functions[] */ +}; +/* }}} */ + + +/* {{{ PHP_MINIT_FUNCTION + */ +PHP_MINIT_FUNCTION(ip2region) +{ + zend_class_entry ip2region_class_entry; + + // @NOTE the line should before REGISTRE_INI_ENTRIES, + // and should not comment it when you have glocbals + ZEND_INIT_MODULE_GLOBALS(ip2region, php_ip2region_init_globals, NULL); + REGISTER_INI_ENTRIES(); + + + if (ip2region_create( &g_resource, IP2REGION_G(db_file)) == 0) + { + g_resource_ptr = NULL; + } else { + g_resource_ptr = &g_resource; + } + + + //le_ip2region = zend_register_list_destructors_ex( + // ip2region_destruction_handler, NULL, le_ip2region_name, module_number); + + // init class + INIT_CLASS_ENTRY( ip2region_class_entry, "ip2region", ip2region_class_functions); + ip2region_class_entry_ptr = + zend_register_internal_class(&ip2region_class_entry TSRMLS_CC); + + return SUCCESS; +} +/* }}} */ + + +/* {{{ ip2region_module_entry + */ +zend_module_entry ip2region_module_entry = { + STANDARD_MODULE_HEADER, + "ip2region", + ip2region_functions, + PHP_MINIT(ip2region), + PHP_MSHUTDOWN(ip2region), + PHP_RINIT(ip2region), /* Replace with NULL if there's nothing to do at request start */ + PHP_RSHUTDOWN(ip2region), /* Replace with NULL if there's nothing to do at request end */ + PHP_MINFO(ip2region), + PHP_IP2REGION_VERSION, + STANDARD_MODULE_PROPERTIES +}; +/* }}} */ + + +#ifdef COMPILE_DL_IP2REGION +ZEND_GET_MODULE(ip2region) +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/binding/php_extension/php7/ip2region/ip2region.php b/binding/php_extension/php7/ip2region/ip2region.php new file mode 100644 index 0000000..4d9faee --- /dev/null +++ b/binding/php_extension/php7/ip2region/ip2region.php @@ -0,0 +1,67 @@ +"; + +if(!extension_loaded('ip2region')) { + dl('ip2region.' . PHP_SHLIB_SUFFIX); +} + +function getTime(){ + return microtime(true) * 1000; +} + +// test class +function classBtreeSearch( $ip) +{ + + $start = getTime(); + //$data = $ip2region->btreeSearch($ip); + $data = Ip2region::btreeSearchString($ip); + $end = getTime(); + var_dump($data); + echo " btree search string - taken: ", ($end - $start), "\n"; + + $start = getTime(); + $data = Ip2region:: btreeSearch(ip2long($ip)); + $end = getTime(); + var_dump($data); + echo " btree search - taken: ", ($end - $start), "\n"; +} + +function classBinarySearch($ip) +{ + + $start = getTime(); + $data = Ip2region::binarySearchString($ip); + $end = getTime(); + var_dump($data); + echo " binary search string -taken: ", ($end - $start), "\n"; + + $start = getTime(); + $data = Ip2region::binarySearch(ip2long($ip)); + $end = getTime(); + var_dump($data); + echo " binary search - taken: ", ($end - $start), "\n"; +} + + +function test(){ + $v1 = rand(0,255); + $v2 = rand(0,255); + $v3 = rand(0,255); + $v4 = rand(0,255); + $ip = "{$v1}.{$v2}.{$v3}.{$v4}"; + classBtreeSearch( $ip ); + classBinarySearch( $ip ); +} + +while(true) +{ + test(); + break; + usleep(5000); +} +?> diff --git a/binding/php_extension/php7/ip2region/lib/README.md b/binding/php_extension/php7/ip2region/lib/README.md new file mode 100644 index 0000000..873c1d2 --- /dev/null +++ b/binding/php_extension/php7/ip2region/lib/README.md @@ -0,0 +1,4 @@ +这里放置 +https://github.com/lionsoul2016/ip2region/tree/master/binding/c + +ip2region.c and ip2region.h diff --git a/binding/php_extension/php7/ip2region/php_ip2region.h b/binding/php_extension/php7/ip2region/php_ip2region.h new file mode 100644 index 0000000..3ff128b --- /dev/null +++ b/binding/php_extension/php7/ip2region/php_ip2region.h @@ -0,0 +1,78 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2015 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: dongyado | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#ifndef PHP_IP2REGION_H +#define PHP_IP2REGION_H + +extern zend_module_entry ip2region_module_entry; +#define phpext_ip2region_ptr &ip2region_module_entry + +#define PHP_IP2REGION_VERSION "0.1.0" /* Replace with version number for your extension */ + +#ifdef PHP_WIN32 +# define PHP_IP2REGION_API __declspec(dllexport) +#elif defined(__GNUC__) && __GNUC__ >= 4 +# define PHP_IP2REGION_API __attribute__ ((visibility("default"))) +#else +# define PHP_IP2REGION_API +#endif + +#ifdef ZTS +#include "TSRM.h" +#endif + + + +ZEND_BEGIN_MODULE_GLOBALS(ip2region) + char *db_file; +ZEND_END_MODULE_GLOBALS(ip2region) + +/* In every utility function you add that needs to use variables + in php_ip2region_globals, call TSRMLS_FETCH(); after declaring other + variables used by that function, or better yet, pass in TSRMLS_CC + after the last function argument and declare your utility function + with TSRMLS_DC after the last declared argument. Always refer to + the globals in your function as IP2REGION_G(variable). You are + encouraged to rename these macros something shorter, see + examples in any other php module directory. +*/ + +#ifdef ZTS +#define IP2REGION_G(v) TSRMG(ip2region_globals_id, zend_ip2region_globals *, v) +#else +#define IP2REGION_G(v) (ip2region_globals.v) +#endif + +static void php_ip2region_init_globals(zend_ip2region_globals *); + +#define le_ip2region_name "Ip2region" + + +void search( ip2region_t, uint_t (*func_ptr) (ip2region_t, uint_t, datablock_t), long , zval **, datablock_t); + +#endif /* PHP_IP2REGION_H */ +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ diff --git a/binding/php_extension/php7/ip2region/tests/001.phpt b/binding/php_extension/php7/ip2region/tests/001.phpt new file mode 100644 index 0000000..4a271b2 --- /dev/null +++ b/binding/php_extension/php7/ip2region/tests/001.phpt @@ -0,0 +1,22 @@ +--TEST-- +Check for ip2region presence +--SKIPIF-- + +--FILE-- + +--EXPECT-- +ip2region extension is available