在开发PHP扩展时,有时候我们需要访问php.ini文件,本文通过一个例子介绍如何在PHP扩展中访问INI设置项。首先打开php_fetion_echo.h头文件(快速入门篇中的例子),在里面加上函数声明:
PHP_FUNCTION(say_hello);
在fetion_echo.c文件中,加入下面代码:
PHP_INI_BEGIN() PHP_INI_ENTRY("hello_greeting", "Hello World!", PHP_INI_ALL, NULL) PHP_INI_END()
此处使用PHP_INI_BEGIN宏定义开始INI项配置节,用PHP_INI_END宏定义结束配置节,每一个INI设置项都用PHP_INI_ENTRY宏进行定义:
第一个参数指定INI配置项名称,为了避免命名冲突,建议使用扩展名 + 自定义配置项名,如hello_greeting。
第二个参数是配置项的初始值,无论INI条目是数值还是字符串值,都需要传递一个相应的字符串值。这归因于.ini 文件本身的文本性。当你在代码中使用 INI_INT(), INI_FLT(), INI_BOOL()的时候,它们会自动进行类型转换。
第三个参数是配置项权限修饰符,即指定配置项在何时可以被修改,PHP_INI_SYSTEM只允许在php.ini中改变这些 值;PHP_INI_USER允许用户在运行时通过像 .htaccess 这样的附加文件来重写其值;而PHP_INI_ALL则允许随意更改。
第四个参数是初始值被改变时接收通知的函数句柄。一旦某个初始值被改变,那么相应的函数就会被调用。这个函数我们可以用宏 PHP_INI_MH 来定义,如:
PHP_INI_MH(OnChanged)
{
// 这里可以访问newvalue
}
改变后的新值将会以字符串的形式并通过一个名为 new_value 变量传递给函数。要是再注意一下 PHP_INI_MH 的定义就会发现,我们实际上用到了不少参数:
#define PHP_INI_MH(name) int name( php_ini_entry *entry, char *new_value, uint new_value_length, void *mh_arg1, void *mh_arg2, void *mh_arg3 )
我们的通知接收函数可以访问整个配置项、改变后的新值以及它的长度和其他三个可选参数。这几个可选参数可以通过 PHP_INI_ENTRY1(携带一个附加参数)、PHP_INI_ENTRY2(携带两个附加参数)、PHP_INI_ENTRY3(携带三个附加参 数)等宏来加以指定。
除此之外,我们还需要对配置节进行初始化,这项工作可以在PHP扩展和销毁函数中完成:
PHP_MINIT_FUNCTION(fetion_echo) { REGISTER_INI_ENTRIES(); return SUCCESS; } PHP_MSHUTDOWN_FUNCTION(fetion_echo) { UNREGISTER_INI_ENTRIES(); return SUCCESS; }
接下来编写我们的扩展函数,读取配置项的值并作为函数返回值:
PHP_FUNCTION(say_hello) { RETURN_STRING(INI_STR("hello_greeting"), 1); }
此处我们使用了INI_STR宏定义读取字符串的值,关于配置项的读取宏有如下几个:
INI_INT(name) | 将配置项 name 的当前值以长整数返回 |
INI_FLT(name) | 将配置项 name 的当前值以双精度浮点数返回 |
INI_STR(name) | 将配置项 name 的当前值以字符串返回。 注意:这个字符串不是复制过的字符串,而是直接指向了内部数据。如果你需要进行进一步的访问的话,那就需要再进行复制一下 |
INI_BOOL(name) | 将配置项 name 的当前值以布尔值返回 |
INI_ORIG_INT(name) | 将配置项 name 的初始值以长整型数返回 |
INI_ORIG_FLT(name) | 将配置项 name 的初始值以双精度浮点数返回 |
INI_ORIG_STR(name) | 将配置项 name 的初始值以字符串返回。 注意:这个字符串不是复制过的字符串,而是直接指向了内部数据。如果你需要进行进一步的访问的话,那就需要再进行复制一下 |
INI_ORIG_BOOL(name) | 将配置项 name 的初始值以布尔值返回 |
最后我们注册扩展函数到函数表中:
const zend_function_entry fetion_echo_functions[] = {
PHP_FE(say_goodbye, NULL)
PHP_FE(say_hello, NULL)
{NULL, NULL, NULL}
};
编写一个简单的测试脚本:
<?php echo say_goodbye("Foo"); echo '<br/>'; echo say_hello(); ?>
运行后效果如下:
此时值为初始值,因为我们没有在别的地方修改配置项的值,如果在php.ini文件里加上一项,修改hello_greeting的值:
hello_greeting = "Hello, Terrylee!"
运行后效果如下:
关于PHP扩展开发中对于初始化文件的访问就介绍到这里。