执行 MySQL 查询时,charset 如何影响 php?

我注意到在 PHP 中进行数据库查询时(例如 Zend_db、mysqli...),您可以设置字符集。例如:mysqli_set_charset($con,"utf8"); 对于这在幕后的实际作用,我有点模糊。

如果我使用 php 进行数据库 SELECT 查询,并且我指定了一个字符集,如果它与数据库中定义的列不同的字符集会发生什么?

我的意思是,数据库返回一个二进制序列,但是如果两个字符集中的字符编码不同,实际返回的是什么?mySQL 会获取内部二进制数据并“按原样”返回吗?

或者 MySQL 是否会尝试将其转换为与您指定的字符集中等效的二进制序列?

我想我的问题的要点是,我想知道当 PHP 在查询中发送时数据是如何编码的,它是如何从 MySQL 传回的,以及 PHP 将其取回并将其存储到后是否还有另一个翻译步骤PHP 内存中的字符串。

同样,如果您正在执行 INSERT 或更新,它是如何从 PHP 发送到 MySQL 的?PHP 是否将其转换为正确的二进制编码然后将其发送到 MySQL?

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 更新:

感谢雷蒙德·奈兰德。我能够修复我的错误。但我确实注意到,对于非标准字符,字符集似乎很重要。

我使用 $db = new \PDO("mysql:host=$host;dbname=$database;charset=latin1", $dbuser, $dbpassword); 做了一个选择语句。首先,我尝试了 latin1,然后我尝试了 utf8。

我的问题是我有一个包含加密数据的列,我猜其中有一些奇怪的字符。如果我直接在数据库查询中对该字段执行 md5,它给了我一个以 889 开头的编码......但是,我试图用 SELECT 语句将它拉入 PHP。如果我使用带有 latin1 字符集的 PDO,然后在 PHP 中执行 MD5(),它会给我相同的哈希值 (889...)。这意味着 PHP 拥有数据库中二进制文件的精确副本。但是如果我确实使用了带有字符集“UTF-8”的 PDO,然后在 PHP 中做了一个 MD5(),它给了我一个以 087 开头的哈希......所以在某个地方,必须进行转换。

至此,我的原始错误已修复,但我仍然对正在发生的事情感到好奇。MYSQL 是在将其返回给 PHP 之前进行转换,还是 PDO 在 PHP 端进行某种转换?


MMTTMM
浏览 186回答 1
1回答

Helenr

mysqli_set_charset($con,"utf8");(或其他客户端库的其他代码)向 MySQL 声明客户端中的编码将是MySQL 的. 如果将不同编码的字节发送到(想想)mysql,就会发生垃圾或错误。CHARACTER SET utf8INSERT该设置还声明客户端希望从SELECTs.每个表CHARACTER SET中每一列上的可能是别的东西(例如,“latin1”)。如果是这样,MySQL 将在传输过程中尝试转换编码。注意:MySQLCHARACTER SET utf8是众所周知的UTF-8. 要获得后者,请CHARACTER SET utf8mb4在表中和mysqli_set_charset($con,"utf8mb4");连接时使用。展望未来,utf8mb4在大多数情况下是首选。非文本内容(“原样”)应放入BLOB或VARBINARY列中——这会绕过对编码的任何检查。(想想 .jpg 或AES_ENCRYPT.)MySQL 的MD5()函数返回一个十六进制字符串。 UNHEX(MD5('...'))返回二进制内容,并且必须存储在例如BINARY(16)列中。UTF-8 字符的麻烦中讨论了许多形式的乱码文本;我看到的不是我存储的。
打开App,查看更多内容
随时随地看视频慕课网APP