DBPdo instead of DBMysqli

This commit is contained in:
xiaomlove
2026-04-13 03:12:04 +07:00
parent 9995767bf7
commit f271e28b15
7 changed files with 197 additions and 10 deletions
+5
View File
@@ -1,6 +1,11 @@
<?php
namespace Nexus\Database;
/**
* @deprecated
*
* use DBPdo instead
*/
class DBMysqli implements DBInterface
{
private $mysqli;
+129
View File
@@ -0,0 +1,129 @@
<?php
namespace Nexus\Database;
use PDO;
class DBPdo implements DBInterface
{
private PDO $pdo;
private $driver;
private $lastStmt;
public function connect($host, $username, $password, $database, $port)
{
$driver = $this->driver = nexus_config('nexus.database.default');
if ($driver === 'mysql') {
$dsn = "mysql:host={$host};port={$port};dbname={$database};charset=utf8mb4";
} elseif ($driver === 'pgsql') {
$dsn = "pgsql:host={$host};port={$port};dbname={$database}";
} else {
throw new DatabaseException("Unsupported driver");
}
$pdo = new PDO($dsn, $username, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 替代 mysqli 报错机制
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
// ===== MySQL 专属 =====
if ($driver === 'mysql') {
$pdo->exec("SET NAMES utf8mb4");
$pdo->exec("SET collation_connection = 'utf8mb4_unicode_ci'");
$pdo->exec("SET sql_mode=''");
$pdo->exec("SET time_zone='".date('P')."'");
}
// ===== PostgreSQL 专属 =====
if ($driver === 'pgsql') {
$pdo->exec("SET TIME ZONE '".date('P')."'");
}
return $this->pdo = $pdo;
}
public function query(string $sql)
{
$this->lastStmt = $this->pdo->query($sql);
return $this->lastStmt;
}
public function error(): string
{
$error = $this->pdo->errorInfo();
return $error[2] ?? '';
}
public function errno(): int
{
$error = $this->pdo->errorInfo();
return (int)($error[1] ?? 0);
}
public function numRows($stmt): int
{
// ⚠️ PDO 对 SELECT 不可靠,这里兼容处理
return $stmt->rowCount();
}
public function selectDb($database)
{
if ($this->driver === 'mysql') {
return $this->pdo->exec("USE `{$database}`");
}
if ($this->driver === 'pgsql') {
// PostgreSQL 不能切数据库,只能重连
throw new DatabaseException("PostgreSQL does not support selectDb()");
}
return false;
}
public function fetchAssoc($stmt)
{
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function fetchRow($stmt)
{
return $stmt->fetch(PDO::FETCH_NUM);
}
public function fetchArray($stmt, $type = null)
{
if ($type === null) {
return $stmt->fetch(PDO::FETCH_BOTH);
}
// 兼容 mysqli 常量
switch ($type) {
case MYSQLI_ASSOC:
return $stmt->fetch(PDO::FETCH_ASSOC);
case MYSQLI_NUM:
return $stmt->fetch(PDO::FETCH_NUM);
default:
return $stmt->fetch(PDO::FETCH_BOTH);
}
}
public function affectedRows(): int
{
return $this->lastStmt ? $this->lastStmt->rowCount() : 0;
}
public function escapeString(string $string): string
{
return substr($this->pdo->quote($string), 1, -1);
}
public function lastInsertId(): int
{
return (int)$this->pdo->lastInsertId();
}
public function freeResult($stmt)
{
return $stmt->closeCursor();
}
}
+12 -5
View File
@@ -57,7 +57,8 @@ class NexusDB
return self::$instance;
}
$instance = new self;
$driver = new DBMysqli();
// $driver = new DBMysqli();
$driver = new DBPdo();
$instance->setDriver($driver);
return self::$instance = $instance;
}
@@ -259,7 +260,7 @@ class NexusDB
public static function bootEloquent(array $config)
{
$capsule = new Capsule(Container::getInstance());
$connectionName = self::ELOQUENT_CONNECTION_NAME;
$connectionName = self::getConnectionName();
$capsule->addConnection($config, $connectionName);
$capsule->setAsGlobal();
$capsule->bootEloquent();
@@ -271,7 +272,7 @@ class NexusDB
private static function schema(): \Illuminate\Database\Schema\Builder
{
if (IN_NEXUS) {
return Capsule::schema(self::ELOQUENT_CONNECTION_NAME);
return Capsule::schema(self::getConnectionName());
}
throw new \RuntimeException('can not call this when not in nexus.');
}
@@ -295,7 +296,7 @@ class NexusDB
public static function table($table): \Illuminate\Database\Query\Builder
{
if (IN_NEXUS) {
return Capsule::table($table, null, self::ELOQUENT_CONNECTION_NAME);
return Capsule::table($table, null, self::getConnectionName());
}
return DB::table($table);
}
@@ -319,7 +320,7 @@ class NexusDB
public static function transaction(\Closure $callback, $attempts = 1)
{
if (IN_NEXUS) {
return Capsule::connection(self::ELOQUENT_CONNECTION_NAME)->transaction($callback, $attempts);
return Capsule::connection(self::getConnectionName())->transaction($callback, $attempts);
}
return DB::transaction($callback, $attempts);
}
@@ -455,5 +456,11 @@ class NexusDB
}
}
public static function getConnectionName()
{
return nexus_config('nexus.database.default');
}
}