database = $loginUser['zt_database'] ?? ""; if (empty($this->database)) { $this->error = "账套数据库名称不能为空"; return; } $this->connName = 'sqlsrv_dynamic_' . md5($this->database); $this->createConnection(); } /** * 创建 SQL Server 连接 */ private function createConnection() { $mainConnName = $this->connName; $mainConfig = [ 'driver' => 'sqlsrv', 'host' => env('SQLSRV_HOST'), 'port' => env('SQLSRV_PORT'), 'database' => $this->database, 'username' => env('SQLSRV_USERNAME'), 'password' => env('SQLSRV_PASSWORD'), 'options' => [ \PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 15, // 查询超时 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, ], 'charset' => 'utf8', 'prefix' => '', ]; try { // 1. 动态注入配置 Config::set("database.connections.{$mainConnName}", $mainConfig); // 2. 获取连接句柄 $this->db = DB::connection($mainConnName); // 3. 验证连接(执行一次 SELECT 1) // 注意:SQLServer 有时候会因为防火墙或网络伪连,这里必须 try 才能抓到错误 $this->db->getPdo(); } catch (\Throwable $e) { $this->error = "SQLServer连接验证失败: " . $e->getMessage(); // 如果连接失败,清理掉无效配置 $this->close(); } } /** * 手动关闭并清理连接 (非常关键) * 特别是在 Command 脚本中,不调用这个会导致数据库句柄残留 */ public function close() { try { if ($this->connName) { // 1. 断开物理连接 DB::disconnect($this->connName); // 2. 从 Laravel 的连接池中彻底清除 DB::purge($this->connName); // 3. 移除动态注入的 Config Config::offsetUnset("database.connections.{$this->connName}"); } } catch (\Throwable $e) { // 忽略清理时的异常 } finally { $this->db = null; } } }