php - 如何在 PHP 中使用 PDO 从 SQL Server 数据库中获取数据并在 UTF-8 编码的 MySQL 数据库中正确编码?

标签 php mysql sql-server pdo utf-8

我在 PHP 中使用 PDO 连接到 SQL Server 数据库并提取数据,以在 MySQL 数据库中复制 SQL Server 数据库。

经过一番搜索,我发现SQL Server DB的排序规则是SQL_Latin1_General_CP1_CI_AS,相当于ISO-8859-1编码。因此,当我使用 PDO 连接到 SQL Server DB 时,我使用以下内容:

$dsn = 'dblib:host=aws-rds-endpoint.rds.amazonaws.com:1433;dbname=db-name;charset=iso_1';

最后的 iso_1 似乎可以正确地从 SQL Server DB 中提取所有内容,而不会出现任何乱码。

尽管 MySQL 数据库是 UTF-8,所以我对每个字符串值运行以下命令,将所有内容从 ISO-8859-1 转换为 UTF-8:

$val = isset($val) ? mb_convert_encoding($val, 'UTF-8', 'ISO-8859-1') : null;

但是,当我将数据插入 MySQL 数据库时(为此我在 PHP 中对数据库链接执行了以下操作:mysqli_set_charset($link, 'utf8');),我我收到乱码文本。
以下是一些乱码示例:

’ => PU2
“ => STS
” => CCH

PU2 等显示在 MySQL 数据库中,周围有黑框。 (请注意,我使用 MySQL Workbench 连接到 MySQL 数据库。)

基本上,我不知道为什么这些字符会出现乱码,也不知道如何修复它。如果我不运行上面的 mb_convert_encoding 函数,那么当我将数据插入 MySQL 数据库时,所有具有上述字符的字符串都会在第一个奇怪字符的实例处立即被截断,并且截断的字符串被插入到 MySQL DB 中。

最后一点,我在 SQL Server 数据库中注意到的字段都是 nvarcharCHARACTER_MAXIMUM_LENGTH 为 -1,如果重要的话,请使用 UNICODE 的 CHARACTER_SET_NAME,而不是 iso_1

最佳答案

不要使用任何转换例程,它只会增加困惑。

utf8 Hex latin1 hex  Unicode     Char    Name
E28099   92          8217=x2019  [’]     RIGHT SINGLE QUOTATION MARK
E2809C   93          8220=x201C  [“]     LEFT DOUBLE QUOTATION MARK
E2809D   94          8221=x201D  [”]     RIGHT DOUBLE QUOTATION MARK

这些是有效的UTF-8 (MySQL 之外)字符,以及 ut8 中的有效 MySQL 字符和utf8mb4 CHARACTER SETs .

8 位 latin1-utf8 映射为 here .

大多数编程语言不会将它们视为与撇号 ( ' ) 和双引号 ( " ) 相同的对待。

这很好:

mysqli_set_charset($link, 'utf8');

但是,您是否还声明了该列的 CHARACTER SET ?让我们看看SHOW CREATE TABLE .

我不认识PU2

如果您正确告诉 MySQL 客户端的编码是什么(latin1、utf8 等),那么 MySQL 将正确转换为 CHARACTER SET您要放入数据的列的名称(假设可以进行转换)。从评论来看,听起来客户使用了 latin1 (例如, 92 ,而不是 E8099 )。

关于php - 如何在 PHP 中使用 PDO 从 SQL Server 数据库中获取数据并在 UTF-8 编码的 MySQL 数据库中正确编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46793756/

相关文章:

php - 帮助处理棘手的 MySQL 查询

php - Laravel 4 如何合并数据库表并按 created_at 对它们进行排序?

Mysql生成的列由其他列上的条件计算

ruby-on-rails - 在 Ruby on Rails 中使用 Windows 身份验证

php - 如何在php的文件中写入语法错误?

php - IP 地理位置与 Mod_Rewrite & PHP

php - 使用 AJAX 的表单复选框始终在 php 中显示为 ON

php - 如何使用 PHP 和 MYSQL 创建饼图?

sql - 交叉表多列

sql - 如何在 30 分钟窗口中选择具有最高时间戳的行?