U8DatabaseServerService.php 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace App\Service;
  3. use Illuminate\Support\Facades\Config;
  4. use Illuminate\Support\Facades\DB;
  5. class U8DatabaseServerService extends Service
  6. {
  7. public $db = null;
  8. public $error = null; // 错误信息
  9. private $database = "";
  10. private $connName = "";
  11. public function __construct($loginUser = [])
  12. {
  13. $this->database = $loginUser['zt_database'] ?? "";
  14. $this->connName = 'sqlsrv_' . $this->database . '_' . uniqid();
  15. $this->createConnection();
  16. }
  17. private function createConnection()
  18. {
  19. $mainConnName = $this->connName;
  20. // 创建连接
  21. $mainConfig = [
  22. 'driver' => 'sqlsrv',
  23. 'host' => env('SQLSRV_HOST'),
  24. 'port' => env('SQLSRV_PORT'),
  25. 'database' => $this->database,
  26. 'username' => env('SQLSRV_USERNAME'),
  27. 'password' => env('SQLSRV_PASSWORD'),
  28. 'options' => [
  29. \PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 15, // 减少超时
  30. \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
  31. ],
  32. ];
  33. // 配置注入
  34. Config::set("database.connections.{$mainConnName}", $mainConfig);
  35. // 连接
  36. $this->db = DB::connection($mainConnName);
  37. // 测试
  38. $this->validateConnection($this->db);
  39. // 如果失败,立即清理,避免残留连接名
  40. if ($this->error) {
  41. $this->safeDisconnect($this->db, $mainConnName);
  42. }
  43. }
  44. private function validateConnection($connection)
  45. {
  46. try {
  47. $pdo = $connection->getPdo();
  48. $stmt = $pdo->prepare("SELECT 1 AS connection_test");
  49. $stmt->execute();
  50. } catch (\Throwable $e) {
  51. $this->error = "数据库连接验证失败: " . $e->getMessage();
  52. }
  53. }
  54. /**
  55. * 手动关闭连接(定时任务必须调用)
  56. */
  57. public function close()
  58. {
  59. $this->safeDisconnect($this->db, $this->connName);
  60. }
  61. private function safeDisconnect(&$connection, $name)
  62. {
  63. try {
  64. if ($connection instanceof \Illuminate\Database\Connection) {
  65. // 断开物理连接
  66. $connection->disconnect();
  67. // 清除 Laravel 连接池
  68. DB::purge($name);
  69. // 移除配置
  70. Config::offsetUnset("database.connections.{$name}");
  71. // 引用置空
  72. $connection = null;
  73. }
  74. } catch (\Throwable $e) {
  75. // 忽略
  76. }
  77. }
  78. /**
  79. * 阻止依赖 __destruct
  80. */
  81. public function __destruct()
  82. {
  83. // 不做任何事,避免不确定行为
  84. }
  85. }