我有一些有趣的问题。以下两个代码不会产生相同的输出:
$result = $sql->QueryFetch("SELECT machinecodeSigned FROM ...");
echo bin2hex($result['machinecodeSigned']);
和
$result = $sql->QueryFetch("SELECT HEX(machinecodeSigned) FROM ...");
echo $result['machinecodeSigned'];
所以,$sql
只是一些包装类和方法 QueryFetch
,在内部只是为 query
和 fetch< 调用 PHP 标准函数
获得值(value)。
不过,我得到了两个不同的结果。例如,对于我数据库中的一些任意输入,我得到:
08c3bd79c3a0c2a66fc2bb375b6370c399c3acc3ba7bc2b8c2b203c39d70
和
08FD79E0A66FBB375B6370D9ECFA7BB8B203DD70
忽略大小写,第一个输出是无意义的,而另一个是正确的。
machinecodeSigned
是一个 char(255)
字段,它是 latin-1
编码的并且具有排序规则 latin-1
(我认为这不应该起作用)。
我得到两个不同结果的原因可能是什么?这个曾经
多年来一直产生相同的结果,但突然间我不得不将代码从版本 1 更改为版本 2 以使其产生正确的结果。看起来,好像 PHP 对字符串中的字节进行了一些任意转换。
编辑:似乎有必要说该字段不是人类可读的。在任何情况下,由于第二个输出是正确的,如果这对您有帮助,请随意将十六进制形式转换为 ASCII 字符。
编辑:
SHOW CREATE TABLE
产生:
CREATE TABLE `user` (
`ID` int(9) NOT NULL AUTO_INCREMENT,
`machinecodeSigned` char(255) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL
PRIMARY KEY (`ID`),
) ENGINE=InnoDB AUTO_INCREMENT=10092 DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci
最佳答案
char(255) CHARACTER SET latin1 COLLATE latin1_bin
将读取/写入字节不变。最好说 BINARY(255)
,或者别的什么。
如果您告诉服务器您的客户端 想要使用“utf8”进行通话,并且您SELECT
该列,那么 MySQL 将从 latin1(字符集数据)到 utf8(你说客户想要的编码)。这会导致更长的十六进制字符串。
你说 phpmyadmin 某处说“utf8”;这可能是造成混淆的原因。
如果它被存储为 base64,就不会混淆,因为 base64 使用很少的不同字符,并且它们在 latin1 和 utf8 中的编码相同。此外,latin1_bin 是合适的。因此,对错误的另一种解释是从 base64 到二进制的不需要的重新转换。
MySQL 的 latin1_bin 实现简单而宽松——所有 256 位值都只是简单地存储和加载,未经检查。这使得它实际上与 BLOB
和 BINARY
相同。
这可能是应该存储的base64_encode:
MDhGRDc5RTBBNjZGQkIzNzVCNjM3MEQ5RUNGQTdCQjhCMjAzREQ3MA==
以 VAR
开头或以 BLOB
或 TEXT
结尾的数据类型是通过“长度”字段加上表示值所需的字节来实现的.
另一方面,CHAR
和BINARY
是固定长度的,由空格(CHAR
) 或\0< 填充
(二进制
)。
因此,将二进制信息写入 CHAR(255)
实际上可能会由于附加的空格而修改数据。
关于php - 从 PHP 获取 MySQL 字符串时不相等的二进制字符比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57460752/