?php/** * 案例标题多环境配置管理 * 说明基于.env文件管理dev/test/prod不同环境配置运行时根据APP_ENV自动加载对应配置 * 需要安装的包 * composer require hyperf/config * composer require vlucas/phpdotenv */declare(strict_types1);// .env.dev 文件内容放项目根目录/* APP_ENVdev APP_NAMEHyperfApp DB_HOST127.0.0.1 DB_PORT3306 DB_DATABASEhyperf_dev DB_USERNAMEroot DB_PASSWORD123456 REDIS_HOST127.0.0.1 REDIS_PORT6379 LOG_LEVELdebug */// .env.prod 文件内容 /* APP_ENVprod APP_NAMEHyperfApp DB_HOST10.0.1.100 DB_PORT3306 DB_DATABASEhyperf_prod DB_USERNAMEhyperf_user DB_PASSWORDStrongPassword123! REDIS_HOST10.0.1.200 REDIS_PORT6379 LOG_LEVELerror */// config/autoload/database.php // 数据库配置文件直接读env变量不同环境自动切换return[default[drivermysql,hostenv(DB_HOST,127.0.0.1),// 从环境变量读数据库地址portenv(DB_PORT,3306),// 端口默认3306databaseenv(DB_DATABASE,hyperf),// 数据库名usernameenv(DB_USERNAME,root),// 用户名passwordenv(DB_PASSWORD,),// 密码生产环境记得改强密码charsetutf8mb4,// 字符集支持emoji用这个collationutf8mb4_unicode_ci,pool[min_connections1,max_connections(int)env(DB_MAX_CONN,10),// 连接池大小也可以用env控制connect_timeout10.0,wait_timeout3.0,heartbeat-1,max_idle_time(float)env(DB_IDLE_TIME,60),],],];// config/autoload/app.php // 应用基础配置return[nameenv(APP_NAME,HyperfSkeleton),// 应用名称envenv(APP_ENV,dev),// 当前环境dev/test/proddebugenv(APP_DEBUG,false),// 调试模式生产别开timezoneAsia/Shanghai,// 时区国内项目固定上海];// app/ConfigProvider.php namespaceApp;classConfigProvider{publicfunction__invoke():array{return[dependencies[],commands[],listeners[],];}}// bin/hyperf.php 启动入口自动加载对应env文件 namespaceApp\Bootstrap;useDotenv\Dotenv;classEnvLoader{/** * 根据APP_ENV环境变量加载对应的.env文件 * 启动时先看有没有 .env.{环境名}有就加载没有就fallback到.env */publicstaticfunctionload(string$basePath):void{$appEnvgetenv(APP_ENV)?:dev;// 先从系统环境变量读没有就默认dev$envFile.env.{$appEnv};// 拼出文件名比如 .env.prodif(file_exists($basePath./.$envFile)){// 找到了对应环境的文件就加载它Dotenv::createImmutable($basePath,$envFile)-load();}elseif(file_exists($basePath./.env)){// 没有对应环境文件fallback到默认.envDotenv::createImmutable($basePath)-load();}// 两个都没有就算了靠系统环境变量跑}}// app/Service/ConfigService.php namespaceApp\Service;useHyperf\Contract\ConfigInterface;classConfigService{publicfunction__construct(privateConfigInterface$config// 注入Hyperf配置对象){}/** * 获取当前环境名方便业务代码判断是不是生产环境 */publicfunctiongetEnv():string{return$this-config-get(app.env,dev);}/** * 判断是不是生产环境生产环境一些敏感操作要禁掉 */publicfunctionisProduction():bool{return$this-getEnv()prod;}/** * 获取数据库配置调试的时候可以打印出来看看加载的是哪个库 */publicfunctiongetDbConfig():array{return$this-config-get(database.default,[]);}}// app/Controller/ConfigController.php namespaceApp\Controller;useApp\Service\ConfigService;useHyperf\HttpServer\Annotation\Controller;useHyperf\HttpServer\Annotation\GetMapping;#[Controller(prefix:/config)]classConfigController{publicfunction__construct(privateConfigService$configService){}/** * GET /config/env - 查看当前跑的是哪个环境 * 生产环境记得把这个接口干掉别暴露配置信息 */#[GetMapping(path:/env)]publicfunctionenv():array{// 生产环境不允许查配置防止信息泄露if($this-configService-isProduction()){return[code403,msg生产环境禁止访问];}return[code0,data[env$this-configService-getEnv(),db_host$this-configService-getDbConfig()[host]??unknown,],];}}