host = DB_HOST; $this->port = DB_PORT; $this->dbname = DB_NAME; $this->user = DB_USER; $this->pass = DB_PASS; $this->charset = DB_CHARSET; } /** 禁止克隆 */ private function __clone() {} public static function instance(): self { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; } /** * 获取 PDO 连接(惰性初始化) */ public function getConnection(): \PDO { if ($this->pdo === null) { $dsn = sprintf( 'mysql:host=%s;port=%d;dbname=%s;charset=%s', $this->host, $this->port, $this->dbname, $this->charset ); $this->pdo = new \PDO($dsn, $this->user, $this->pass, [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, \PDO::ATTR_EMULATE_PREPARES => false, \PDO::ATTR_STRINGIFY_FETCHES => false, ]); // 设置严格 SQL 模式 $this->pdo->exec("SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'"); } return $this->pdo; } /** * 执行查询返回所有行 */ public function fetchAll(string $sql, array $params = []): array { $stmt = $this->execute($sql, $params); return $stmt->fetchAll(); } /** * 执行查询返回单行 */ public function fetchOne(string $sql, array $params = []): ?array { $stmt = $this->execute($sql, $params); $row = $stmt->fetch(); return $row !== false ? $row : null; } /** * 执行查询返回单列值 */ public function fetchColumn(string $sql, array $params = []): mixed { $stmt = $this->execute($sql, $params); return $stmt->fetchColumn(); } /** * 执行 INSERT/UPDATE/DELETE,返回受影响行数 */ public function execute(string $sql, array $params = []): \PDOStatement { $pdo = $this->getConnection(); $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt; } /** * 获取最后插入的 ID */ public function lastInsertId(): string { return $this->getConnection()->lastInsertId(); } /** * 事务封装 */ public function beginTransaction(): void { $this->getConnection()->beginTransaction(); } public function commit(): void { $this->getConnection()->commit(); } public function rollback(): void { $this->getConnection()->rollback(); } /** * 不带数据库名连接(用于建库操作) */ public static function rawConnection(): \PDO { $dsn = sprintf('mysql:host=%s;port=%d;charset=%s', DB_HOST, DB_PORT, DB_CHARSET); return new \PDO($dsn, DB_USER, DB_PASS, [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, ]); } /** * 销毁连接(用于重置) */ public function close(): void { $this->pdo = null; self::$instance = null; } }