_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:接口文檔參考模板