php内核 PHP内置函数底层C代码注册流程
·
内置函数在底层 C 的注册流程,按最实用顺序就是这 8 步:
1. 写函数实现 2. 写参数签名 arginfo
3. 写函数注册表 zend_function_entry[] 4. 写模块入口 zend_module_entry
5. 在 config.m4 声明扩展
6. PHP_NEW_EXTENSION(..., $ext_shared) 支持静态/动态
7. ./configure --enable-hp(静态内置)或 --enable-hp=shared(so)
8. 编译后用 php -m、function_exists() 验证
下面给你最小完整模板。
---
1) 函数实现(C)
PHP_FUNCTION(hp_hello)
{
RETURN_STRING("hello hp");
}
---
2) 参数信息(arginfo)
ZEND_BEGIN_ARG_INFO_EX(arginfo_hp_hello, 0, 0, 0)
ZEND_END_ARG_INFO()
如果有参数,比如 hp_add(int $a, int $b):
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_hp_add, 0, 2, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, a, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, b, IS_LONG, 0)
ZEND_END_ARG_INFO()
---
3) 函数注册表(关键)
static const zend_function_entry hp_functions[] = {
PHP_FE(hp_hello, arginfo_hp_hello)
// PHP_FE(hp_add, arginfo_hp_add)
PHP_FE_END
};
PHP_FE 就是把 “PHP 函数名 -> C 函数指针 + 参数签名” 绑定进 Zend 函数表。
---
4) 模块入口(关键)
zend_module_entry hp_module_entry = {
STANDARD_MODULE_HEADER,
"hp", // 扩展名
hp_functions, // 注册函数表
PHP_MINIT(hp), // 模块初始化
NULL, // MSHUTDOWN
NULL, // RINIT
NULL, // RSHUTDOWN
PHP_MINFO(hp), // phpinfo
"1.0.0",
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_HP
ZEND_GET_MODULE(hp)
#endif
MINIT 负责模块级初始化(类注册、常量注册、INI 注册等)。
---
5) config.m4(构建入口)
PHP_ARG_ENABLE(hp, whether to enable hp extension,
[ --enable-hp Enable hp extension], no)
if test "$PHP_HP" != "no"; then
PHP_NEW_EXTENSION(hp, hp.c, $ext_shared)
fi
---
6) 完整最小 hp.c 示例
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "ext/standard/info.h"
PHP_FUNCTION(hp_hello)
{
RETURN_STRING("hello hp");
}
ZEND_BEGIN_ARG_INFO_EX(arginfo_hp_hello, 0, 0, 0)
ZEND_END_ARG_INFO()
static const zend_function_entry hp_functions[] = {
PHP_FE(hp_hello, arginfo_hp_hello)
PHP_FE_END
};
PHP_MINIT_FUNCTION(hp)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(hp)
{
php_info_print_table_start();
php_info_print_table_row(2, "hp support", "enabled");
php_info_print_table_end();
}
zend_module_entry hp_module_entry = {
STANDARD_MODULE_HEADER,
"hp",
hp_functions,
PHP_MINIT(hp),
NULL,
NULL,
NULL,
PHP_MINFO(hp),
"1.0.0",
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_HP
ZEND_GET_MODULE(hp)
#endif
---
7) 编译方式
静态内置(进 PHP 二进制):
./buildconf --force
./configure --enable-hp ...
make -j"$(nproc)"
make install
动态 so:
phpize
./configure --enable-hp=shared
make -j"$(nproc)"
make install
---
8) 验证
php -m | grep -i hp
php -r 'var_dump(function_exists("hp_hello")); echo hp_hello(), PHP_EOL;'
---
一句话记忆版:
真正“注册”发生在 hp_functions 挂到 zend_module_entry 这一步,Zend 在模块加载时把这张表塞进全局函数表,PHP
层就能直接调用了。
更多推荐



所有评论(0)