Php7中如何获取ini配置?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Php7中如何获取ini配置?相关的知识,希望对你有一定的参考价值。

本文和大家分享的主要是php7的扩展声明与ini配置获取相关内容,一起来看看吧,希望对大家学习php有所帮助。

今天在开发PHP扩展中遇到了获取ini配置的需求,采用如下的方法获取发现得到的是空值:

static inline String ini_get(String varname){

char *value = zend_ini_string((char *) varname.c_str(), (uint) varname.length(), 0);

if (!value)

{

return "";

}

return value;

}

ini文件中我是这样配置的:

[catx]

catx.abc = "hello"

经过谷歌搜索,发现了 这篇博客 介绍了INI的使用方式,发现ini是需要先声明才能获取的。

通常的用法,是先通过下面的宏定义一个INI数组:

ZEND_INI_BEGIN()

ZEND_INI_ENTRY("catx.abc", "hi", PHP_INI_ALL, NULL)ZEND_INI_END()

通过查看Zend源码,其对应展开如下:

#define ZEND_INI_BEGIN()                static const zend_ini_entry_def ini_entries[] = {

#define ZEND_INI_ENTRY(name, default_value, modifiable, on_modify) \

ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, NULL)

#define ZEND_INI_ENTRY_EX(name, default_value, modifiable, on_modify, displayer) \

ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, NULL, NULL, NULL, displayer)

#define ZEND_INI_ENTRY3_EX(name, default_value, modifiable, on_modify, arg1, arg2, arg3, displayer) \

{ name, on_modify, arg1, arg2, arg3, default_value, displayer, modifiable, sizeof(name)-1, sizeof(default_value)-1 },

#define ZEND_INI_END()          { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0} };

其实就是定义了一个zend_ini_entry_def的数组,其名字固定叫做ini_entries,里面每一项是要注册的INI配置。

上面的宏定义,无论你是在函数里还是全局作用域定义都是可以的,但是还需要主动注册到zend里去,通常用下面的2个宏来搞定:

#define REGISTER_INI_ENTRIES() zend_register_ini_entries(ini_entries, module_number)

#define UNREGISTER_INI_ENTRIES() zend_unregister_ini_entries(module_number)

上述宏默认就会找ini_entries变量传进去,第二个参数module_number你可以在扩展的MINITMSHUTDOWN两个函数的回调参数里得到,所以REGISTER_INI_ENTRIES要在MINIT里调用,后者在MSHUTDOWN里调用用于销毁注册的INI配置。

再就是关注一下zend_ini_entry_def的定义:

typedef struct _zend_ini_entry_def {

const char *name;

ZEND_INI_MH((*on_modify));

void *mh_arg1;

void *mh_arg2;

void *mh_arg3;

const char *value;

void (*displayer)(zend_ini_entry *ini_entry, int type);

int modifiable;

uint name_length;

uint value_length;

} zend_ini_entry_def;

nameini配置的keyvalue是默认值(也就是ini里没配置时候的值),mh_arg1-3是用户可以指定的上下文参数(主要是用来displayeron_modify回调时候提供上下文),modifiable是限制是否可以通过ini_set来修改ini配置,name_lengthname的长度,value_lengthvalue的长度。

on_modifydisplayer没必要用,通过php代码ini_set修改变量可以直接反应到zend_ini_string的结果中,这些回调函数只是给你一个主动通知机制,一般是用不到的。

因为 PHP-X项目 C++封装的Zend api,所以没法直接用上面的宏来搞定这些事情,因此需要绕过宏直接与Zend api交互:

// INI

struct IniEntry {

std::string name;

std::string default_value;

int modifiable;

};

// modifiable can be one of these:PHP_INI_SYSTEM/PHP_INI_PERDIR/PHP_INI_USER/PHP_INI_ALL

void addIniEntry(const char* name, const char* default_value = "", int modifiable = PHP_INI_ALL)

{

IniEntry entry;

entry.name = name;

entry.default_value = default_value;

entry.modifiable = modifiable;

ini_entries.push_back(entry);

}

protected:

std::vectorini_entries;

通过上述接口,允许用户添加若干ini配置,当MINIT回调的时候一股脑给它注册上去:

void Extension::registerIniEntries(int module_number) {

if (!ini_entries.size()) {

return;

}

zend_ini_entry_def* entry_defs = new zend_ini_entry_def[ini_entries.size() + 1];

for (auto i = 0; i < ini_entries.size(); ++i) {

IniEntry& entry = ini_entries[i];

zend_ini_entry_def def = {

entry.name.c_str(), // name

NULL,   // on_modify

NULL,   // mh_arg1

NULL,   // mh_arg2

NULL,   // mh_arg3

entry.default_value.c_str(), // value

NULL,   // displayer

entry.modifiable, // modifiable

(uint)entry.name.size(), // name_length

(uint)entry.default_value.size(), // value_length

};

entry_defs[i] = def;

}

memset(entry_defs + ini_entries.size(), 0, sizeof(*entry_defs));

zend_register_ini_entries(entry_defs, module_number);

delete []entry_defs;

}

MSHUTDOWN的时候一键卸载:

void Extension::unregisterIniEntries(int module_number) {

if (ini_entries.size()) {

zend_unregister_ini_entries(module_number);

}

}

这样就搞定ini~

 

来源:鱼儿的博客

以上是关于Php7中如何获取ini配置?的主要内容,如果未能解决你的问题,请参考以下文章

pytestconfig--获取命令行参数及pytest.ini文件配置

中兴机顶盒现场配置工具读取配置信息获取所有ini配置文件失败

如何在 shell 脚本中获取 INI 值?

C/C++ 关于如何读写ini配置文件 (小结)

如何升级php版本

php如何修改ini文件