├── tests ├── foo.php └── compiletime_001.phpt ├── php_compiletime.h ├── config.m4 ├── README.md ├── .gitignore └── compiletime.c /tests/foo.php: -------------------------------------------------------------------------------- 1 | $afterRequire) { 14 | echo "FAIL!"; 15 | } 16 | var_dump($afterRequire); 17 | --EXPECTF-- 18 | int(%d) 19 | -------------------------------------------------------------------------------- /php_compiletime.h: -------------------------------------------------------------------------------- 1 | /* compiletime extension for PHP */ 2 | 3 | #ifndef PHP_COMPILETIME_H 4 | # define PHP_COMPILETIME_H 5 | 6 | extern zend_module_entry compiletime_module_entry; 7 | # define phpext_compiletime_ptr &compiletime_module_entry 8 | 9 | # define PHP_COMPILETIME_VERSION "0.0.1" 10 | 11 | # if defined(ZTS) && defined(COMPILE_DL_COMPILETIME) 12 | ZEND_TSRMLS_CACHE_EXTERN() 13 | # endif 14 | 15 | #endif /* PHP_COMPILETIME_H */ 16 | 17 | -------------------------------------------------------------------------------- /config.m4: -------------------------------------------------------------------------------- 1 | dnl config.m4 for extension compiletime 2 | 3 | PHP_ARG_ENABLE(compiletime, whether to enable compiletime support, 4 | [ --enable-compiletime Enable compiletime support], no) 5 | 6 | if test "$PHP_COMPILETIME" != "no"; then 7 | AC_CHECK_FUNCS(gettimeofday) 8 | AC_CHECK_FUNCS(clock_gettime) 9 | PHP_SUBST(COMPILETIME_SHARED_LIBADD) 10 | PHP_NEW_EXTENSION(compiletime, compiletime.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) 11 | fi 12 | 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # compiletime 2 | 3 | Running benchmarks of complex PHP code on the CLI? The numbers are lying to 4 | you. Even with `opcache.enable_cli=1` you will have compilation times of the 5 | files in timings. With this extension you can have access how much milliseconds 6 | the current PHP script has spent in compiling (not executing) code. 7 | 8 | ## Installation 9 | 10 | phpize 11 | ./configure 12 | make 13 | sudo make install 14 | echo 'extension=compiletime.so' > /path/to/php.ini.d/compiletime.ini 15 | 16 | ## Usage 17 | 18 | Extension exposes one simple function: 19 | 20 | /** 21 | * Returns the current time spent in compiling since the beginning of script. 22 | */ 23 | function compiletime_get_current() : int 24 | 25 | Substracting two compile time durations allows to compute the time compiling 26 | between those calls. 27 | 28 | License: MIT 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .deps 2 | /Makefile 3 | *.lo 4 | *.loT 5 | *.slo 6 | *.mk 7 | *.la 8 | *.mem 9 | .libs 10 | libs.mk 11 | ac*.m4 12 | /build 13 | /config.h 14 | /config.h.in 15 | /config.nice 16 | /config.sub 17 | /configure 18 | /configure.ac 19 | /configure.in 20 | /config.status 21 | /config.cache 22 | /conftest 23 | /conftest.c 24 | /core 25 | /dynlib.m4 26 | /install-sh 27 | /ltmain.sh 28 | /include 29 | /Makefile.fragments 30 | /Makefile.global 31 | /Makefile.objects 32 | /missing 33 | /memory: 34 | /mkinstalldirs 35 | /modules 36 | /nbproject 37 | /scan_makefile_in.awk 38 | /config.guess 39 | *swo 40 | *swp 41 | *swn 42 | tags 43 | /tmp-php.ini 44 | /config.log 45 | /libtool 46 | *.plg 47 | *.patch 48 | *.tgz 49 | *.ncb 50 | *.opt 51 | *.dsw 52 | /autom4te.cache 53 | .svn 54 | /*~ 55 | tests/*.diff 56 | tests/*.out 57 | tests/*.php 58 | tests/*.sh 59 | tests/*.log 60 | tests/*.exp 61 | run-tests.php 62 | vendor/ 63 | *.phar 64 | php5/*.lo 65 | php7/*.lo 66 | php5/.libs 67 | php7/.libs 68 | /.gdb_history 69 | .vscode 70 | .idea 71 | -------------------------------------------------------------------------------- /compiletime.c: -------------------------------------------------------------------------------- 1 | /* compiletime extension for PHP */ 2 | 3 | #ifdef HAVE_CONFIG_H 4 | # include "config.h" 5 | #endif 6 | 7 | #include 8 | #include 9 | #include 10 | #include "php.h" 11 | #include "ext/standard/info.h" 12 | #include "php_compiletime.h" 13 | 14 | #define COMPILETIME_G(e) php_compiletime_globals.e 15 | 16 | typedef struct _php_compiletime_globals_t { 17 | zend_long compile_time; 18 | } php_compiletime_globals_t; 19 | 20 | ZEND_TLS php_compiletime_globals_t php_compiletime_globals; 21 | 22 | ZEND_API zend_op_array *(*_zend_compile_file)(zend_file_handle *file_handle, int type); 23 | ZEND_DLEXPORT zend_op_array * compiletime_compile_file (zend_file_handle *file_handle, int type); 24 | 25 | static zend_long time_milliseconds() 26 | { 27 | #if HAVE_CLOCK_GETTIME 28 | struct timespec s; 29 | 30 | if (clock_gettime(CLOCK_MONOTONIC, &s) == 0) { 31 | return s.tv_sec * 1000000 + s.tv_nsec / 1000; 32 | } else { 33 | struct timeval now; 34 | if (gettimeofday(&now, NULL) == 0) { 35 | return now.tv_sec * 1000000 + now.tv_usec; 36 | } 37 | } 38 | #elif HAVE_GETTIMEOFDAY 39 | struct timeval now; 40 | if (gettimeofday(&now, NULL) == 0) { 41 | return now.tv_sec * 1000000 + now.tv_usec; 42 | } 43 | #endif 44 | return 0; 45 | } 46 | 47 | ZEND_DLEXPORT zend_op_array * compiletime_compile_file (zend_file_handle *file_handle, int type) 48 | { 49 | zend_op_array *ret; 50 | zend_long start = time_milliseconds(); 51 | 52 | ret = _zend_compile_file (file_handle, type); 53 | 54 | COMPILETIME_G(compile_time) += (time_milliseconds() - start); 55 | 56 | return ret; 57 | } 58 | 59 | PHP_FUNCTION(compiletime_get_current) 60 | { 61 | RETURN_LONG(COMPILETIME_G(compile_time)); 62 | } 63 | 64 | PHP_MINIT_FUNCTION(compiletime) 65 | { 66 | _zend_compile_file = zend_compile_file; 67 | zend_compile_file = compiletime_compile_file; 68 | 69 | return SUCCESS; 70 | } 71 | 72 | PHP_MSHUTDOWN_FUNCTION(compiletime) 73 | { 74 | return SUCCESS; 75 | } 76 | 77 | PHP_RINIT_FUNCTION(compiletime) 78 | { 79 | #if defined(ZTS) && defined(COMPILE_DL_COMPILETIME) 80 | ZEND_TSRMLS_CACHE_UPDATE(); 81 | #endif 82 | 83 | COMPILETIME_G(compile_time) = 0; 84 | 85 | return SUCCESS; 86 | } 87 | 88 | PHP_RSHUTDOWN_FUNCTION(compiletime) 89 | { 90 | return SUCCESS; 91 | } 92 | 93 | PHP_MINFO_FUNCTION(compiletime) 94 | { 95 | php_info_print_table_start(); 96 | php_info_print_table_header(2, "compiletime support", "enabled"); 97 | php_info_print_table_end(); 98 | } 99 | 100 | zend_function_entry php_compiletime_functions[] = { 101 | PHP_FE(compiletime_get_current, NULL) 102 | PHP_FE_END 103 | }; 104 | 105 | zend_module_entry compiletime_module_entry = { 106 | STANDARD_MODULE_HEADER, 107 | "compiletime", 108 | php_compiletime_functions, 109 | PHP_MINIT(compiletime), 110 | PHP_MSHUTDOWN(compiletime), 111 | PHP_RINIT(compiletime), 112 | PHP_RSHUTDOWN(compiletime), 113 | PHP_MINFO(compiletime), 114 | PHP_COMPILETIME_VERSION, 115 | STANDARD_MODULE_PROPERTIES 116 | }; 117 | 118 | #ifdef COMPILE_DL_COMPILETIME 119 | # ifdef ZTS 120 | ZEND_TSRMLS_CACHE_DEFINE() 121 | # endif 122 | ZEND_GET_MODULE(compiletime) 123 | #endif 124 | --------------------------------------------------------------------------------