php - PHP、PDO 和遗留数据库 - 动态更改字符集?
问题描述
很久没用PHP了。需要将一个非常非常旧的站点从 升级mysql_*
到PDO
. 迁移效果很好,但数据库是混合Latin1
和utf8
表格的可怕混乱。无法改变这一点。
在这里看到了一个简洁的解决方案,您只需为每种类型的字符集创建一个连接,但我的问题是该站点是作为类的层次结构构建的,所有这些类都派生自一个 Db 类,它在初始化时定义了字符集。
在旧代码中,问题是通过使用“解决”的mysql_set_charset()
,但不幸的是我找不到 PDO 等价物。
如何在 PDO 连接上动态更改字符集?甚至可能吗?或者任何人都可以提出一种模式?
这是从 PHP 5.x 升级到 7.2 引起的“发烧救援”,它不是重构整个代码库或数据库的选项。
它或多或少是这样的:
class Db {
private $pdo;
public function __construct() {
$dsn = "mysql:host=".$this->hostname.";dbname=".$this->database.";charset=".$this->charset;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false
];
try {
$this->pdo = new PDO($dsn, $this->username, $this->password, $opt);
} catch(PDOException $e) {
echo "Error connecting to database: ". $e->getMessage();
}
}
}
class AnotherClass extends Db {
public function __construct() {
parent::__construct();
...
}
}
class YetAnotherClass extends AnotherClass [
...
}
想在类上实现一个方法,Db
所以我在继承的类中可以执行例如$this->changeCharset('Latin1');
解决方案
使用 PDO 连接 MySQL 时,明智的做法是将字符集显式设置为 utf8(当然,只有在使用 utf8 时才是字符集)。在 MySQL 或 MySQLi 扩展中,我通常会执行查询 SET NAMES utf8 来设置它。
在 PDO 中,可以在连接字符串中指定字符集:
$conn = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
charset 选项仅在 PHP 5.3.6 之后使用,因此在运行旧版本的 PHP 时要考虑到这一点。在这种情况下,您应该在构造 PDO 对象后运行以下语句:
$conn->exec('SET NAMES utf8');
但无论如何,你不应该运行这样一个旧版本的 PHP。
推荐阅读
- node.js - 如何使用履行对具有相同意图的不同平台做出不同的响应
- python - 列表索引超出范围(python jupyter)
- java - 嵌套循环和流的时间复杂度
- iis - IIS Fastcgi 只运行某个用户创建的环境
- c# - IActionContextAccessor 为空
- java - 使用spring boot查询MySQL数据库时,未找到SQL查询返回列'id'
- java - 在 JAVA 中处理 Oracle TO_DATE(1, 'j')
- javascript - 如何防止Chrome中的页面刷新或默认提示框
- postgresql - INSERT INTO 使用格式
- css - 使用 ngStyle 传递 CSS 值