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

PHP 7 & Doctrine 2.4.3 : Changing column charset from utf8 to 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'
);

我尝试向 table 添加注释: /* @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 { ... }

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

以上的

None 有效。我在执行 doctrine orm:schema-tool:update --dump-sql 时预计会有一个 ALTER TABLE 查询,但 Doctrine 没有看到任何变化,而且我仍然无法插入 4 字节的表情符号。

如果我自己直接在 MySQL 中更新列的字符集,表情符号会得到支持,但是当我这样做时 运行 orm:schema-tool:update,Doctrine 会发现我的实体和模式之间存在差异,但似乎不知道该怎么做,因为我得到的输出如下: ALTER TABLE post CHANGE text text LONGTEXT NOT NULL ;

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

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

如果你们中的任何人对此事有任何线索,请随时联系我!提前致谢。

整体转换table:

ALTER TABLE tbl CONVERT TO CHARACTER SET utf8mb4;

请提供

SHOW CREATE TABLE ...

更多疑难解答:

由于我有遗留需求并且现在无法更新 Doctrine 的库,我必须找到一个解决方法。

我所做的是使用 SQL 查询手动将我的 tables 转换为 utf8mb4,在执行 [=15] 时不会被 Doctrine 覆盖回 utf8 =] 字符集转换后。

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

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;

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

对于新实体 (tables),在 table 选项中使用正确的设置注释它们确实会使用正确的字符集和排序规则创建它们:

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

干杯。