我有一些带有 utf8mb4 字段的MySQL表,还有一些带有 utf8 的MySQL表。
在所有表的PDO连接字符串中使用utf8mb4是否安全?还是我必须将所有内容都转换为utf8mb4,或者启动两个不同的PDO连接?
编辑:问题不是“我可以将4字节字符存储到utf8列中吗?”我们已经知道不能,这不取决于连接,因此,如果一栏是utf8,则意味着它将不会接收4个字节的字符,例如国家或货币代码,电子邮件地址,用户名...,其中输入由应用程序验证。
最佳答案
使用以下脚本可以很容易地对此进行测试:
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', 'test', '');
$pdo->exec("
drop table if exists utf8_test;
create table utf8_test(
conn varchar(50) collate ascii_bin,
column_latin1 varchar(50) collate latin1_general_ci,
column_utf8 varchar(50) collate utf8_unicode_ci,
column_utf8mb4 varchar(50) collate utf8mb4_unicode_ci
);
");
$latin = 'abc äŒé';
$utf8 = '♔♕';
$mb4 = '🛃 🔣';
$pdo->exec("set names utf8");
$pdo->exec("
insert into utf8_test(conn, column_latin1, column_utf8, column_utf8mb4)
values ('utf8', '$latin', '$latin $utf8', '$latin $utf8 $mb4')
");
$pdo->exec("set names utf8mb4");
$pdo->exec("
insert into utf8_test(conn, column_latin1, column_utf8, column_utf8mb4)
values ('utf8mb4', '$latin', '$latin $utf8', '$latin $utf8 $mb4')
");
$result = $pdo->query('select * from utf8_test')->fetchAll(PDO::FETCH_ASSOC);
var_export($result);
结果如下:
array (
0 =>
array (
'conn' => 'utf8',
'column_latin1' => 'abc äŒé',
'column_utf8' => 'abc äŒé ♔♕',
'column_utf8mb4' => 'abc äŒé ♔♕ ???? ????',
),
1 =>
array (
'conn' => 'utf8mb4',
'column_latin1' => 'abc äŒé',
'column_utf8' => 'abc äŒé ♔♕',
'column_utf8mb4' => 'abc äŒé ♔♕ 🛃 🔣',
),
)
如您所见,当我们处理
utf8
列时,不能将utf8mb4
用作连接字符集(请参阅????
)。但是,当使用utf8mb4
列时,我们可以使用utf8
进行连接。同样,写入和读取latin
或ascii
列也不会有问题。原因是您可以用
utf8
编码任何latin
,ascii
或utf8mb4
字符,但不能反之。因此,在这种情况下,使用utf8mb4
作为连接的字符集是安全的。关于php - 我可以安全地将utf8mb4连接与utf8列一起使用吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34595463/