├── config.m4 ├── config.w32 ├── php_test.h ├── test.c └── tests ├── 001.phpt ├── 002.phpt └── 003.phpt /config.m4: -------------------------------------------------------------------------------- 1 | dnl config.m4 for extension test 2 | 3 | dnl Comments in this file start with the string 'dnl'. 4 | dnl Remove where necessary. 5 | 6 | dnl If your extension references something external, use 'with': 7 | 8 | dnl PHP_ARG_WITH([test], 9 | dnl [for test support], 10 | dnl [AS_HELP_STRING([--with-test], 11 | dnl [Include test support])]) 12 | 13 | dnl Otherwise use 'enable': 14 | 15 | PHP_ARG_ENABLE([test], 16 | [whether to enable test support], 17 | [AS_HELP_STRING([--enable-test], 18 | [Enable test support])], 19 | [no]) 20 | 21 | if test "$PHP_TEST" != "no"; then 22 | dnl Write more examples of tests here... 23 | 24 | dnl Remove this code block if the library does not support pkg-config. 25 | dnl PKG_CHECK_MODULES([LIBFOO], [foo]) 26 | dnl PHP_EVAL_INCLINE($LIBFOO_CFLAGS) 27 | dnl PHP_EVAL_LIBLINE($LIBFOO_LIBS, TEST_SHARED_LIBADD) 28 | 29 | dnl If you need to check for a particular library version using PKG_CHECK_MODULES, 30 | dnl you can use comparison operators. For example: 31 | dnl PKG_CHECK_MODULES([LIBFOO], [foo >= 1.2.3]) 32 | dnl PKG_CHECK_MODULES([LIBFOO], [foo < 3.4]) 33 | dnl PKG_CHECK_MODULES([LIBFOO], [foo = 1.2.3]) 34 | 35 | dnl Remove this code block if the library supports pkg-config. 36 | dnl --with-test -> check with-path 37 | dnl SEARCH_PATH="/usr/local /usr" # you might want to change this 38 | dnl SEARCH_FOR="/include/test.h" # you most likely want to change this 39 | dnl if test -r $PHP_TEST/$SEARCH_FOR; then # path given as parameter 40 | dnl TEST_DIR=$PHP_TEST 41 | dnl else # search default path list 42 | dnl AC_MSG_CHECKING([for test files in default path]) 43 | dnl for i in $SEARCH_PATH ; do 44 | dnl if test -r $i/$SEARCH_FOR; then 45 | dnl TEST_DIR=$i 46 | dnl AC_MSG_RESULT(found in $i) 47 | dnl fi 48 | dnl done 49 | dnl fi 50 | dnl 51 | dnl if test -z "$TEST_DIR"; then 52 | dnl AC_MSG_RESULT([not found]) 53 | dnl AC_MSG_ERROR([Please reinstall the test distribution]) 54 | dnl fi 55 | 56 | dnl Remove this code block if the library supports pkg-config. 57 | dnl --with-test -> add include path 58 | dnl PHP_ADD_INCLUDE($TEST_DIR/include) 59 | 60 | dnl Remove this code block if the library supports pkg-config. 61 | dnl --with-test -> check for lib and symbol presence 62 | dnl LIBNAME=TEST # you may want to change this 63 | dnl LIBSYMBOL=TEST # you most likely want to change this 64 | 65 | dnl If you need to check for a particular library function (e.g. a conditional 66 | dnl or version-dependent feature) and you are using pkg-config: 67 | dnl PHP_CHECK_LIBRARY($LIBNAME, $LIBSYMBOL, 68 | dnl [ 69 | dnl AC_DEFINE(HAVE_TEST_FEATURE, 1, [ ]) 70 | dnl ],[ 71 | dnl AC_MSG_ERROR([FEATURE not supported by your test library.]) 72 | dnl ], [ 73 | dnl $LIBFOO_LIBS 74 | dnl ]) 75 | 76 | dnl If you need to check for a particular library function (e.g. a conditional 77 | dnl or version-dependent feature) and you are not using pkg-config: 78 | dnl PHP_CHECK_LIBRARY($LIBNAME, $LIBSYMBOL, 79 | dnl [ 80 | dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $TEST_DIR/$PHP_LIBDIR, TEST_SHARED_LIBADD) 81 | dnl AC_DEFINE(HAVE_TEST_FEATURE, 1, [ ]) 82 | dnl ],[ 83 | dnl AC_MSG_ERROR([FEATURE not supported by your test library.]) 84 | dnl ],[ 85 | dnl -L$TEST_DIR/$PHP_LIBDIR -lm 86 | dnl ]) 87 | dnl 88 | dnl PHP_SUBST(TEST_SHARED_LIBADD) 89 | 90 | dnl In case of no dependencies 91 | AC_DEFINE(HAVE_TEST, 1, [ Have test support ]) 92 | 93 | PHP_NEW_EXTENSION(test, test.c, $ext_shared) 94 | fi 95 | -------------------------------------------------------------------------------- /config.w32: -------------------------------------------------------------------------------- 1 | ARG_ENABLE('test', 'test support', 'no'); 2 | 3 | if (PHP_TEST != 'no') { 4 | AC_DEFINE('HAVE_TEST', 1, 'test support enabled'); 5 | 6 | EXTENSION('test', 'test.c', null, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); 7 | } 8 | -------------------------------------------------------------------------------- /php_test.h: -------------------------------------------------------------------------------- 1 | /* test extension for PHP */ 2 | 3 | #ifndef PHP_TEST_H 4 | # define PHP_TEST_H 5 | 6 | extern zend_module_entry test_module_entry; 7 | # define phpext_test_ptr &test_module_entry 8 | 9 | # define PHP_TEST_VERSION "0.1.0" 10 | 11 | # if defined(ZTS) && defined(COMPILE_DL_TEST) 12 | ZEND_TSRMLS_CACHE_EXTERN() 13 | # endif 14 | 15 | ZEND_BEGIN_MODULE_GLOBALS(test) 16 | zend_long scale; 17 | ZEND_END_MODULE_GLOBALS(test) 18 | 19 | ZEND_EXTERN_MODULE_GLOBALS(test) 20 | 21 | #define TEST_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(test, v) 22 | 23 | #endif /* PHP_TEST_H */ 24 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | /* test extension for PHP */ 2 | 3 | #ifdef HAVE_CONFIG_H 4 | # include "config.h" 5 | #endif 6 | 7 | #include "php.h" 8 | #include "ext/standard/info.h" 9 | #include "php_test.h" 10 | 11 | /* For compatibility with older PHP versions */ 12 | #ifndef ZEND_PARSE_PARAMETERS_NONE 13 | #define ZEND_PARSE_PARAMETERS_NONE() \ 14 | ZEND_PARSE_PARAMETERS_START(0, 0) \ 15 | ZEND_PARSE_PARAMETERS_END() 16 | #endif 17 | 18 | ZEND_DECLARE_MODULE_GLOBALS(test) 19 | 20 | PHP_INI_BEGIN() 21 | STD_PHP_INI_ENTRY("test.scale", "1", PHP_INI_ALL, OnUpdateLong, scale, 22 | zend_test_globals, test_globals) 23 | PHP_INI_END() 24 | 25 | /* {{{ void test_test1() 26 | */ 27 | PHP_FUNCTION(test_test1) 28 | { 29 | ZEND_PARSE_PARAMETERS_NONE(); 30 | 31 | php_printf("The extension %s is loaded and working!\r\n", "test"); 32 | } 33 | /* }}} */ 34 | 35 | /* {{{ string test_test2( [ string $var ] ) 36 | */ 37 | PHP_FUNCTION(test_test2) 38 | { 39 | char *var = "World"; 40 | size_t var_len = sizeof("World") - 1; 41 | zend_string *retval; 42 | 43 | ZEND_PARSE_PARAMETERS_START(0, 1) 44 | Z_PARAM_OPTIONAL 45 | Z_PARAM_STRING(var, var_len) 46 | ZEND_PARSE_PARAMETERS_END(); 47 | 48 | retval = strpprintf(0, "Hello %s", var); 49 | 50 | RETURN_STR(retval); 51 | } 52 | /* }}}*/ 53 | 54 | static int do_scale_ref(zval *x, zend_long factor) 55 | { 56 | ZVAL_DEREF(x); 57 | if (Z_TYPE_P(x) == IS_LONG) { 58 | Z_LVAL_P(x) *= factor; 59 | } else if (Z_TYPE_P(x) == IS_DOUBLE) { 60 | Z_DVAL_P(x) *= factor; 61 | } else if (Z_TYPE_P(x) == IS_STRING) { 62 | size_t len = Z_STRLEN_P(x); 63 | char *p; 64 | 65 | ZVAL_STR(x, zend_string_safe_realloc(Z_STR_P(x), len, factor, 0, 0)); 66 | p = Z_STRVAL_P(x) + len; 67 | while (--factor > 0) { 68 | memcpy(p, Z_STRVAL_P(x), len); 69 | p += len; 70 | } 71 | *p = '\000'; 72 | } else if (Z_TYPE_P(x) == IS_ARRAY) { 73 | zval *val; 74 | 75 | SEPARATE_ARRAY(x); 76 | ZEND_HASH_FOREACH_VAL(Z_ARR_P(x), val) { 77 | if (do_scale_ref(val, factor) != SUCCESS) { 78 | return FAILURE; 79 | } 80 | } ZEND_HASH_FOREACH_END(); 81 | } else { 82 | php_error_docref(NULL, E_WARNING, "unexpected argument type"); 83 | return FAILURE; 84 | } 85 | return SUCCESS; 86 | } 87 | 88 | PHP_FUNCTION(test_scale_ref) 89 | { 90 | zval *x; 91 | zend_long factor = TEST_G(scale); // default value 92 | 93 | ZEND_PARSE_PARAMETERS_START(1, 2) 94 | Z_PARAM_ZVAL(x) 95 | Z_PARAM_OPTIONAL 96 | Z_PARAM_LONG(factor) 97 | ZEND_PARSE_PARAMETERS_END(); 98 | 99 | do_scale_ref(x, factor); 100 | } 101 | 102 | static PHP_GINIT_FUNCTION(test) 103 | { 104 | #if defined(COMPILE_DL_BCMATH) && defined(ZTS) 105 | ZEND_TSRMLS_CACHE_UPDATE(); 106 | #endif 107 | test_globals->scale= 1; 108 | } 109 | 110 | /* {{{ PHP_MINIT_FUNCTION 111 | */ 112 | PHP_MINIT_FUNCTION(test) 113 | { 114 | REGISTER_INI_ENTRIES(); 115 | 116 | return SUCCESS; 117 | } 118 | /* }}} */ 119 | 120 | /* {{{ PHP_MINFO_FUNCTION 121 | */ 122 | PHP_MINFO_FUNCTION(test) 123 | { 124 | php_info_print_table_start(); 125 | php_info_print_table_header(2, "test support", "enabled"); 126 | php_info_print_table_end(); 127 | } 128 | /* }}} */ 129 | 130 | /* {{{ arginfo 131 | */ 132 | ZEND_BEGIN_ARG_INFO(arginfo_test_test1, 0) 133 | ZEND_END_ARG_INFO() 134 | 135 | ZEND_BEGIN_ARG_INFO(arginfo_test_test2, 0) 136 | ZEND_ARG_INFO(0, str) 137 | ZEND_END_ARG_INFO() 138 | /* }}} */ 139 | 140 | ZEND_BEGIN_ARG_INFO(arginfo_test_scale_ref, 0) 141 | ZEND_ARG_INFO(1, x) // pass by reference 142 | ZEND_ARG_INFO(0, factor) 143 | ZEND_END_ARG_INFO() 144 | 145 | /* {{{ test_functions[] 146 | */ 147 | static const zend_function_entry test_functions[] = { 148 | PHP_FE(test_test1, arginfo_test_test1) 149 | PHP_FE(test_test2, arginfo_test_test2) 150 | PHP_FE(test_scale_ref, arginfo_test_scale_ref) 151 | PHP_FE_END 152 | }; 153 | /* }}} */ 154 | 155 | /* {{{ test_module_entry 156 | */ 157 | zend_module_entry test_module_entry = { 158 | STANDARD_MODULE_HEADER, 159 | "test", /* Extension name */ 160 | test_functions, /* zend_function_entry */ 161 | PHP_MINIT(test), /* PHP_MINIT - Module initialization */ 162 | NULL, /* PHP_MSHUTDOWN - Module shutdown */ 163 | NULL, /* PHP_RINIT - Request initialization */ 164 | NULL, /* PHP_RSHUTDOWN - Request shutdown */ 165 | PHP_MINFO(test), /* PHP_MINFO - Module info */ 166 | PHP_TEST_VERSION, /* Version */ 167 | PHP_MODULE_GLOBALS(test), /* Module globals */ 168 | PHP_GINIT(test), /* PHP_GINIT - Globals initialization */ 169 | NULL, /* PHP_GSHUTDOWN - Globals shutdown */ 170 | NULL, 171 | STANDARD_MODULE_PROPERTIES_EX 172 | }; 173 | /* }}} */ 174 | 175 | #ifdef COMPILE_DL_TEST 176 | # ifdef ZTS 177 | ZEND_TSRMLS_CACHE_DEFINE() 178 | # endif 179 | ZEND_GET_MODULE(test) 180 | #endif 181 | -------------------------------------------------------------------------------- /tests/001.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | Check if test is loaded 3 | --SKIPIF-- 4 | 9 | --FILE-- 10 | 13 | --EXPECT-- 14 | The extension "test" is available 15 | -------------------------------------------------------------------------------- /tests/002.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | test_test1() Basic test 3 | --SKIPIF-- 4 | 9 | --FILE-- 10 | 15 | --EXPECT-- 16 | The extension test is loaded and working! 17 | NULL 18 | -------------------------------------------------------------------------------- /tests/003.phpt: -------------------------------------------------------------------------------- 1 | --TEST-- 2 | test_test2() Basic test 3 | --SKIPIF-- 4 | 9 | --FILE-- 10 | 14 | --EXPECT-- 15 | string(11) "Hello World" 16 | string(9) "Hello PHP" 17 | --------------------------------------------------------------------------------