├── EXPERIMENTAL ├── CREDITS ├── .gitignore ├── config.w32 ├── ant.php ├── tests └── 001.phpt ├── README.md ├── config.m4 ├── php_ant.h └── ant.c /EXPERIMENTAL: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CREDITS: -------------------------------------------------------------------------------- 1 | ant 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_* 2 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | // vim:ft=javascript 3 | 4 | // If your extension references something external, use ARG_WITH 5 | // ARG_WITH("ant", "for ant support", "no"); 6 | 7 | // Otherwise, use ARG_ENABLE 8 | ARG_ENABLE("ant", "enable ant support", "no"); 9 | 10 | if (PHP_ANT != "no") { 11 | EXTENSION("ant", "ant.c", PHP_EXTNAME_SHARED, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /ant.php: -------------------------------------------------------------------------------- 1 | "; 3 | 4 | if(!extension_loaded('ant')) { 5 | dl('ant.' . PHP_SHLIB_SUFFIX); 6 | } 7 | $module = 'ant'; 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 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check for ant presence 3 | --SKIPIF-- 4 | 5 | --FILE-- 6 | 20 | --EXPECT-- 21 | ant extension is available 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ant PHP Extension 2 | 3 | PHP 扩展, 用于 PHP-FPM、FastCGI 模式下突破 `disabled_functions`。 4 | 5 | ### 原理 6 | 7 | 加载该扩展后, 可使用函数 `antsystem` 执行命令(相当于 `system` 别名) 8 | 9 | eg: 10 | 11 | ```php 12 | 13 | ``` 14 | 15 | ### php.ini 样例 16 | 17 | ``` 18 | disable_functions = pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,system 19 | ``` 20 | 21 | ### 编译 22 | 23 | ```bash 24 | $ cd ant_php_extension/ 25 | $ phpize && ./configure && make 26 | ``` 27 | 28 | 编译完成后当前目录下的 `ant.so` 则是需要的文件 29 | 30 | ### 安装到本机 31 | 32 | ```bash 33 | $ cd ant_php_extension/ 34 | $ phpize && ./configure && make 35 | $ make install 36 | 37 | # 测试 38 | $ php -d enable_dl=On ant.php 39 | ``` 40 | 41 | ### 相关链接 42 | 43 | * [AntSword](github.com/antswordproject/antsword) 44 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl $Id$ 2 | dnl config.m4 for extension ant 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 | PHP_ARG_WITH(ant, for ant support, 11 | Make sure that the comment is aligned: 12 | [ --with-ant Include ant support]) 13 | 14 | dnl Otherwise use enable: 15 | 16 | PHP_ARG_ENABLE(ant, whether to enable ant support, 17 | Make sure that the comment is aligned: 18 | [ --enable-ant Enable ant support]) 19 | 20 | if test "$PHP_ANT" != "no"; then 21 | dnl Write more examples of tests here... 22 | 23 | dnl # get library FOO build options from pkg-config output 24 | dnl AC_PATH_PROG(PKG_CONFIG, pkg-config, no) 25 | dnl AC_MSG_CHECKING(for libfoo) 26 | dnl if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists foo; then 27 | dnl if $PKG_CONFIG foo --atleast-version 1.2.3; then 28 | dnl LIBFOO_CFLAGS=`$PKG_CONFIG foo --cflags` 29 | dnl LIBFOO_LIBDIR=`$PKG_CONFIG foo --libs` 30 | dnl LIBFOO_VERSON=`$PKG_CONFIG foo --modversion` 31 | dnl AC_MSG_RESULT(from pkgconfig: version $LIBFOO_VERSON) 32 | dnl else 33 | dnl AC_MSG_ERROR(system libfoo is too old: version 1.2.3 required) 34 | dnl fi 35 | dnl else 36 | dnl AC_MSG_ERROR(pkg-config not found) 37 | dnl fi 38 | dnl PHP_EVAL_LIBLINE($LIBFOO_LIBDIR, ANT_SHARED_LIBADD) 39 | dnl PHP_EVAL_INCLINE($LIBFOO_CFLAGS) 40 | 41 | dnl # --with-ant -> check with-path 42 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this 43 | dnl SEARCH_FOR="/include/ant.h" # you most likely want to change this 44 | dnl if test -r $PHP_ANT/$SEARCH_FOR; then # path given as parameter 45 | dnl ANT_DIR=$PHP_ANT 46 | dnl else # search default path list 47 | dnl AC_MSG_CHECKING([for ant files in default path]) 48 | dnl for i in $SEARCH_PATH ; do 49 | dnl if test -r $i/$SEARCH_FOR; then 50 | dnl ANT_DIR=$i 51 | dnl AC_MSG_RESULT(found in $i) 52 | dnl fi 53 | dnl done 54 | dnl fi 55 | dnl 56 | dnl if test -z "$ANT_DIR"; then 57 | dnl AC_MSG_RESULT([not found]) 58 | dnl AC_MSG_ERROR([Please reinstall the ant distribution]) 59 | dnl fi 60 | 61 | dnl # --with-ant -> add include path 62 | dnl PHP_ADD_INCLUDE($ANT_DIR/include) 63 | 64 | dnl # --with-ant -> check for lib and symbol presence 65 | dnl LIBNAME=ant # you may want to change this 66 | dnl LIBSYMBOL=ant # you most likely want to change this 67 | 68 | dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, 69 | dnl [ 70 | dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $ANT_DIR/$PHP_LIBDIR, ANT_SHARED_LIBADD) 71 | dnl AC_DEFINE(HAVE_ANTLIB,1,[ ]) 72 | dnl ],[ 73 | dnl AC_MSG_ERROR([wrong ant lib version or lib not found]) 74 | dnl ],[ 75 | dnl -L$ANT_DIR/$PHP_LIBDIR -lm 76 | dnl ]) 77 | dnl 78 | dnl PHP_SUBST(ANT_SHARED_LIBADD) 79 | 80 | dnl PHP_NEW_EXTENSION(ant, ant.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) 81 | PHP_NEW_EXTENSION(ant, ant.c, $ext_shared) 82 | fi 83 | -------------------------------------------------------------------------------- /php_ant.h: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5, 7, 8 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2018 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: github.com/antswordproject | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifndef PHP_ANT_H 22 | #define PHP_ANT_H 23 | 24 | extern zend_module_entry ant_module_entry; 25 | #define phpext_ant_ptr &ant_module_entry 26 | 27 | #define PHP_ANT_VERSION "0.1.0" /* Replace with version number for your extension */ 28 | 29 | #ifdef PHP_WIN32 30 | # define PHP_ANT_API __declspec(dllexport) 31 | #elif defined(__GNUC__) && __GNUC__ >= 4 32 | # define PHP_ANT_API __attribute__ ((visibility("default"))) 33 | #else 34 | # define PHP_ANT_API 35 | #endif 36 | 37 | #ifdef ZTS 38 | #include "TSRM.h" 39 | #endif 40 | 41 | PHP_MINIT_FUNCTION(ant); 42 | PHP_MSHUTDOWN_FUNCTION(ant); 43 | PHP_RINIT_FUNCTION(ant); 44 | PHP_RSHUTDOWN_FUNCTION(ant); 45 | PHP_MINFO_FUNCTION(ant); 46 | 47 | PHP_FUNCTION(confirm_ant_compiled); 48 | PHP_FUNCTION(antsystem); /* php system */ 49 | 50 | /* 51 | Declare any global variables you may need between the BEGIN 52 | and END macros here: 53 | 54 | ZEND_BEGIN_MODULE_GLOBALS(ant) 55 | zend_long global_value; 56 | char *global_string; 57 | ZEND_END_MODULE_GLOBALS(ant) 58 | */ 59 | #if PHP_MAJOR_VERSION == 7 || PHP_MAJOR_VERSION == 8 60 | /* Always refer to the globals in your function as ANT_G(variable). 61 | You are encouraged to rename these macros something shorter, see 62 | examples in any other php module directory. 63 | */ 64 | #define ANT_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(ant, v) 65 | 66 | #if defined(ZTS) && defined(COMPILE_DL_ANT) 67 | ZEND_TSRMLS_CACHE_EXTERN() 68 | #endif 69 | 70 | #elif PHP_MAJOR_VERSION == 5 71 | 72 | #ifdef ZTS 73 | #define ANT_G(v) TSRMG(ant_globals_id, zend_ant_globals *, v) 74 | #else 75 | #define ANT_G(v) (ant_globals.v) 76 | #endif 77 | 78 | #else /* PHP_MAJOR_VERSION */ 79 | 80 | #endif /* PHP_MAJOR_VERSION */ 81 | 82 | #endif /* PHP_ANT_H */ 83 | 84 | /* 兼容php5-8 */ 85 | #if PHP_MAJOR_VERSION == 8 86 | #define TSRMLS_CC 87 | #endif 88 | 89 | #if PHP_MAJOR_VERSION == 5 90 | #define ant_num_type int 91 | #else 92 | #define ant_num_type size_t 93 | #endif 94 | 95 | /* 96 | * Local variables: 97 | * tab-width: 4 98 | * c-basic-offset: 4 99 | * End: 100 | * vim600: noet sw=4 ts=4 fdm=marker 101 | * vim<600: noet sw=4 ts=4 102 | */ 103 | -------------------------------------------------------------------------------- /ant.c: -------------------------------------------------------------------------------- 1 | /* 2 | +----------------------------------------------------------------------+ 3 | | PHP Version 5, 7, 8 | 4 | +----------------------------------------------------------------------+ 5 | | Copyright (c) 1997-2018 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: github.com/antswordproject | 16 | +----------------------------------------------------------------------+ 17 | */ 18 | 19 | /* $Id$ */ 20 | 21 | #ifdef HAVE_CONFIG_H 22 | #include "config.h" 23 | #endif 24 | 25 | #include "php.h" 26 | #include "php_ini.h" 27 | #include "ext/standard/info.h" 28 | #include "ext/standard/exec.h" 29 | #include "php_ant.h" 30 | 31 | /* If you declare any globals in php_ant.h uncomment this: 32 | ZEND_DECLARE_MODULE_GLOBALS(ant) 33 | */ 34 | 35 | /* True global resources - no need for thread safety here */ 36 | static int le_ant; 37 | 38 | /* {{{ ext/standard/basic_functions.c for exec.c */ 39 | ZEND_BEGIN_ARG_INFO_EX(arginfo_system, 0, 0, 1) 40 | ZEND_ARG_INFO(0, command) 41 | ZEND_END_ARG_INFO() 42 | /* }}} */ 43 | 44 | ZEND_BEGIN_ARG_INFO_EX(arginfo_compile, 0, 0, 1) 45 | ZEND_ARG_INFO(0, data) 46 | ZEND_END_ARG_INFO() 47 | 48 | 49 | /* {{{ ant_functions[] 50 | * 51 | * Every user visible function must have an entry in ant_functions[]. 52 | */ 53 | const zend_function_entry ant_functions[] = { 54 | PHP_FE(confirm_ant_compiled, arginfo_compile) /* For testing, remove later. */ 55 | PHP_FE(antsystem, arginfo_system) 56 | PHP_FE_END /* Must be the last line in ant_functions[] */ 57 | }; 58 | /* }}} */ 59 | 60 | /* {{{ ant_module_entry 61 | */ 62 | zend_module_entry ant_module_entry = { 63 | #if ZEND_MODULE_API_NO >= 20010901 64 | STANDARD_MODULE_HEADER, 65 | #endif 66 | "ant", 67 | ant_functions, 68 | PHP_MINIT(ant), 69 | PHP_MSHUTDOWN(ant), 70 | PHP_RINIT(ant), /* Replace with NULL if there's nothing to do at request start */ 71 | PHP_RSHUTDOWN(ant), /* Replace with NULL if there's nothing to do at request end */ 72 | PHP_MINFO(ant), 73 | #if ZEND_MODULE_API_NO >= 20010901 74 | PHP_ANT_VERSION, 75 | #endif 76 | STANDARD_MODULE_PROPERTIES 77 | }; 78 | /* }}} */ 79 | 80 | /* {{{ PHP_INI 81 | */ 82 | /* Remove comments and fill if you need to have entries in php.ini 83 | PHP_INI_BEGIN() 84 | STD_PHP_INI_ENTRY("ant.global_value", "42", PHP_INI_ALL, OnUpdateLong, global_value, zend_ant_globals, ant_globals) 85 | STD_PHP_INI_ENTRY("ant.global_string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_ant_globals, ant_globals) 86 | PHP_INI_END() 87 | */ 88 | /* }}} */ 89 | 90 | /* Remove the following function when you have successfully modified config.m4 91 | so that your module can be compiled into PHP, it exists only for testing 92 | purposes. */ 93 | 94 | /* Every user-visible function in PHP should document itself in the source */ 95 | /* {{{ proto string confirm_ant_compiled(string arg) 96 | Return a string to confirm that the module is compiled in */ 97 | PHP_FUNCTION(confirm_ant_compiled) 98 | { 99 | #if PHP_MAJOR_VERSION == 7 || PHP_MAJOR_VERSION == 8 100 | char *arg = NULL; 101 | size_t arg_len, len; 102 | zend_string *strg; 103 | 104 | if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &arg, &arg_len) == FAILURE) { 105 | return; 106 | } 107 | 108 | strg = strpprintf(0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "ant", arg); 109 | 110 | RETURN_STR(strg); 111 | 112 | #elif PHP_MAJOR_VERSION == 5 113 | char *arg = NULL; 114 | int arg_len, len; 115 | char *strg; 116 | 117 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { 118 | return; 119 | } 120 | 121 | len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "ant", arg); 122 | RETURN_STRINGL(strg, len, 0); 123 | #else 124 | #endif 125 | }; 126 | /* }}} */ 127 | 128 | 129 | static void ant_system(INTERNAL_FUNCTION_PARAMETERS) 130 | { 131 | char *cmd=""; 132 | ant_num_type cmd_len; 133 | int ret; 134 | 135 | if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &cmd, &cmd_len) == FAILURE) { 136 | RETURN_FALSE; 137 | } 138 | 139 | if (!cmd_len) { 140 | php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute a blank command"); 141 | RETURN_FALSE; 142 | } 143 | 144 | /* call the system function directly */ 145 | ret = php_exec(1, cmd, NULL, return_value TSRMLS_CC); 146 | 147 | /* set the status code into return value */ 148 | RETURN_LONG(ret); 149 | } 150 | 151 | 152 | /* {{{ proto int antsystem(string command [, int &return_value]) 153 | Execute an external program and display output */ 154 | PHP_FUNCTION(antsystem) 155 | { 156 | ant_system(INTERNAL_FUNCTION_PARAM_PASSTHRU); 157 | }; 158 | /* }}} */ 159 | /* The previous line is meant for vim and emacs, so it can correctly fold and 160 | unfold functions in source code. See the corresponding marks just before 161 | function definition, where the functions purpose is also documented. Please 162 | follow this convention for the convenience of others editing your code. 163 | */ 164 | 165 | 166 | /* {{{ php_ant_init_globals 167 | */ 168 | /* Uncomment this function if you have INI entries 169 | static void php_ant_init_globals(zend_ant_globals *ant_globals) 170 | { 171 | ant_globals->global_value = 0; 172 | ant_globals->global_string = NULL; 173 | } 174 | */ 175 | /* }}} */ 176 | 177 | /* {{{ PHP_MINIT_FUNCTION 178 | */ 179 | PHP_MINIT_FUNCTION(ant) 180 | { 181 | /* If you have INI entries, uncomment these lines 182 | REGISTER_INI_ENTRIES(); 183 | */ 184 | return SUCCESS; 185 | } 186 | /* }}} */ 187 | 188 | /* {{{ PHP_MSHUTDOWN_FUNCTION 189 | */ 190 | PHP_MSHUTDOWN_FUNCTION(ant) 191 | { 192 | /* uncomment this line if you have INI entries 193 | UNREGISTER_INI_ENTRIES(); 194 | */ 195 | return SUCCESS; 196 | } 197 | /* }}} */ 198 | 199 | /* Remove if there's nothing to do at request start */ 200 | /* {{{ PHP_RINIT_FUNCTION 201 | */ 202 | PHP_RINIT_FUNCTION(ant) 203 | { 204 | #if PHP_MAJOR_VERSION == 7 205 | #if defined(COMPILE_DL_ANT) && defined(ZTS) 206 | ZEND_TSRMLS_CACHE_UPDATE(); 207 | #endif 208 | #endif 209 | return SUCCESS; 210 | }; 211 | /* }}} */ 212 | 213 | /* Remove if there's nothing to do at request end */ 214 | /* {{{ PHP_RSHUTDOWN_FUNCTION 215 | */ 216 | PHP_RSHUTDOWN_FUNCTION(ant) 217 | { 218 | return SUCCESS; 219 | }; 220 | /* }}} */ 221 | 222 | /* {{{ PHP_MINFO_FUNCTION 223 | */ 224 | PHP_MINFO_FUNCTION(ant) 225 | { 226 | php_info_print_table_start(); 227 | php_info_print_table_header(2, "ant support", "enabled"); 228 | php_info_print_table_end(); 229 | 230 | /* Remove comments if you have entries in php.ini 231 | DISPLAY_INI_ENTRIES(); 232 | */ 233 | }; 234 | /* }}} */ 235 | 236 | #ifdef COMPILE_DL_ANT 237 | #if PHP_MAJOR_VERSION == 7 238 | 239 | #ifdef ZTS 240 | ZEND_TSRMLS_CACHE_DEFINE() 241 | #endif 242 | 243 | #endif /* PHP_MAJOR_VERSION */ 244 | ZEND_GET_MODULE(ant) 245 | #endif 246 | 247 | /* 248 | * Local variables: 249 | * tab-width: 4 250 | * c-basic-offset: 4 251 | * End: 252 | * vim600: noet sw=4 ts=4 fdm=marker 253 | * vim<600: noet sw=4 ts=4 254 | */ 255 | --------------------------------------------------------------------------------