├── .gitignore ├── CREDITS ├── EXPERIMENTAL ├── README.md ├── config.m4 ├── config.w32 ├── export.go ├── gophp.go ├── gophp.php ├── php_gophp.h └── tests └── 001.phpt /.gitignore: -------------------------------------------------------------------------------- 1 | .deps 2 | *.lo 3 | *.la 4 | .libs 5 | acinclude.m4 6 | aclocal.m4 7 | autom4te.cache 8 | build 9 | config.guess 10 | config.h 11 | config.h.in 12 | config.log 13 | config.nice 14 | config.status 15 | config.sub 16 | configure 17 | configure.in 18 | include 19 | install-sh 20 | libtool 21 | ltmain.sh 22 | Makefile 23 | Makefile.fragments 24 | Makefile.global 25 | Makefile.objects 26 | missing 27 | mkinstalldirs 28 | modules 29 | run-tests.php 30 | tests/*/*.diff 31 | tests/*/*.out 32 | tests/*/*.php 33 | tests/*/*.exp 34 | tests/*/*.log 35 | tests/*/*.sh 36 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | gophp -------------------------------------------------------------------------------- /EXPERIMENTAL: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-aki/gophp_sample/9fbd6388041a62d8f6d163abc1f9a591fbf6779b/EXPERIMENTAL -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | golang で php 拡張を作ってみるテスト 2 | 3 | # environment 4 | * CentOS release 6.7 5 | * PHP 7.0.1 6 | * go version go1.5.2 linux/amd64 7 | 8 | # build 9 | 10 | ``` 11 | $ phpize 12 | $ ./configure 13 | $ CGO_CFLAGS="-g -O0 -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 -I. -DPHP_ATOM_INC \ 14 | -I./include -I./main \ 15 | -I`php-config --include-dir` \ 16 | -I`php-config --include-dir`/main \ 17 | -I`php-config --include-dir`/TSRM \ 18 | -I`php-config --include-dir`/Zend \ 19 | -I`php-config --include-dir`/ext \ 20 | -I`php-config --include-dir`/ext/date/lib \ 21 | -DHAVE_CONFIG_H -DCOMPILE_DL_GOPHP -fPIC -DPIC" \ 22 | CGO_LDFLAGS="-Wl,--export-dynamic -Wl,--unresolved-symbols=ignore-all -Wl,-z,nodelete" \ 23 | go build -p 1 -gcflags "-l" -buildmode=c-shared -o modules/gophp.so gophp.go export.go 24 | 25 | ``` 26 | 27 | # run 28 | 29 | ``` 30 | $ time php -d extension=`pwd`/modules/gophp.so -r 'echo go_fib(40) . PHP_EOL;' 31 | 102334155 32 | php -d extension=`pwd`/modules/gophp.so -r 'echo go_fib(40) . PHP_EOL;' 1.87s user 0.03s system 99% cpu 1.909 total 33 | 34 | ``` 35 | 36 | # see also 37 | http://www.slideshare.net/do_aki/writing-php-extensions-in-golang 38 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 2 | dnl config.m4 for extension gophp 3 | 4 | dnl Comments in this file start with the string 'dnl'. 5 | dnl Remove where necessary. This file will not work 6 | dnl without editing. 7 | 8 | dnl If your extension references something external, use with: 9 | 10 | dnl PHP_ARG_WITH(gophp, for gophp support, 11 | dnl Make sure that the comment is aligned: 12 | dnl [ --with-gophp Include gophp support]) 13 | 14 | dnl Otherwise use enable: 15 | 16 | PHP_ARG_ENABLE(gophp, whether to enable gophp support, 17 | [ --enable-gophp Enable gophp support] 18 | ) 19 | 20 | if test "$PHP_GOPHP" != "no"; then 21 | dnl Write more examples of tests here... 22 | 23 | dnl # --with-gophp -> check with-path 24 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this 25 | dnl SEARCH_FOR="/include/gophp.h" # you most likely want to change this 26 | dnl if test -r $PHP_GOPHP/$SEARCH_FOR; then # path given as parameter 27 | dnl GOPHP_DIR=$PHP_GOPHP 28 | dnl else # search default path list 29 | dnl AC_MSG_CHECKING([for gophp files in default path]) 30 | dnl for i in $SEARCH_PATH ; do 31 | dnl if test -r $i/$SEARCH_FOR; then 32 | dnl GOPHP_DIR=$i 33 | dnl AC_MSG_RESULT(found in $i) 34 | dnl fi 35 | dnl done 36 | dnl fi 37 | dnl 38 | dnl if test -z "$GOPHP_DIR"; then 39 | dnl AC_MSG_RESULT([not found]) 40 | dnl AC_MSG_ERROR([Please reinstall the gophp distribution]) 41 | dnl fi 42 | 43 | dnl # --with-gophp -> add include path 44 | dnl PHP_ADD_INCLUDE($GOPHP_DIR/include) 45 | 46 | dnl # --with-gophp -> check for lib and symbol presence 47 | dnl LIBNAME=gophp # you may want to change this 48 | dnl LIBSYMBOL=gophp # you most likely want to change this 49 | 50 | dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 51 | dnl [ 52 | dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $GOPHP_DIR/$PHP_LIBDIR, GOPHP_SHARED_LIBADD) 53 | dnl AC_DEFINE(HAVE_GOPHPLIB,1,[ ]) 54 | dnl ],[ 55 | dnl AC_MSG_ERROR([wrong gophp lib version or lib not found]) 56 | dnl ],[ 57 | dnl -L$GOPHP_DIR/$PHP_LIBDIR -lm 58 | dnl ]) 59 | dnl 60 | dnl PHP_SUBST(GOPHP_SHARED_LIBADD) 61 | 62 | PHP_NEW_EXTENSION(gophp, gophp.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) 63 | fi 64 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | // If your extension references something external, use ARG_WITH 5 | // ARG_WITH("gophp", "for gophp support", "no"); 6 | 7 | // Otherwise, use ARG_ENABLE 8 | // ARG_ENABLE("gophp", "enable gophp support", "no"); 9 | 10 | if (PHP_GOPHP != "no") { 11 | EXTENSION("gophp", "gophp.c", PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /export.go: -------------------------------------------------------------------------------- 1 | package main 2 | /* 3 | #ifdef HAVE_CONFIG_H 4 | #include "config.h" 5 | #endif 6 | 7 | #include "php.h" 8 | #include "php_ini.h" 9 | #include "ext/standard/info.h" 10 | #include "php_gophp.h" 11 | 12 | */ 13 | import "C" 14 | 15 | //export fib 16 | func fib(n int) int { 17 | if n <= 1 { 18 | return n 19 | } 20 | return fib(n-1) + fib(n-2) 21 | } 22 | 23 | -------------------------------------------------------------------------------- /gophp.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | /* 4 | #ifdef HAVE_CONFIG_H 5 | #include "config.h" 6 | #endif 7 | 8 | #include "php.h" 9 | #include "php_ini.h" 10 | #include "ext/standard/info.h" 11 | #include "php_gophp.h" 12 | 13 | static int le_gophp; 14 | 15 | PHP_MINIT_FUNCTION(gophp) 16 | { 17 | return SUCCESS; 18 | } 19 | 20 | PHP_MSHUTDOWN_FUNCTION(gophp) 21 | { 22 | return SUCCESS; 23 | } 24 | 25 | PHP_MINFO_FUNCTION(gophp) 26 | { 27 | php_info_print_table_start(); 28 | php_info_print_table_header(2, "gophp support", "enabled"); 29 | php_info_print_table_end(); 30 | } 31 | 32 | const zend_function_entry gophp_functions[] = { 33 | PHP_FE(go_fib, NULL) 34 | PHP_FE_END 35 | }; 36 | 37 | zend_module_entry gophp_module_entry = { 38 | STANDARD_MODULE_HEADER, 39 | "gophp", 40 | gophp_functions, 41 | PHP_MINIT(gophp), 42 | PHP_MSHUTDOWN(gophp), 43 | NULL, 44 | NULL, 45 | PHP_MINFO(gophp), 46 | PHP_GOPHP_VERSION, 47 | STANDARD_MODULE_PROPERTIES 48 | }; 49 | 50 | #ifdef COMPILE_DL_GOPHP 51 | #ifdef ZTS 52 | ZEND_TSRMLS_CACHE_DEFINE(); 53 | #endif 54 | ZEND_GET_MODULE(gophp) 55 | #endif 56 | 57 | extern unsigned int fib(unsigned int n); 58 | 59 | PHP_FUNCTION(go_fib) 60 | { 61 | zend_long n; 62 | 63 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &n) == FAILURE) { 64 | return; 65 | } 66 | 67 | RETURN_LONG(fib(n)); 68 | 69 | } 70 | */ 71 | import "C" 72 | 73 | func main(){} 74 | 75 | -------------------------------------------------------------------------------- /gophp.php: -------------------------------------------------------------------------------- 1 | "; 3 | 4 | if(!extension_loaded('gophp')) { 5 | dl('gophp.' . PHP_SHLIB_SUFFIX); 6 | } 7 | $module = 'gophp'; 8 | $functions = get_extension_funcs($module); 9 | echo "Functions available in the test extension:$br\n"; 10 | foreach($functions as $func) { 11 | echo $func."$br\n"; 12 | } 13 | echo "$br\n"; 14 | $function = 'confirm_' . $module . '_compiled'; 15 | if (extension_loaded($module)) { 16 | $str = $function($module); 17 | } else { 18 | $str = "Module $module is not compiled into PHP"; 19 | } 20 | echo "$str\n"; 21 | ?> 22 | -------------------------------------------------------------------------------- /php_gophp.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PHP_GOPHP_H 3 | #define PHP_GOPHP_H 4 | 5 | extern zend_module_entry gophp_module_entry; 6 | #define phpext_gophp_ptr &gophp_module_entry 7 | 8 | #define PHP_GOPHP_VERSION "0.1.0" /* Replace with version number for your extension */ 9 | 10 | #ifdef PHP_WIN32 11 | # define PHP_GOPHP_API __declspec(dllexport) 12 | #elif defined(__GNUC__) && __GNUC__ >= 4 13 | # define PHP_GOPHP_API __attribute__ ((visibility("default"))) 14 | #else 15 | # define PHP_GOPHP_API 16 | #endif 17 | 18 | #ifdef ZTS 19 | #include "TSRM.h" 20 | #endif 21 | 22 | /* 23 | Declare any global variables you may need between the BEGIN 24 | and END macros here: 25 | 26 | ZEND_BEGIN_MODULE_GLOBALS(gophp) 27 | zend_long global_value; 28 | char *global_string; 29 | ZEND_END_MODULE_GLOBALS(gophp) 30 | */ 31 | 32 | /* Always refer to the globals in your function as GOPHP_G(variable). 33 | You are encouraged to rename these macros something shorter, see 34 | examples in any other php module directory. 35 | */ 36 | #define GOPHP_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(gophp, v) 37 | 38 | #if defined(ZTS) && defined(COMPILE_DL_GOPHP) 39 | ZEND_TSRMLS_CACHE_EXTERN(); 40 | #endif 41 | 42 | PHP_FUNCTION(go_fib); 43 | 44 | #endif /* PHP_GOPHP_H */ 45 | 46 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check for gophp presence 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 20 | --EXPECT-- 21 | gophp extension is available 22 | --------------------------------------------------------------------------------