diff --git a/caddy/php-cli.go b/caddy/php-cli.go index 4e76ff147a..19b17b7a15 100644 --- a/caddy/php-cli.go +++ b/caddy/php-cli.go @@ -38,6 +38,20 @@ func cmdPHPCLI(fs caddycmd.Flags) (int, error) { } var status int + + if len(args) == 1 { + switch args[0] { + case "-i", "--info": + status = frankenphp.DisplayPHPInfo() + os.Exit(status) + return status, nil + case "-v", "--version": + status = frankenphp.DisplayPHPVersion() + os.Exit(status) + return status, nil + } + } + if len(args) >= 2 && args[0] == "-r" { status = frankenphp.ExecutePHPCode(args[1]) } else { diff --git a/frankenphp.c b/frankenphp.c index 27dc103a90..978ea208c6 100644 --- a/frankenphp.c +++ b/frankenphp.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -1144,21 +1145,16 @@ static void *execute_script_cli(void *arg) { return exit_status; } -int frankenphp_execute_script_cli(char *script, int argc, char **argv, - bool eval) { +static int frankenphp_execute_in_thread(void *(*thread_func)(void *), void *arg) { pthread_t thread; int err; void *exit_status; - cli_script = script; - cli_argc = argc; - cli_argv = argv; - /* * Start the script in a dedicated thread to prevent conflicts between Go and * PHP signal handlers */ - err = pthread_create(&thread, NULL, execute_script_cli, (void *)eval); + err = pthread_create(&thread, NULL, thread_func, arg); if (err != 0) { return err; } @@ -1171,6 +1167,80 @@ int frankenphp_execute_script_cli(char *script, int argc, char **argv, return (intptr_t)exit_status; } +int frankenphp_execute_script_cli(char *script, int argc, char **argv, + bool eval) { + cli_script = script; + cli_argc = argc; + cli_argv = argv; + + return frankenphp_execute_in_thread(execute_script_cli, (void *)eval); +} + +static void *frankenphp_execute_with_php_embed(void *arg) { + php_embed_context *ctx = (php_embed_context *)arg; + void *exit_status; + + php_embed_module.name = ctx->module_name; + php_embed_module.pretty_name = ctx->pretty_name; + + php_embed_init(ctx->argc, ctx->argv); + + zend_first_try { + ctx->execute_func(ctx->execute_arg); + } zend_end_try(); + + exit_status = (void *)(intptr_t)EG(exit_status); + + php_embed_shutdown(); + + return exit_status; +} + +static void *frankenphp_execute_standard(void (*execute_func)(void *)) { + php_embed_context ctx = { + .module_name = "frankenphp", + .pretty_name = "FrankenPHP", + .argc = 0, + .argv = NULL, + .execute_func = execute_func, + .execute_arg = NULL + }; + + return frankenphp_execute_with_php_embed(&ctx); +} + +static void *standard_thread_wrapper(void *arg) { + void (*execute_func)(void *) = (void (*)(void *))arg; + return frankenphp_execute_standard(execute_func); +} + +static int frankenphp_execute_standard_in_thread(void (*execute_func)(void *)) { + return frankenphp_execute_in_thread(standard_thread_wrapper, (void *)execute_func); +} + +static void execute_phpinfo(void *arg) { + int as_text = sapi_module.phpinfo_as_text; + sapi_module.phpinfo_as_text = 1; + + php_print_info(PHP_INFO_ALL); + php_output_end_all(); + + sapi_module.phpinfo_as_text = as_text; +} + +static void execute_version_print(void *arg) { + const char *vi = php_version(); + php_printf("%s\n", vi); +} + +int frankenphp_print_phpinfo(void) { + return frankenphp_execute_standard_in_thread(execute_phpinfo); +} + +int frankenphp_print_php_version(void) { + return frankenphp_execute_standard_in_thread(execute_version_print); +} + int frankenphp_reset_opcache(void) { zend_function *opcache_reset = zend_hash_str_find_ptr(CG(function_table), ZEND_STRL("opcache_reset")); diff --git a/frankenphp.go b/frankenphp.go index 37fb236784..015574646c 100644 --- a/frankenphp.go +++ b/frankenphp.go @@ -628,6 +628,14 @@ func ExecutePHPCode(phpCode string) int { return int(C.frankenphp_execute_script_cli(cCode, 0, nil, true)) } +func DisplayPHPInfo() int { + return int(C.frankenphp_print_phpinfo()) +} + +func DisplayPHPVersion() int { + return int(C.frankenphp_print_php_version()) +} + func convertArgs(args []string) (C.int, []*C.char) { argc := C.int(len(args)) argv := make([]*C.char, argc) diff --git a/frankenphp.h b/frankenphp.h index 6d95629006..c1d69dbbdd 100644 --- a/frankenphp.h +++ b/frankenphp.h @@ -65,6 +65,18 @@ int frankenphp_execute_script(char *file_name); int frankenphp_execute_script_cli(char *script, int argc, char **argv, bool eval); +typedef struct { + char *module_name; + char *pretty_name; + int argc; + char **argv; + void (*execute_func)(void *); + void *execute_arg; +} php_embed_context; + +int frankenphp_print_phpinfo(); +int frankenphp_print_php_version(); + void frankenphp_register_variables_from_request_info( zval *track_vars_array, zend_string *content_type, zend_string *path_translated, zend_string *query_string,