当前位置: 首页 > Linux

Yaconf-一个高性能的配置管理扩展

时间:2023-04-06 23:37:18 Linux

随着PHP7的发布,增加了很多类型的持久化支持,比如IS_IMMUTABLE_ARRAY,所以我在PHP7下重新开发了yaconf,开源方便大家使用。简介首先,让我谈谈这是干什么的。我看到很多项目都是用PHP文件来配置的。一个config目录下可能有十几个甚至几十个.php配置文件,里面有各种各样的数组,配置里也放了一些字典文件(比如中英文对照)。这导致配置文件的解析会消耗大量的性能(确实使用opcache可以更好,但实际上还是有一个执行的过程)。除了PHP,还有使用json和yaml的。一个共同的特点是这些配置的可读性比较差。此外,它们还需要被运行时解析。config目录经常和代码放在一起,首先存在安全隐患(经常有敏感信息),其次如果配置和代码属于同一个项目,会导致修改配置和上网的过程。一些资源配置文件,比如mysql/memcache的配置信息,应该对开发透明。运维可直接负责。但是如果放到代码里,运维要发起一些改动,也必须开发修改配置文件才能上线。因此,Yaconf就是为解决这些问题而生的工具。它使用单独的A配置目录(在yaconf.directory中指定),不带代码。它处理了PHP启动时所有要处理的配置,然后这些配置会常驻内存,伴随着PHP的生命周期。它避免了每次发出请求时都解析配置文件。所有的配置内容都是不可变的,可以借助Fork的COW减少内存占用,而且在访问配置的时候,几乎不需要内存拷贝,也不会有不必要的引用计数增减。最重要的是,配置目录和代码分离后,可以通过一个配置管理后台,实现对配置的统一管理。支持(对于非ZTS)配置变更重载,也就是说,配置有变化(建议使用mv而不是cp来改配置),不重启就重新加载(检测频率为由yaconf.check_delay控制)。支持丰富的配置类型,包括字符串、数组、sections、Sectional继承,也可以直接在配置中写入PHP常量和环境变量。最重要的是,它非常简单。APIYaconf只提供了两个方法,mixedYaconf::get(string$name,mixed$default=NULL)这个是获取一个配置,name就是配置的名字,一般如果你有一个ini文件叫foo.ini,那么如果$name使用foo会获取这个文件中的所有内容,并以数组的形式返回。default是配置不存在时返回的默认值。boolYaconf::has(string$name)这个是检测配置是否存在。yaconf配置项yaconf.directory配置文件目录,这个配置不能通过ini_set指定,因为它必须在PHP启动时确定。yaconf.check_delay多久(秒)检测一次文件变化,如果为0则不检测,也就是说如果为0时,文件变化只能通过重启PHP重新加载来完成配置格式。Yaconf使用ini文件作为配置文件。这是因为我一直认为ini是最合适的配置文件。键值格式清晰易读。简单配置写法如下(以下均假设ini文件名为test):foo="bar"phpversion=PHP_VERSIONenv=${HOME}如上所示,我们用引号表示一般配置。对于没有引用的,我们会尽量用PHP常量来解释,也就是说可以直接在配置中写PHP常量。另外可以看到,我们可以直接在配置中写环境变量,比如上面的env:Yaconf::get("test.env");//test是配置文件的名字//string(16)"/home/huixinchen"如上图可以看到,假设foo的值,可以通过下面的代码访问:yaconf::get("测试.foo");//test是配置文件名Yaconf也支持配置数组类型,写法如下:arr[]=1arr.1=2如上所示,可以直接使用foo[]形式来定义数组,即可也可以使用arr.1、arr.2来指定键定义。对于数组的第二个值,可以通过以下代码访问:Yaconf::get("test.arr.1");//test是配置文件名也可以通过获取整个arr数组来访问:$arr=Yaconf::get("test.arr");//吨est是配置文件的名字echo$arr[1];Yaconf也支持map类型配置,写法如下:map.foo=barmap.bar=foo;可以用分号写注释map2.foo.name=yaconfmap2.foo.year=2015map2的foo子图的name值可以通过下面的形式获取:Yaconf::get("test.map2.foo.name");//test是配置文件名,配置文件也可以分节,节继承:[parent]parent="base"children="NULL"[children:parent]children="children"请付费注意配置的sectioninheritancechildren的语法:(冒号)parent,表示childrensection继承所有基础配置项。那么您在与父节同名的子节中定义的配置将覆盖父节中定义的内容。children部分的children配置的值可以通过如下形式获取:Yaconf::get("test.children.children");//test是示例配置文件名首先,假设我们所有的配置文件都放在/tmp/yaconf中,那么我们需要在php.ini中添加如下配置:yaconf.directory=/tmp/yaconf这样,当yaconf启动PHP,会在这个目录下找到所有的.ini文件,然后尝试处理它们。这里需要注意的是,不支持多级目录,即yaconf只会处理yaconf.directory下的.ini文件,不会处理子目录下的(这个主要是为了简单考虑,因为有section,可以自己定义每个项目一个ini文件)。假设/tmp/yaconf有两个ini文件,分别是:foo.ininame="yaconf"year=2015features[]="fast"features.1="light"features.plus="zero-copy"features.constant=PHP_VERSIONbar.ini[base]parent="yaconf"children="NULL"[children:base]children="set"然后对于foo的内容:php7-r'var_dump(Yaconf::get("foo"));'/*array(3){["name"]=>string(6)"yaconf"["year"]=>string(4)"2015"["features"]=>array(4){[0]=>string(4)"fast"[1]=>string(5)"light"["plus"]=>string(9)"zero-copy"["constant"]=>string(9)"7.0.0-dev"}}*/对于bar的内容:php7-r'var_dump(Yaconf::get("bar"));'/*array(2){["base"]=>array(2){["parent"]=>string(6)"yaconf"["children"]=>string(4)"NULL"}["children"]=>array(2){["parent"]=>string(6)"yaconf"["children"]=>string(3)"set"}}*/Of当然,您可以使用(.)链接语法来精确访问任何特定值。终于,我的Ya系列扩展又增加了一个新成员,算上之前的Yaf(PHP框架)、Yar(PHPRPC框架)、Yac(PHP独立缓存),你可以轻松搭建一套高性能的LAMP应用方案.最后:Yaconf要求使用PHP7,今天发布了PHP7的alpha1版本,欢迎大家测试(关于alpha与否,只要你的项目不触发bug,那么对你,不是吗?)