您好,登录后才能下订单哦!
在基于EasySwoole框架开发项目时,合理的配置管理是项目架构中非常重要的一环。随着项目规模的增长,配置项往往会变得越来越多,如果将所有配置都放在一个文件中,会导致配置文件臃肿、难以维护。本文将详细介绍如何在EasySwoole中实现一个自动加载自定义配置文件夹下所有配置文件的封装方案,使配置管理更加模块化和规范化。
在开始自定义配置加载方案前,我们先了解一下EasySwoole的默认配置机制。
EasySwoole的默认配置文件通常位于项目根目录下的dev.php
、produce.php
等环境相关文件中。这些文件返回一个数组,包含了框架运行所需的各种配置。
// dev.php
return [
'SERVER_NAME' => "EasySwoole",
'MN_SERVER' => [
'LISTEN_ADDRESS' => '0.0.0.0',
'PORT' => 9501,
'SERVER_TYPE' => EASYSWOOLE_WEB_SERVER,
'SOCK_TYPE' => SWOOLE_TCP,
'RUN_MODEL' => SWOOLE_PROCESS,
'SETTING' => [
'worker_num' => 8,
'reload_async' => true,
'max_wait_time' => 3
],
'TASK'=>[
'workerNum'=>4,
'maxRunningNum'=>128,
'timeout'=>15
]
],
'TEMP_DIR' => null,
'LOG_DIR' => null
];
EasySwoole在启动时会自动加载这些配置文件,并通过Config
类实例进行管理。我们可以通过以下方式获取配置:
$config = \EasySwoole\EasySwoole\Config::getInstance();
$serverConfig = $config->getConf('MN_SERVER');
虽然这种机制简单直接,但在大型项目中存在以下问题:
我们的自定义配置加载方案需要实现以下目标:
我们将实现一个ConfigLoader
类,主要包含以下功能:
首先创建一个ConfigLoader
类来处理配置加载逻辑:
<?php
namespace App\Utility;
use EasySwoole\EasySwoole\Config;
class ConfigLoader
{
/**
* 加载指定目录下的所有配置文件
* @param string $configPath 配置目录路径
* @param bool $mergeToGlobal 是否合并到全局配置
* @return array
*/
public static function load(string $configPath, bool $mergeToGlobal = true): array
{
if (!is_dir($configPath)) {
return [];
}
$configs = [];
$files = scandir($configPath);
foreach ($files as $file) {
if ($file === '.' || $file === '..') {
continue;
}
$filePath = $configPath . '/' . $file;
if (is_file($filePath) {
$info = pathinfo($file);
if ($info['extension'] === 'php') {
$configName = $info['filename'];
$configs[$configName] = include $filePath;
}
}
}
if ($mergeToGlobal) {
self::mergeToGlobal($configs);
}
return $configs;
}
/**
* 将配置合并到全局配置中
* @param array $configs
*/
protected static function mergeToGlobal(array $configs): void
{
$globalConfig = Config::getInstance();
foreach ($configs as $name => $config) {
$globalConfig->setConf($name, $config);
}
}
}
在EasySwooleEvent.php
的initialize
方法中调用我们的配置加载器:
use App\Utility\ConfigLoader;
public static function initialize()
{
// 其他初始化代码...
// 加载自定义配置
$customConfigPath = EASYSWOOLE_ROOT . '/Config';
ConfigLoader::load($customConfigPath);
// 其他初始化代码...
}
我们可以按照以下结构组织配置文件:
App/
Config/
├── database.php # 数据库配置
├── redis.php # Redis配置
├── cache.php # 缓存配置
├── queue.php # 队列配置
└── api.php # API相关配置
每个配置文件返回自己的配置数组:
// Config/database.php
return [
'host' => '127.0.0.1',
'port' => 3306,
'user' => 'root',
'password' => '',
'database' => 'test',
'timeout' => 5,
'charset' => 'utf8mb4',
];
现在我们可以通过统一的方式获取配置:
// 获取数据库配置
$dbConfig = \EasySwoole\EasySwoole\Config::getInstance()->getConf('database');
// 获取Redis配置
$redisConfig = \EasySwoole\EasySwoole\Config::getInstance()->getConf('redis');
在实际项目中,我们经常需要根据环境不同使用不同的配置。我们可以扩展ConfigLoader
来支持环境变量覆盖:
public static function load(string $configPath, bool $mergeToGlobal = true): array
{
// ...之前的代码...
foreach ($files as $file) {
// ...文件处理逻辑...
$configName = $info['filename'];
$config = include $filePath;
// 检查是否有环境特定配置
$envConfigFile = $configPath . '/' . $configName . '_' . env('APP_ENV', 'dev') . '.php';
if (file_exists($envConfigFile)) {
$envConfig = include $envConfigFile;
$config = array_merge($config, $envConfig);
}
$configs[$configName] = $config;
}
// ...之后的代码...
}
为了提升性能,我们可以添加配置缓存支持:
public static function load(string $configPath, bool $mergeToGlobal = true): array
{
$cacheFile = EASYSWOOLE_ROOT . '/Runtime/config_cache.php';
// 开发环境不缓存
if (env('APP_ENV', 'dev') !== 'produce' || !file_exists($cacheFile)) {
$configs = self::loadFromFiles($configPath);
// 生产环境缓存配置
if (env('APP_ENV', 'dev') === 'produce') {
file_put_contents($cacheFile, '<?php return ' . var_export($configs, true) . ';');
}
} else {
$configs = include $cacheFile;
}
if ($mergeToGlobal) {
self::mergeToGlobal($configs);
}
return $configs;
}
protected static function loadFromFiles(string $configPath): array
{
// 实现从文件加载配置的逻辑
// 同之前的load方法实现
}
对于更复杂的项目,我们可能需要支持多级配置目录:
public static function load(string $configPath, bool $mergeToGlobal = true): array
{
$configs = [];
$dirIterator = new \RecursiveDirectoryIterator($configPath, \RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::SELF_FIRST);
foreach ($iterator as $file) {
if ($file->isFile() && $file->getExtension() === 'php') {
$relativePath = $iterator->getSubPath();
$configName = str_replace('/', '.', $relativePath . '.' . $file->getBasename('.php'));
$config = include $file->getPathname();
$configs[$configName] = $config;
}
}
if ($mergeToGlobal) {
self::mergeToGlobal($configs);
}
return $configs;
}
这样我们可以按照目录结构组织配置,例如:
Config/
├── db/
│ ├── master.php
│ └── slave.php
├── cache/
│ ├── redis.php
│ └── memcached.php
└── app.php
获取配置时可以使用点语法:
$masterDbConfig = Config::getInstance()->getConf('db.master');
通过本文介绍的方法,我们实现了一个灵活、高效的EasySwoole自定义配置加载方案。该方案具有以下优点:
在实际项目中,可以根据具体需求进一步扩展此方案,例如添加配置热更新、配置变更监听等功能,使配置管理更加完善。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。