Yii2控制台多数据库处理难题:无会话无法切换企业专属库
Yii2控制台命令多数据库切换解决方案
核心思路
控制台环境无会话,需通过命令行参数传递企业标识,或直接遍历所有数据库配置,动态切换对应数据库连接。以下是具体实现方案:
方案1:命令行传参指定单企业数据库
1. 封装基础控制台控制器
创建通用父类,统一处理数据库切换逻辑,所有业务控制台命令继承该类:
namespace console\controllers; use yii\console\Controller; use Yii; class BaseConsoleController extends Controller { // 接收命令行传入的企业ID public $companyId; // 声明允许接收的命令行参数 public function options($actionID) { return array_merge(parent::options($actionID), ['companyId']); } // 执行动作前初始化数据库 public function beforeAction($action) { if (!parent::beforeAction($action)) { return false; } if (!$this->companyId) { $this->stderr('请指定企业ID:--company-id=xxx' . PHP_EOL); return false; } // 根据企业ID匹配对应数据库配置(需自行实现映射逻辑) $dbName = 'db' . $this->companyId; if (!isset(Yii::$app->components[$dbName])) { $this->stderr("企业ID {$this->companyId} 对应的数据库配置不存在" . PHP_EOL); return false; } // 动态替换默认db组件为目标数据库 Yii::$app->set('db', Yii::$app->components[$dbName]); return true; } }
2. 编写业务控制台命令
继承基础控制器后,直接使用Yii::$app->db即可操作指定企业的数据库:
namespace console\controllers; class BusinessController extends BaseConsoleController { // 示例:同步指定企业的数据 public function actionSyncData() { $data = Yii::$app->db->createCommand('SELECT * FROM business_table')->queryAll(); // 此处编写业务逻辑 } }
3. 执行命令
通过命令行参数指定企业ID:
yii business/sync-data --company-id=1
方案2:批量遍历所有企业数据库
若需一次性处理所有企业数据,可直接遍历配置中的所有数据库组件:
namespace console\controllers; use yii\console\Controller; use Yii; class BatchController extends Controller { public function actionProcessAll() { // 遍历所有数据库配置 foreach (Yii::$app->components as $name => $config) { // 筛选出db开头的数据库连接配置 if (strpos($name, 'db') === 0 && is_array($config) && $config['class'] === 'yii\db\Connection') { // 切换当前数据库 Yii::$app->set('db', $config); // 执行单企业业务逻辑 $this->processSingleCompany(); } } } private function processSingleCompany() { // 此处编写单企业的业务处理逻辑 $count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM some_table')->queryScalar(); $this->stdout("当前企业数据条数:{$count}" . PHP_EOL); } }
执行批量命令:
yii batch/process-all
方案3:统一Web/控制台数据库获取逻辑
封装Helper类,复用数据库切换逻辑,同时支持Web端会话获取和控制台传参:
namespace common\helpers; use Yii; class DbHelper { /** * 获取指定企业的数据库连接 * @param int|null $companyId 控制台传参时指定,Web端自动从会话获取 * @return \yii\db\Connection * @throws \Exception */ public static function getDb($companyId = null) { if ($companyId === null) { // Web端从会话读取企业标识 $companyId = Yii::$app->session->get('company_id'); } $dbName = 'db' . $companyId; if (!Yii::$app->has($dbName)) { throw new \Exception("企业ID {$companyId} 对应的数据库配置不存在"); } return Yii::$app->get($dbName); } }
- Web端使用:
DbHelper::getDb() - 控制台使用:
DbHelper::getDb($this->companyId)
注意事项
- 确保企业ID与数据库配置名称的映射关系准确,避免配置匹配错误
- 控制台命令执行时需处理异常,及时输出错误信息便于排查
- 长时间运行的批量命令,需注意数据库连接的有效性,必要时重新连接
内容的提问来源于stack exchange,提问作者ric128
相关产品推荐
相关产品推荐

