feat(extension): 添加请求生命周期钩子函数支持

- 在扩展模板中添加 PHP_RINIT 和 PHP_RSHUTDOWN 函数实现
- 配置模块入口结构以启用请求初始化和关闭回调
- 更新主程序初始化逻辑以使用模块生命周期函数
- 实现请求启动和关闭时的应用程序初始化清理功能
- 解决 PHP 内部字符串处理的双释放问题
- 简化示例代码以演示全局变量访问功能
pull/1/head
韩天峰 7 months ago
parent 38110f67d5
commit 6632629f58
  1. 39
      examples/hello.php
  2. 52
      src/cpp/main.cc
  3. 16
      src/template/extension.cc.php

@ -1,33 +1,14 @@
<?php
function main(int $argc, array $argv): int
function main(): int
{
$a = 1;
$b = 2;
$c = 3.12343;
$d = 'hello';
$e = ['hello' => 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;
}

@ -4,35 +4,44 @@
#endif
#include <phpx.h>
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;

@ -136,14 +136,26 @@ foreach ($this->nativeConstants as $name => $constant):
<?php endforeach; ?>
}
static PHP_RINIT_FUNCTION(<?=$this->targetName?>) {
php::request_init();
php_app_init();
return SUCCESS;
}
static PHP_RSHUTDOWN_FUNCTION(<?=$this->targetName?>) {
php_app_clean();
php::request_shutdown();
return SUCCESS;
}
zend_module_entry <?=$this->targetName?>_module_entry = {
STANDARD_MODULE_HEADER,
"<?=$this->targetName?>",
ext_functions,
PHP_MINIT(<?=$this->targetName?>),
nullptr,
nullptr,
nullptr,
PHP_RINIT(<?=$this->targetName?>),
PHP_RSHUTDOWN(<?=$this->targetName?>),
nullptr,
nullptr,
STANDARD_MODULE_PROPERTIES,

Loading…
Cancel
Save