- 生成扩展
./ext_skel --extname=inis
- config.m4
PHP_ARG_ENABLE(inis, whether to enable inis support,
[ --enable-inis Enable inis support])
if test "$PHP_INIS" != "no"; then
PHP_NEW_EXTENSION(inis, inis.c, $ext_shared)
fi
- php_inis.h
ZEND_BEGIN_MODULE_GLOBALS(inis)
char *name;
long level;
ZEND_END_MODULE_GLOBALS(inis)
#ifdef ZTS
#define INIS_G(v) TSRMG(inis_globals_id, zend_inis_globals *, v)
#else
#define INIS_G(v) (inis_globals.v)
#endif
- inis.c
定义全局变量
ZEND_DECLARE_MODULE_GLOBALS(inis)
设置INI参数
PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("inis.name","sunzy",PHP_INI_ALL,OnUpdateString,name,zend_inis_globals,inis_globals)
STD_PHP_INI_ENTRY("inis.level","1",PHP_INI_ALL,OnUpdateLong,level,zend_inis_globals,inis_globals)
PHP_INI_END()
初始化函数
static void php_inis_init_globals(zend_inis_globals *inis_globals)
{
inis_globals->name="sunzy.org";
inis_globals->level=10;
}
注册&清除INI变量
PHP_MINIT_FUNCTION(inis)
{
REGISTER_INI_ENTRIES();
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(inis)
{
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
自定义函数
PHP_FUNCTION(inis_report)
{
php_printf("Name:%s\n",INIS_G(name));
php_printf("Level:%d\n",INIS_G(level));
}
注册自定义函数
const zend_function_entry inis_functions[] = {
PHP_FE(inis_report,NULL)
PHP_FE_END /* Must be the last line in inis_functions[] */
};
- 测试
测试脚本
$function = "inis_report";
call_user_func($function);
测试
$ /usr/local/php5.6.9/bin/php -q inis.php
Functions available in the test extension:
inis_report
Name:sunzy
Level:1
修改php.ini
inis.name=test
inis.level=2
$ /usr/local/php5.6.9/bin/php -q inis.php
Functions available in the test extension:
inis_report
Name:test
Level:2
- ZEND_DECLARE_MODULE_GLOBALS ->Zend/zend_API.h
#ifdef ZTS
#define ZEND_DECLARE_MODULE_GLOBALS(module_name) \
ts_rsrc_id module_name##_globals_id;
#else
#define ZEND_DECLARE_MODULE_GLOBALS(module_name) \
zend_##module_name##_globals module_name##_globals;
#endif
ts_rsrc_id
是线程安全里的内容
- PHP_INI_BEGIN、PHP_INI_END、STD_PHP_INI_ENTRY ->main/php_ini.h
#define PHP_INI_BEGIN ZEND_INI_BEGIN
#define PHP_INI_END ZEND_INI_END
#define STD_PHP_INI_ENTRY STD_ZEND_INI_ENTRY
- ZEND_INI_BEGIN、ZEND_INI_END、STD_ZEND_INI_ENTRY -> Zend/zend_ini.h
#define ZEND_INI_BEGIN() static const zend_ini_entry ini_entries[] = {
#define ZEND_INI_END() { 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL } };
#define ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, displayer) \
{ 0, modifiable, name, sizeof(name), on_modify, arg1, arg2, arg3, default_value, sizeof(default_value)-1, NULL, 0, 0, 0, displayer },
#define ZEND_INI_ENTRY3(name, default_value, modifiable, on_modify, arg1, arg2, arg3) \
ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, NULL)
#define ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, arg1, arg2, displayer) \
ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, NULL, displayer)
#define ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, arg1, arg2) \
ZEND_INI_ENTRY2_EX(name, default_value, modifiable, on_modify, arg1, arg2, NULL)
#ifdef ZTS
#define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr##_id)
#else
#define STD_ZEND_INI_ENTRY(name, default_value, modifiable, on_modify, property_name, struct_type, struct_ptr) \
ZEND_INI_ENTRY2(name, default_value, modifiable, on_modify, (void *) XtOffsetOf(struct_type, property_name), (void *) &struct_ptr)
#endif
前面扩展中对ini变量的定义展开后
static const zend_ini_entry ini_entries[] = {//BEGIN
{0, PHP_INI_ALL, "inis.enable", sizeof("inis.enable"), OnUpdateBool, enable, zend_inis_globals, inis_globals... }//inis.enable定义
...
{ 0, 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 0, NULL } //END
};
- REGISTER_INI_ENTRIES、UNREGISTER_INI_ENTRIES ->Zend/zend_ini.h
#define REGISTER_INI_ENTRIES() zend_register_ini_entries(ini_entries, module_number TSRMLS_CC) //注册ini变量
#define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries(module_number TSRMLS_CC) //清除ini变量
#define DISPLAY_INI_ENTRIES() display_ini_entries(zend_module) //在phpinfo中显示变量值
- ZEND_INIT_MODULE_GLOBALS ->Zend/zend_ini.h
#ifdef ZTS
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \
ts_allocate_id(&module_name##_globals_id, sizeof(zend_##module_name##_globals), (ts_allocate_ctor) globals_ctor, (ts_allocate_dtor) globals_dtor);
#else
#define ZEND_INIT_MODULE_GLOBALS(module_name, globals_ctor, globals_dtor) \
globals_ctor(&module_name##_globals);
#endif
初始化ini值的宏
module_name 与传递给ZEND_BEGIN_MODULE_GLOBALS()宏相同的扩展名称。
globals_ctor 构造函数指针。在myfile扩展里,函数原形与void php_myfile_init_globals(zend_myfile_globals *myfile_globals)类似
globals_dtor 析构函数指针。例如,php_myfile_init_globals(zend_myfile_globals *myfile_globals)