thinkphp51 - 如何精简配置文件,并使其具有可移植性

324 阅读2分钟

用过tp的都知道,一般用tp的php格式的配置文件,说白了就是数组,但这个php配置文件本事大了,你可以欢快的在这个文件写符合tp的规范代码,拾取了app配置文件的一段代码:

// 默认跳转页面对应的模板文件
'dispatch_success_tmpl'  => Env::get('think_path') . 'tpl/dispatch_jump.tpl',
'dispatch_error_tmpl'    => Env::get('think_path') . 'tpl/dispatch_jump.tpl',

// 异常页面的模板文件
'exception_tmpl'         => Env::get('think_path') . 'tpl/think_exception.tpl',

咋一看Env::get('think_path')什么鬼?是的,tp就是如此强大,强大到可移植性差到极致。
现在需求来了,某类应用需要用多种语言实现,比如短信应用,tp实现一份,java实现一份,go再实现一份;部署的时候不可能维护三种格式的配置文件吧。我们规定,统一用ini。我看下tp51如何实现:

思路一:通过env将php配置文件改为加载ini配置文件

在应用根目录的.env

CONFIG_EXT=".ini"

这也是官方给出吃奶的方法,但我就想问下ini能带有Env::get('think_path')吗?遇到这种需求怎么配置?我们说可以指配置php和ini同时存在,比如app.php和app.ini,然后ini优先,想象是美好的,官方并没有给出这样的逻辑,真是搬石头砸脚了,这招不行。

思路二:把php大配置中,我们所需要的一部分,配置到env上去,然后通过Env::get获取:

# .env文件
[DATABASE]
USERNAME =  root
PASSWORD =  123456

然后在应用中,通过以下获取

Env::get('database.username');
Env::get('database.password');

那么问题来了,我原来读取配置方法,现在全部要更换,并且在某些情况下还要动态配置,要知道动态配置是很危险的操作,并且有些配置调用写法在tp核心文件中已经集成,弄不好还要改核心,尽量不这么干。

最终,我们采用的如下方案

# .env文件,这里就是经常变动的配置,可以摘取php配置变量的某些,并没有把所有的配置都放到里边
[database]
username =  root
password =  123456

[cache]
type=redis
host=172.17.0.1
port=6379
password=111111
persistent=true
prefix=redis_

以上ini配置内容摘自以下php配置文件

# database.php 配置文件(简略)
 // 用户名
'username'        => Env::get('database.username'),
// 密码
'password'        => Env::get('database.password'),
# cache.php 配置文件(完整)
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | 缓存设置
// +----------------------------------------------------------------------

return [
    /*
    // 驱动方式
    'type'   => 'File',
    // 缓存保存目录
    'path'   => '',
    // 缓存前缀
    'prefix' => '',
    // 缓存有效期 0表示永久缓存
    'expire' => 0,
    */
    'type'=>env('cache.type'),
    'host'       => env('cache.host'),
    'port'       => env('cache.port'),
    'password'   => '',
    'select'     => 0,
    'timeout'    => 0,
    'expire'     => 0,
    'persistent' => true,
    'prefix'     =>  env('cache.prefix'),
    /*'serialize'  => true,*/
];

如此,你的.env如一条小虫可以自由地穿梭各个应用了。