TP5一套代码实现多域名独立配置的实践

业务背景

在开发项目过程中,要实现一套代码,多个项目共存

思路

根据域名区分不同项目,读取不同配置(如数据库等配置)

实现过程

改造前目录结构

├─application
├─config
    ├─config.php

改造后目录结构

├─application
├─config
    ├─core
    │   ├─a.example.com.php
    │   ├─b.example.com.php
    ├─config.php

针对TP5.0.*原有config.php做如下修改

<?php
// +----------------------------------------------------------------------
// | 配置文件
// | 请根据接口域名创建对应核心配置文件,文件名同接口域名,后缀.php
// | 例:api.example.com ,对应核心配置文件为 core\api.example.com.php
// | 公共配置写在此文件,单独配置写到core内对应文件
// | 配置合并原则:核心配置$configCore会覆盖基础配置$configBase
// +----------------------------------------------------------------------
error_reporting(E_ERROR | E_WARNING | E_PARSE);
date_default_timezone_set('Asia/Shanghai');

$serverName  = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : ''; // 服务器主机名  例:api.example.com
$configFile  = 'core'.DS.$serverName.'.php';  // 核心配置文件  例:core\api.example.com.php
try {
    // 核心配置
    $configCore = $serverName ? include_once($configFile) : []; 
} catch (Exception $e) {
    throw new Exception('配置文件不存在:'.$e->getMessage());
}

// 基础配置
$configBase = [
    // 这里是原有的配置 吧啦吧啦
    # code...
];

// 配置合并 原则:核心配置覆盖基础配置
$config = array_merge_two($configBase, $configCore);

return $config;

/**
 * 二维数组合并
 */
function array_merge_two( array $arr1, array $arr2)
{ 
    $arrTemp = array_merge($arr1,$arr2);
    foreach ($arr1 as $key => $value) {
        if(is_array($value)){
            if(is_array($arr1[$key]) && isset($arr2[$key]) && is_array($arr2[$key])){
                $arr1[$key] = array_merge($arr1[$key],$arr2[$key]);
            }
        }else{
            $arr1[$key] = isset($arr2[$key]) ? $arr2[$key] : $value;
        }
    }
    return array_merge($arrTemp,$arr1);
}

单域名核心配置示例 a.example.com.php

<?php
// +----------------------------------------------------------------------
// | Description: 核心配置文件
// +----------------------------------------------------------------------
return [
    // 数据库配置
    'database' => [
        // 服务器地址
        'hostname' => 'localhost',
        // 数据库名
        'database' => 'test',
        // 用户名
        'username' => 'root',
        // 密码
        'password' => 'root',
    ],
    // 缓存配置
    'cache' => [
        // 驱动方式
        'type'     => 'Redis',
        // 缓存保存目录
        'path'     => CACHE_PATH,
        // 缓存前缀
        'prefix'   => 'a.example.com:',
        // 缓存有效期 0表示永久缓存
        'expire'   => 0,
        // redis主机
        'host'     => 'localhost',
        // 密码
        'password' => '',
        // 操作库
        'select'   => 0,
    ],
    // redis配置
    'redis' => [
        'host'     => 'localhost',
        'password' => '',
        'select'   => 1,
    ],
    // 项目名
    'project_name' => 'a.example.com',
    // 渠道号
    'channel' => 1001,
];

坑点

用这种方式后,如果要使用TP5的cli命令行模式,需要在config.php中添加一个默认数据库配置,不然读取数据库会报错

标签: php thinkphp

发表评论: