我花了好几个小时调试一个算法并发现它来自Doctrine(v2.3.3)。 我正在使用libpuzzle来计算图像的哈希并将此哈希存储在数据库中。 返回的哈希中有特殊字符,显然Doctrine不喜欢它。
这是我拥有的那种字符串(~550 char):
...ÿþÿÿþþþÿþÿþÿþþþÿþÿÿÿÿþþÿþÿÿÿþÿþÿþþÿþþÿÿÿþÿþþþþÿþþþþÿÿÿÿÿþþÿþÿþÿþÿþþÿþÿÿÿþþÿþþþþÿþþþþÿÿÿþþþÿÿþþþÿÿþÿþþÿþþþÿþ
我调查过并发现有些人说要在配置中添加字符集,但我已经拥有它了:
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
如果我将列的排序规则从utf8_unicode_ci
更改为utf8_general_ci
仍然无法正常工作。此外,我确保默认架构排序规则为utf8_general_ci
。
我尝试过另一个带有特殊字符的字符串:
测试!§$%& /()=? äöüÄÖÜ:D
此字符串已正确插入但哈希仍然没有。
有谁知道我可以在哪里解决这个问题?这是一个学说错误吗?
----------------------------------
更新
在执行之前,我仍然拥有正确的数据绑定。所以我猜这是一个编码或驱动程序问题。我修改了symfony配置:
# Doctrine Configuration
doctrine:
dbal:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
options:
1002: "SET NAMES 'UTF8'"
我还试图在不使用实体的情况下执行查询:
$this->db = $this->getContainer()->get('doctrine')->getConnection();
$img = '/var/www/acme/web/upload/tmp/cd1fa593cf6feb2cde83e68f461a2d947.jpg';
$hash = puzzle_fill_cvec_from_file($img);
$sql = "UPDATE image set hash=? WHERE id=?";
$stmt = $this->db->prepare($sql);
$stmt->execute(array($hash, 180));
数据库中仍为空数据。
在另一个项目中,我使用了Zend_Db
并且在保存此哈希时没有任何问题。
我不知道这是Doctrine
中的错误:(
----------------------------------
更新2
我已经在mysql中记录了所有查询,我可以在日志中看到内容绑定正确。但是没有被mysql正确保存。
INSERT INTO image (guid, type, createTime, updateTime, images, imageSize, imageHash, status)
VALUES (
'c30df23d6b0b08aff079287e00f21ec8a',
'image',
'2013-04-22 03:30:33',
'2013-04-22 03:30:34',
'path/image.jpg',
'165458',
'?\0????\0?????????\0??????\0??????\0??????????????????????\0????\0??\0???\0???????????????????????????\0\0\0??\0?\0??\0??????????????????\0\0\0??\0?\0???????????????\0?????????????????\0?\0????????????\0?\0??????????????????????????\0?\0???????????\0???\0?????????\0??????\0\0?????????????????????\0\0??????\0???????????????\0',
1)
这是我的创建表:
delimiter $$
CREATE TABLE `image` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`guid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`type` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`createTime` datetime NOT NULL,
`updateTime` datetime DEFAULT NULL,
`images` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`imageSize` bigint(20) DEFAULT NULL,
`imageHash` longtext COLLATE utf8_unicode_ci,
`status` integer(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci$$
干杯, 马克西姆
答案 0 :(得分:2)
你不应该使用imageHash longtext COLLATE utf8_unicode_ci,
因为RDBM会尝试将数据映射到字符集,如果你的哈希数据是libpuzzle二进制输出,这显然不匹配。
尝试更改您的架构,使imageHash
列成为BLOB
。
如上所述:http://dev.mysql.com/doc/refman/5.0/en/blob.html
BLOB值被视为二进制字符串(字节字符串)。它们具有无字符集,并且排序和比较基于列值中字节的数值。
TEXT值被视为非二进制字符串(字符串)。它们具有字符集,并且值将根据字符集的排序规则进行排序和比较。
答案 1 :(得分:0)
默认情况下,您的MySQL服务器可能未配置为从客户端接受UTF8。
在这种情况下,您需要运行以下查询:
SET NAMES utf8
在PHP脚本的开头运行它,例如通过Doctrine Connection对象。