| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <?php
- namespace App\Service;
- use Illuminate\Support\Facades\Config;
- use Illuminate\Support\Facades\DB;
- class U8DatabaseServerService
- {
- public $db = null;
- public $error = null; // 错误信息存储
- private $database = "";
- private $connName = "";
- public function __construct($loginUser = [])
- {
- $this->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;
- }
- }
- }
|