3

我花了几个小时来调试一个算法,并注意到它来自 Doctrine (v2.3.3)。我正在使用 libpuzzle 来计算图像的哈希并将此哈希存储在数据库中。返回的哈希具有特殊字符,显然 Doctrine 不喜欢它。

这是我拥有的那种字符串(约 550 个字符):

我调查并发现有人说要在配置中添加字符集,但我已经有了它:

# 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_ciutf8_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$$

干杯,马克西姆

4

2 回答 2

2

您不应该使用imageHash longtext COLLATE utf8_unicode_ci, ,因为 RDBM 会尝试将数据映射到字符集,如果您的哈希数据是 libpuzzle 二进制输出,这显然不匹配。

尝试更改您的架构以使您的imageHash列成为BLOB.

如此处所述:http: //dev.mysql.com/doc/refman/5.0/en/blob.html

BLOB 值被视为二进制字符串(字节字符串)。它们没有字符集,排序和比较基于列值中字节的数值。

TEXT 值被视为非二进制字符串(字符串)。它们有一个字符集,并且根据字符集的排序规则对值进行排序和比较

于 2013-04-26T14:08:47.350 回答
0

可能是您的 MySQL 服务器未配置为默认接受来自客户端的 UTF8。

在这种情况下,您需要运行以下查询:

SET NAMES utf8

在 PHP 脚本的开头运行它,例如通过 Doctrine Connection 对象。

于 2013-04-21T10:17:13.403 回答