_Experience by itself teaches nothing... Without theory, experience has no meaning. Without theory, one has no questions to ask. Hence, without theory, there is no learning. – Edwards Deming_
##1.16.1 配置的简单读取
通常,我们会有以下三个配置文件:
```javascript
dogstar@ubuntu:Config$ tree
.
├── app.php
├── dbs.php
└── sys.php
```
其中app.php为项目应用配置;dbs.php为分布式存储的数据库配置;sys.php为不同环境下的系统配置。
在入口文件,注册配置组件服务后:
```javascript
//$ vim ./Public/init.php
//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');
```
假设有这样的app.php配置:
```javascript
return array(
'version' => '1.1.1',
'email' => array(
'address' => 'chanzonghuang@gmail.com',
);
);
```
我们就可以分别这样根据需要获取配置:
```javascript
//app.php里面的全部配置
DI()->config->get('app');
//app.php里面的单个配置
DI()->config->get('app.version'); //返回:1.1.1
//app.php里面的多级配置
DI()->config->get('app.email'); //返回:array('address' => 'chanzonghuang@gmail.com')
```
其他配置文件类似,你也可以随意添加新的配置文件。
##1.16.2 内外环境配置管理的策略
可以说,在项目开发中,除了我们的代码、数据和文档外,配置也是一块相当重要的组成部分,而且占据着非常重要的位置。最为明显的是,如果配置一旦出错,就很可能影响到整个系统的运行,并且远比修改代码再上线发布速度快(假设我们不用文件存储配置而是以分布式存储在各服务器内存中)。
但这里将讨论另外一个同样重要的问题,即: **不同环境下不同配置的管理和切换** 。
现在将不同的策略分说如下。
###(1)支持整包发布的环境变量配置
此种策略的主要方法就是在PHP代码中读取php-fpm中的ENV环境配置,再对应到linux环境下的profile环境变量,即:
```
PHP代码 --> $_ENV环境配置 --> Linux服务器环境变量/etc/profile
```
这样的好处莫过于可以支持项目代码的整包发布,而不需要在各个环境(开发环境、测试环境、回归环境、预发布环境、生产环境)来回修改切换配置,同时运维可以更好地保护服务器的账号和密码而不让开发知道。
而这样的不足则是,在对项目进行初次部署时,需要添加以上一系列的配置,而且后期维护也比较复杂麻烦,特别当机器多时。这时可以通过pupple/stacksalt这些运维工具进行自动化管理。但对于开发来说,依然会觉得有点烦锁。
###(2)不同环境,不同入口
当服务器的账号和密码也是由开发来掌控时,则可以使用这种在代码层次控制的策略。
我们可以在Public下提供不同的入口,一如:
```javascript
$ mkdir ./Public/myapi
$ myapi$ tree
.
├── index.php
└── test.php
```
我们有这样不同的入口,客户端在测试时,只需要将入口路径改成:/myapi/test.php?service=XXX.XXX,而在打包发布时只需要将入口路径改成:/myapi/?service=XXX.XXX 即可。也就是将test.php去掉。
而在服务端,仅需要在这些不同的入口文件,修改一下配置文件目录路径即可:
```javascript
//$ vim ./Public/myapi/test.php
DI()->config = new PhalApi_Config_File(API_ROOT . '/ConfigTest');
```
另外,也可以通过客户端在请求时带参数来作区分,如带上&env=test或者&env=prod。
###(3)持续集成下的配置管理
但个人最为建议的还是在 **持续集成** 下作配置管理。
因为首先,持续集成中的发布应该是经常性的,且应该是自动化的。所以,既然有自动化的支持,我们也应该及早地将配置纳入其中管理。
配置文件不同只要是环境不同,而环境不同所影响的配置文件通常只有sys.php和dbs.php;为此,我们为测试环境和生产环境准备了各自的配置文件,而在发布时自动选择所需要的配置文件。一般地,我们建议生产环境的配置文件以 **.prod** 结尾。所以,这时我们的配置文件可能会是这样:
```javascript
dogstar@ubuntu:Config$ tree
.
├── app.php
├── dbs.php
├── dbs.php.prod
├── sys.php
└── sys.php.prod
```
多了生产环境的配置文件:dbs.php.prod和sys.php.prod。
再通过发布工具,我们就可以对不同环境的配置文件进行快速选择了。这里以phing为例,说明一下相关的配置和效果。
如下,在Phing的配置文件build.xml中,在生产环境发布过程中,我们将配置文件进行了替换。
```javascript
//$ vim ./build.xml
<copy
file="./Config/dbs.php.prod"
tofile="./Config/dbs.php"
overwrite="true" />
<copy
file="./Config/sys.php.prod"
tofile="./Config/sys.php"
overwrite="true" />
```
执行phing发布后,将会看到对应的这样提示:
```javascript
[copy] Copying 1 file to /home/phapapi/Config
[copy] Copying 1 file to /home/phapapi/Config
```
##1.16.3 主从数据库的配置
通常一般而言,数据库支持分表分库配置,且只有一份,即:
```javascript
./Config/dbs.php
```
然后,我们这样指定数据库的配置:
```javascript
DI()->notorm = function() {
$debug = !empty($_GET['__sql__']) ? true : false;
return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug);
};
```
如果需要从库时,要以参考./Config/dbs.php,创建一个从库的配置拷贝,即:
```javascript
cp ./Config/dbs.php ./Config/dbs_slave.php
```
然后,注册一个从库的notorm:
```javascript
DI()->notormSlave = function() {
$debug = !empty($_GET['__sql__']) ? true : false;
return new PhalApi_DB_NotORM(DI()->config->get('dbs_slave'), $debug); //注意:配置不同
};
```
最后使用此从库的服务DI()->notormSlave即可完成对从库的读取操作,用法同DI()->notorm,这里不再赘述。
##1.16.4 扩展你的配置读取
虽然上面有不同的配置文件管理策略,但很多实际情况下,我们的配置需要可以随时更改、下发和调整。并且在海量访问,性能要求高的情况下快速读取配置。
这就要求我们的项目既可以方便维护即时修改,又需要能够快速同步一致更新下发和读取。这样就涉及到了配置更高层的管理: 统一集中式的配置管理,还是分布式的配置管理? 文件存储,还是DB存储,还是MC缓存,还是进驻内存?
个人认为,性能最优的莫过于配置进驻内存并分布式存储。毕竟作为前端机的PHP内存这块还是相对充裕且可以利用的。但需要把这一条线打通,有点难度。
这里不过多地谈论配置更多的内容,但在PhalApi框架中,当你根据自己项目的需要实现了自己的配置读取方式后,再次简单的在入口文件重新注册即可。
##1.16.5 使用Yaconf扩展快速读取配置
首先,非常感谢 @豹 同学的提议:使用Yaconf扩展快速读取配置。
虽然现在是冬天,有点冷(特别是在北京的同学),而且现在还是凌晨1点25分。但我们希望能继续将开源的热情继续下去。
以下是刚刚这几个小时努力的成果。
###(1)前期准备:PHP7 的安装
具体可以参考:[Linux环境PHP7.0安装 ](http://blog.csdn.net/21aspnet/article/details/47708763)
###(2)前期准备:Yaconf扩展的安装
具体可以参考:[laruence/yaconf](https://github.com/laruence/yaconf)
###(3)使用
和正常的配置一样,简单如下:
```
DI()->config = new PhalApi_Config_Yaconf();
var_dump(DI()->config->get('foo')); //相当于var_dump(Yaconf::get("foo"));
var_dump(DI()->config->has('foo')); //相当于var_dump(Yaconf::has("foo"));
```
以上,假设我们已经有了这样的配置文件:
```
$ vim ./test.ini
name="PhalApi"
version="1.3.1"
```
需要注意的是,如果需要使用Yaconf扩展,需要PHP7的版本支持,但使用基本上和原来PhalApi的思路是完全一样的。
但还有所区别的是,配置文件的目录路径(当然也可以配置成和PhalApi的配置目录一致)、以及配置文件的格式。
Just have fun!
- 欢迎使用PhalApi!
- 接口,从简单开始!
- [1.1]-下载与安装
- [1.2]-创建一个自己的项目
- [1.3]-在线体验
- [1.4]-文档、帮助和官网
- [1.10]-对PhalApi框架的抉择
- [1.11]-快速入门(backup)
- [1.12]-参数规则:接口参数规则配置
- [1.13]-统一的接口请求方式:_sevice=XXX.XXX
- [1.14]-统一的返回格式和结构:ret-data-msg
- [1.15]-数据库操作:基于NotORM的使用及优化
- [1.16]-配置读取:内外网环境配置的完美切换
- [1.17]-日记纪录:简化版的日记接口
- [1.18]-快速函数:人性化的关怀
- [1.19]-DI服务速查:各资源服务一览表
- [1.20]-DB操作:数据库基本操作速查
- [1.21]-类的自动加载:遵循PEAR包的命名规范
- [1.22]-签名验证:自定义签名规则
- [1.23]-请求和响应:GET和POST两者皆可得及超越JSON格式返回
- [1.24]-缓存策略:更灵活地可配置化的多级缓存
- [1.25]-国际化翻译:为走向国际化提前做好翻译准备
- [1.26]-数据安全:数据对称加密方案
- [1.27]-精益开发:更富表现力的Model层和重量级数据获取的应对方案
- [1.28]-COOKIE:对COOKIE原生态的支持及记忆加密升级版
- [1.29]-开放与封闭:多入口和统一初始化
- [1.30]-保持的力量:接口开发最佳实践
- [1.31]-新型计划任务:以接口形式实现的计划任务
- [2.11]-核心思想:DI依赖注入-让资源更可控
- [2.12]-海量数据:可配置的分库分表
- [2.13]-接口调试:在线SQL语句查看与性能优化
- [2.14]-测试驱动开发:意图导向编程下的接口开发
- [2.15]-演进:新型计划任务续篇
- [2.16]-领域驱动设计:应对复杂领域业务的Domain层
- [2.17]-微服务:Api接口服务层
- [2.18]-定制化:资源服务的再实现
- [2.19]-扩展库:可重用的扩展类库
- [2.20]-约定编程:架构明显的编程风格
- [2.21]-服务器统一部署方案简明版:CentOs---Nginx---php-fpm---MySql-[--Memcached]
- [2.22]-更多工具:精益项目和团队建设
- [3.1]-扩展类库:微信开发
- [3.2]-扩展类库:代理模式下phprpc协议的轻松支持
- [3.3]-扩展类库:基于PHPMailer的邮件发送
- [3.4]-扩展类库:优酷开放平台接口调用
- [3.5]-扩展类库:七牛云存储接口调用
- [3.6]-扩展类库:新型计划任务
- [3.8]-扩展类库:用户、会话和第三方登录集成
- [3.9]-扩展类库:swoole支持下的长链接和异步任务实现
- [3.11]-扩展类库:基于FastRoute的快速路由
- [4.2]-开发实战2:模拟优酷开放平台接口项目开发
- [4.3]-开发实战3:一个简单的小型项目开发(奔跑吧兄弟投票活动)
- [5.1]-架构与思想:PhalApi核心设计和思想解读
- [5.2]-杂谈:扯一些PhalApi的前世和今生
- [5.3]-框架总结:术语表和PHP开发建议
- [5.4]-许可
- [5.5]-联系和加入我们
- [5.6]-更新日记
- [5.8]-致框架贡献者:加入PhalApi开源指南
- [6.1]-基于接口查询语言的SDK包
- [6.2]-SDK包(JAVA版)
- [6.3]-SDK包(PHP版)
- [6.4]-SDK包(Objective-C版)
- [6.5]-SDK包(javascript版)
- [6.6]-SDK包(Ruby版)
- [8.1]-PhalApi视频教程
- 附录1:接口文档参考模板