不同环境中,如何优雅的选择数据库配置文件

shwyshwy

前言

工作中,遇到线上和测试数据库分离的情况,起初,一开始都是在 config/database.php 下面修改的。在线上、测试服务器中在单独更改。每次,Git 提交的时候还要专门忽略database.php 在提交,非常的麻烦。于是,就是如下。

首先

config/database.php 入手,这里新建两个数据库配置数组,比如:

//测试数据库地址
$db['test'] = array(
    'dsn'	=> '',
    'hostname' => '测试地址',
    'use'save_queries' => TRUE,
     // 以下其他配置省略
);

// 正式数据库地址
$db['production'] = array(
    'dsn'	=> '',
    'hostname' => '正式地址',
    'use'save_queries' => TRUE,
     // 以下其他配置省略
);

这里,就有两个数据库配置地址了。


再去,配置测试环境的配置文件,就在 config/config.php 目录下,新建一个获取数据库配置名的数组。 值就是上面 config/database.php 对应的key。

/*
    测试环境数据库名
*/
$config['sql']['sqlname'] = 'test';

再去,config 目录下,新建一个production 目录,这个作用于生产环境的配置文件。

在这里面新建一个 config.php 文件(config/production/config.php),也可以复制上一层目录的那个 config.php 文件,在里面写上同样的。

/*
    正式环境数据库名
*/
$config['sql']['sqlname'] = 'production';


接着, 就是完成什么测试环境的时候访问的是测试的配置文件。正式环境的时候访问的是正式的配置文件。

这个呢,就可以是在入口文件 index.php 配置一下。其实,默认本来也是可以的。

// 默认 index.php 56行
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');

但是我为了更直观的访问就改成了如下.

//如果是正式环境域名访问的就是读取正式环境的配置文件,否则都读取测试环境的配置文件   
 if($_SERVER['SERVER_NAME'] == '正式环境域名'){
        define('ENVIRONMENT','production');
    }else{
        define('ENVIRONMENT','development');
    }


再然后, 就是要折腾 model 目录了。我这里采用的是多个继承一个,就是在 model 目录新建一个 Base_Model.php ,其他 model 文件在继承于它。而这个文件主要作用就是,选择合适的数据库配置文件,以及 sql 的编写。

具体代码,类似如下,核心就是 __construct 里的方法

class Base_Model extends CI_Model {

    protected $mTable;
    //主键
    protected $mPkId = 'id';

    public function __construct()
    {
        //这个就会根据 index.php 文件的访问,读取不同的配置文件.
        $sqlname = $this->config->item('sql')['sqlname'];
        //这里是自己写的一个 自定义获取数据库配置文件的函数.
        $this->db = _getDb($sqlname);
    }

    //获取前缀
    public function prefix()
    {
        return $this->db->dbprefix;
    }
    
    //获取表
    public function table($table = '')
    {
        if (!$table) {
            $table = $this->mTable;
        }
        return $this->db->protect_identifiers($table, TRUE);
    }
    
    public function set_table($table)
    {
        $this->mTable = $table;
        return $this;
    }

    /**
     * 插入数据
     * @param array $data 要插入的数据
     * @return mixed
     */
    public function add($data){
        return $this->db->insert($this->mTable,$data);
    }
}

其中, _getDb 我是在 helpers 下新建了一个 common_helper.php 文件来当公共函数使用。

/**
 * 获取自定义数据库配置文件
 * @param string $group database.php的key名
 * @return mixed
 */
function _getDb($group = 'aliyun_procurement')
{
    static $db = array();
    if (!isset($db[$group])) {
        $CI =& get_instance();
        $db[$group] = $CI->load->database($group, TRUE);
        $db_name = 'ist_' . $group;
        $CI->$db_name = $db[$group];
    }
    return $db[$group];
}


代码工作就到这为止,就结束了.


具体使用的话,就只需要在 model 目录下,新建 xxx_model.php 文件, 比如 stock 表内容如下:

<?php
/**
 * Created by PhpStorm.
 * User: shwy
 * Date: 2017/5/16
 * Time: 15:47
 */
class Stock_model extends Base_Model {
    //这里的 stock 就是数据库的名字
    protected $mTable = 'stock';
}

Controller 中使用就直接使用

class Stock extends MY_Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('stock_model');
    }

    public function add(){
        $this->stock_model->数据库方法();
    }
}

以下:是我个人的见解和想法,如有指教欢迎评论指出。

文章被以下专栏收录
3 条评论
推荐阅读