[5.x]: MySQL DSN in config array bypasses charset

Đã đóng Phù hợp với người mới
#20,248 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
62/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
mariadb, mysql, php
Lĩnh vực
databases

Hướng nghiên cứu

Bắt đầu với DbConfig::init() trong các lớp cấu hình của Craft, hàm này bỏ qua _updateDsn() khi có DSN được cung cấp, nên driver vẫn là null. App::dbConfig() đọc driver từ DSN, vì vậy hãy so sánh hai nơi này. getCharset() nên trả về utf8mb4 cho MySQL sau khi driver đã được xác định. Hoàn thành khi new DbConfig(['dsn' => 'mysql:host=localhost;dbname=example'])->getCharset() trả về utf8mb4 và driver được thiết lập, kèm một unit test bao phủ trường hợp này.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug repo:cms
What happened?

When a MySQL DSN is supplied through a database config array, DbConfig::$driver remains null. This causes getCharset() to return utf8 instead of normalizing it to utf8mb4.

On MariaDB, creating a table with Craft’s default collation then produces an incompatible combination:

DEFAULT CHARACTER SET = utf8 DEFAULT COLLATE = utf8mb4_unicode_ci

MariaDB rejects this with:

COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER SET 'utf8mb3'
Steps to reproduce

This can be reproduced without connecting to a database:

$config = new \craft\config\DbConfig([
    'dsn' => 'mysql:host=localhost;dbname=example',
]);

var_dump($config->driver);       // null
var_dump($config->getCharset()); // "utf8"

For comparison, explicitly supplying the driver returns the expected charset:

$config = new \craft\config\DbConfig([
    'dsn' => 'mysql:host=localhost;dbname=example',
    'driver' => 'mysql',
]);

var_dump($config->getCharset()); // "utf8mb4"
Expected behavior

Craft should recognize the MySQL driver from the DSN and normalize the default charset to utf8mb4, consistently with the fluent dsn() method.

Additional information

DbConfig::init() skips _updateDsn() when a DSN is already supplied, leaving the driver unset. Meanwhile, App::dbConfig() reads the driver directly from the DSN, so the connection can work despite the missing configured driver.

Explicitly setting charset to utf8mb4 works around the issue.

Found while investigating Blitz #929.

Tested on Craft 5.11.5.1, but may affect other versions as well.

Craft CMS version

5.11.5.1

PHP version

No response

Operating system and version

No response

Database type and version

No response

Image driver and version

No response

Installed plugins and versions
Ngôn ngữ chính
PHP
Star
3.6k
Fork
714
Merge trung bình
13 giờ 9 phút
Pull request đã merge (30 ngày)
378

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của craftcms/cms

Tất cả issue của craftcms/cms

Issue tương tự

Thêm issue về PHP

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.