diff --git a/examples/hello.php b/examples/hello.php index d6b5a1fe..195ce547 100644 --- a/examples/hello.php +++ b/examples/hello.php @@ -1,33 +1,14 @@ 1, 'world' => 33.43]; - - for ($i = 1; $i < $argc; ++$i) { - $a += $argv[$i]; - } - - $argc = 999; - $a = $b * 13; - $a += $b << 4; - $a += $b >> 1; - - $_tmp = $e['hello']; - $_tmp -= 4; - $_tmp *= 5; - $_tmp /= 10; - $_tmp %= 10; - - var_dump($_tmp, 1000); - - echo "value:=" . ($a + $b); - - echo "value:=", $a, $b; - - return $a * $b; + global $a; + $a = 100; + + var_dump($GLOBALS['a']); + var_dump($a); + var_dump(gettype($_SERVER)); + var_dump($_SERVER['argc']); + var_dump($_SERVER['argv']); + return 0; } diff --git a/src/cpp/main.cc b/src/cpp/main.cc index 30450089..d1da7ac8 100644 --- a/src/cpp/main.cc +++ b/src/cpp/main.cc @@ -4,35 +4,44 @@ #endif #include -extern php::Var argc; -extern php::Var argv; - -extern void php_app_init(); -extern void php_app_clean(); extern zend_module_entry *php_embed_get_module(); -int main(int cpp_argc, char **cpp_argv) { - php_embed_init(cpp_argc, cpp_argv); - php::throw_impl = [](zend_object *ex) { throw ex; }; - zend_module_entry *module = php_embed_get_module(); - +void module_init(zend_module_entry *module) { if (zend_register_module_ex(module, MODULE_PERSISTENT) == NULL) { zend_error(E_ERROR, "Failed to register module [%s]", module->name); - return 255; + exit(255); } - if (zend_startup_module_ex(module) == FAILURE) { zend_error(E_ERROR, "Failed to startup module [%s]", module->name); - return 255; + exit(255); } +} + +void module_shutdown(zend_module_entry *module) { + /** + * There is a bug in PHP's handling of internal strings. All interned strings are released in the request shutdown + * function, but then released again in the php_embed_shutdown function, resulting in a use-after-free issue. These + * must be manually removed from the module table to prevent double release. + */ + auto name_len = strlen(module->name); + auto lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT); + zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len); + zend_hash_del(&module_registry, lcname); +} + +int main(int cpp_argc, char **cpp_argv) { + php_embed_init(cpp_argc, cpp_argv); + php::throw_impl = [](zend_object *ex) { throw ex; }; + + zend_module_entry *module = php_embed_get_module(); + module_init(module); int rc = 0; #if PPROF_ON ProfilerStart("profile.out"); #endif try { - php::request_init(); - php_app_init(); + module->request_startup_func(module->type, module->module_number); php::eval("main();"); } catch (zend_object *e) { rc = EG(exit_status); @@ -41,19 +50,8 @@ int main(int cpp_argc, char **cpp_argv) { #if PPROF_ON ProfilerStop(); #endif - php_app_clean(); - php::request_shutdown(); - - /** - * There is a bug in PHP's handling of internal strings. All interned strings are released in the request shutdown - * function, but then released again in the php_embed_shutdown function, resulting in a use-after-free issue. These - * must be manually removed from the module table to prevent double release. - */ - auto name_len = strlen(module->name); - auto lcname = zend_string_alloc(name_len, module->type == MODULE_PERSISTENT); - zend_str_tolower_copy(ZSTR_VAL(lcname), module->name, name_len); - zend_hash_del(&module_registry, lcname); + module->request_shutdown_func(module->type, module->module_number); php_embed_shutdown(); return rc; diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index cada7074..43750218 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -136,14 +136,26 @@ foreach ($this->nativeConstants as $name => $constant): } +static PHP_RINIT_FUNCTION(targetName?>) { + php::request_init(); + php_app_init(); + return SUCCESS; +} + +static PHP_RSHUTDOWN_FUNCTION(targetName?>) { + php_app_clean(); + php::request_shutdown(); + return SUCCESS; +} + zend_module_entry targetName?>_module_entry = { STANDARD_MODULE_HEADER, "targetName?>", ext_functions, PHP_MINIT(targetName?>), nullptr, - nullptr, - nullptr, + PHP_RINIT(targetName?>), + PHP_RSHUTDOWN(targetName?>), nullptr, nullptr, STANDARD_MODULE_PROPERTIES,