如何制作一个php网站源码,腾冲住房和城乡建设局网站,互联网信息服务业务经营许可证,企业建站电话多少用 JSON 保存后台配置数据 在前台数据交换中#xff0c;优其 web应用领域#xff0c;JSON以其简单性和可扩展性“大有替代”xml 之势#xff08;夸张地说#xff09;。本文简单介绍了 json 作为配置的存取在后台操作的便利性#xff0c;希望本文能抛砖引玉#xff0c;让J…用 JSON 保存后台配置数据 在前台数据交换中优其 web应用领域JSON以其简单性和可扩展性“大有替代”xml 之势夸张地说。本文简单介绍了 json 作为配置的存取在后台操作的便利性希望本文能抛砖引玉让JSON给大家后台配置存取提供更多便利。 编辑器: JSON 在线编辑器 JsonEditor V1.03.2 在一些中/小型应用程序中配置文件是必须的。采用什么格式的配置文件一直困扰着很多开发人员。实践中常用的有四种类型1 采用 c/c 的结构体存储。 虽然很原始便还是在很多场景可以看到原因是免解析。缺点太多了比如不易扩展可读性差。
2采用 名称 值 的行存储或类似 windows 系统 ini 文件的格式。 通过 xxx_set/xxx_get 的方法进行存取. 在各种应用中都很常见优其小型嵌入式设备上很多时候配置采用类似的方法。
3采用相对复杂的分段/分级配置。 如 Apache/Ngix 等的配置文件再如 cisco 的 consle 配置。优点时文本方式便于编辑有良好的结构性。 缺点解析起来相对复杂需要为应用定制配置格式。
4采用 xml 格式保存配置。 在大型应用优其 java.net 的项目中应用的优其多。原因是平台或操作语言提供了 xml 的操作 API。 在小型 c/c 程序中 如果你有 DOM/XML 的操作 API 依然是是可行的。 最近在一些小型项目的实践中 保存配置文件我是越来越倾向于使用 JSON 了。原因是 1 JSON 像 XML 一样有的良好结构性。
2 JSON 固有的数据类型 object/string/number/true/false 意义明确便于表达.
3 JSON 语法简单解析器易实现同时便于解析和格式化输出。JSON的官方站点上有各种语言的解析器
4 配置层次性好最近又修改了一个开源 JSON 树型 编辑器。用工具编辑配置文件感觉很省事。 说了这多 还未到正文。下来用示例来说明下吧。后文件示例以 c 代码作为伪代码展示。假设你已经有如下 JSON 的操作 API 如果没有可以很容易自己实现封装
1) json_t /*json 类型 */
2) json_t * json_parse_string(const char * json_string); /* 解析 json 树 */3) const char * json_get_name(json_t * json, const char * path); /* 获取节点名 */4) const char * json_get_str(json_t * json, const char * path); /* 获取节点值string 类型 */5) const char * json_get_int(json_t * json, const char * path); /* 获取节点值int 类型 */6) FOREACH_IN_JSON_CHILD(json, path, pchild) /* 宏用于遍历子节点 */ 以下为假想配置示例:
{
Root:F:/website/doc,
Connection:{
maxconnects:1500,
maxkeepalive:0,
keeptimeout:15,
},
Listen:[{
ip:0.0.0.0,
port:8088,
protocol:http,
maxlisten:100
},
{
ip:127.0.0.1,
port:8090,
protocol:http,
maxlisten:100
}],
Directory:{
/app/:{
path:F:/website/doc,
RewriteRule:[{
from:,
to:{}
},
{
from:,
to:{}
}]
},
/libso/:{
path:E:/eybuild/lib6/app/,
RewriteRule:[{
from:,
to:{}
},
{
from:,
to:{}
}]
},
}
},
DAction:[
/libso/*.so,
/libso/*.dll,
/dll/*.dll],
SAction:[
/app/**,
/bbr/,
/cplus/],
Log:{
Logfile:c:/log/log.log,
Loglevel:5
}
}
1 加载配置文件解析成 JSON 树. readfile(conf_buf, from_file); /*加载配置 */ json_t * jcon json_parse_string(conf_buf); 2遍历第一层配置。 json_t * jobj; FOREACH_IN_JSON_CHILD(jconf, , jobj) { const char * pname json_get_name(jobj)); const char * pvalue json_get_str(jobj); if (compare(Root, pname)) call_xxx_set_root(); /* 把值传给处理函数 */ else if (compare(Connection, pname)) call_xxx_set_connection(); /* 把值传给处理函数 */ else if (compare(Listen, pname)) call_xxx_set_listen(jobj); /* 把值传给处理函数 */ .... /* 其它节点 */ }
3对子节点进行处理以 Listen 数组下的结点为例。 从上面我们可以看到 Listen是个数组其下的节点数目是不确定的依然使用 foreach 的形式进行遍历. int call_xxx_set_lisen(json_t * jconf) { json_t * jobj; /* 从数组中取出一个节点 */ FOREACH_IN_JSON_CHILD(jconf, , jobj) { /* 对数组中的每一个原素 */ const char * ip json_get_name(jobj, ip)); short int port json_get_int(jobj, port); .... /* 这里加上应用该配置的函数 */ } } 4其它节点类似。 附示例代码:
static int load_conf_listen(EGHTTPD * phttpd, EBJSON * jconf)
{
EBJSON * jobj NULL;
EBJSON_FOREACH(jconf, Listen, jobj)
{
const char * ip ebJSONGetString(jobj, ip);
const short port ebJSONGetInt( jobj, port);
const char * protocol ebJSONGetString(jobj, protocol);
const int maxlisten ebJSONGetInt( jobj, maxlisten);
BOOL blhttps;
JSON_IGNORE_EMPTY_OBJ(jobj);
blhttps !strcmp(protocol, https);
if (NULL egHttpdAddListener(phttpd, ip, port, maxlisten, blhttps))
{
egHttpdLog(LOGLEVEL_ERROR, Add listener(%s: %hu: %s: %d) error!/n,
ip, port, protocol, maxlisten);
return ERROR;
}
egHttpdLog(LOGLEVEL_DEBUG, %s: %hu: %s: %d/n, ip, port, protocol, maxlisten);
}
return OK;
}
static int load_conf_directory(EGHTTPD * phttpd, EBJSON * jconf)
{
EBJSON * jobj NULL;
EBJSON * jval NULL;
EBJSON_FOREACH(jconf, Directory, jobj)
{
const char * vpath ebJSONGetName(jobj);
const char * rpath ebJSONGetString(jobj, path);
JSON_IGNORE_EMPTY_OBJ(jobj);
egHttpdLog(LOGLEVEL_DEBUG, %s: %s/n, vpath, rpath);
if (!strissp(vpath) !strissp(rpath))
{
int i 0;
if (OK ! egHttpdAddVirtualPath(phttpd, vpath, rpath))
{
egHttpdLog(LOGLEVEL_DEBUG, Add virtual path (%s) error!/n, vpath);
return ERROR;
}
EBJSON_FOREACH(jobj, RewriteRule, jval)
{
const char * from ebJSONGetString(jval, from);
const char * to ebJSONGetString(jval, to);
egHttpdLog(LOGLEVEL_DEBUG, Rule%d: %s %s/n, i, from, to);
JSON_IGNORE_EMPTY_OBJ(jobj);
if (!strissp(from) !strissp(to))
{
if (OK ! egHttpdAddRewriteRule(phttpd, vpath, from, to))
{
egHttpdLog(LOGLEVEL_ERROR, Set rewrite rule error: %s: %s %s/n,
vpath, from, to);
return ERROR;
}
}
}
}
}
return OK;
} 小结
JSON 的如下特性决定了 json 非常适合配置存储
1 JSON 具有良好的树型结构便于程序操作。
2 JSON 对像的值可以是一个普通对象也可以是一个“集合”或数组使用FOREACH_IN_JSON_CHILD()的形式对子节点遍历。
3 JSON 对象便于序列化成 string 存储/传递.
4 JSON 便于解析/格式化
5 因为天太晚了该睡了此处略去 nK 字吧, 呵呵