PHP 7& Doctrine 2.4.3:将列字符集从utf8更改为utf8mb4

时间:2018-04-20 15:07:09

标签: php mysql utf-8 doctrine-orm utf8mb4

我正在使用Doctrine 2.4.3开发一个项目,该项目使用MySQL 5.7.21数据库,utf8作为默认字符集。

最近,我一直在寻求实施表情符号支持。为了克服MySQL对utf8的3个字节的限制,我需要将可以接收表情符号的列更改为utf8mb4字符集(请参阅https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)。

但是,我还没有找到在我的实体中反映这一点的方法(使用注释)。

我的数据库连接配置如下:

$data = array(
    'driver' => 'pdo_mysql',
    'host' => $dbhost,
    'port' => $dbport,
    'dbname' => $dbname,
    'user' => $dbuser,
    'password' => $dbpw,
    'charset' => 'utf8mb4'
);

我尝试在表格中添加注释: /* @Entity(repositoryClass="path\to\DAO") @Table(name="post", indexes={@Index(name="uid", columns={"uid"})}, options={"charset":"utf8mb4", "collation":"utf8mb4_unicode_ci"}) * @HasLifecycleCallbacks */ class Post extends BaseEntity { ... }

以同样的方式,尝试在列中添加注释(在同一个表中): /* @Column(type="text", options={"charset":"utf8mb4", collation":"utf8mb4_unicode_ci"}) */ protected $text;

以上都没有奏效。我在执行ALTER TABLE时期望doctrine orm:schema-tool:update --dump-sql查询,但Doctrine看不到任何更改,我仍然无法插入4个字节的emojis。

如果我自己直接在MySQL中更新了列的字符集,那么emojis会得到支持,但是当我运行orm:schema-tool:update时,Doctrine看到了我的实体和架构之间的区别,但似乎不知道该怎么做它,因为我得到的输出如下: ALTER TABLE post CHANGE text text LONGTEXT NOT NULL ;

我还尝试在我的数据库连接配置数组中添加SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci driverOptions,唉也没有结果。

不幸的是,我在Doctrine的文档中找不到任何关于此事的内容。

如果你们有任何关于此事的任何线索,请随时打我!提前谢谢。

2 个答案:

答案 0 :(得分:1)

要转换整个表格:

ALTER TABLE tbl CONVERT TO CHARACTER SET utf8mb4;

请提供

SHOW CREATE TABLE ...

有关更多问题排查:Trouble with UTF-8 characters; what I see is not what I stored

答案 1 :(得分:-1)

由于我有遗留的要求而且目前无法更新Doctrine的lib,所以我必须找到解决方法。

我所做的是使用SQL查询手动将我的表转换为utf8mb4,在charset转换后执行utf8时,Doctrine不会将其覆盖回orm:schema-tool:update --force

为了记录,我使用以下脚本生成了更新语句:

SELECT CONCAT('ALTER TABLE ', t.table_schema, '.', t.table_name, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;')
FROM information_schema.tables t
WHERE t.table_schema LIKE {your_schema};

^不要盲目执行 - 事先检查现有数据是否适合utf8mb4编码。有关详细信息,请查看Mathias Bynens关于此事的非常好的文章:https://mathiasbynens.be/notes/mysql-utf8mb4#column-index-length

我还更改了数据库的字符集设置。

ALTER DATABASE {database_name} CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;

我确实将'charset' => 'utf8mb4'保留在Doctrine的数据库连接设置数组中,以便正确传输数据。

对于新实体(表格),使用表格选项中的正确设置对它们进行注释会使用正确的字符集和整理来创建它们:

@Entity @Table(name="table", options={"charset":"utf8mb4", "collate":"utf8mb4_unicode_ci"})

干杯。