#phpmyadmin
Вопрос:
Я установил новый экземпляр phpMyAdmin для работы с MySQL8. При входе на главную страницу я получаю предупреждение с сообщением:
Notice in ./libraries/classes/Charsets.php#154
Undefined index: utf8mb3
Backtrace
./libraries/classes/Controllers/HomeController.php#163: PhpMyAdminCharsets::getServerCharset(,
boolean false,)
./libraries/classes/Routing.php#186: PhpMyAdminControllersHomeController->index(array)
./index.php#18: PhpMyAdminRouting::callControllerForRoute(
string '/',,,)
Моя кодировка сервера и клиента MySQL: utf8.
Есть идеи, как я могу это исправить?
Ответ №1:
Причина
По-видимому, это вызвано ошибкой в MySQL 8 при установке character_set_server
значения utf8
в конфигурации MySQL ( [mysqld]
).
В руководстве по MySQL говорится:
MySQL немедленно преобразует экземпляры utf8mb3 в операторах в utf8, поэтому в таких операторах, как SHOW CREATE TABLE или SELECT CHARACTER_SET_NAME ИЗ INFORMATION_SCHEMA.COLUMNS или SELECT COLLATION_NAME ИЗ INFORMATION_SCHEMA.COLUMNS, пользователи видят имя utf8 или utf8_collation_substring.
Однако запрос SHOW VARIABLES LIKE 'character_set_server';
все равно возвращает
---------------------- ----------
| Variable_name | Value |
---------------------- ---------
| character_set_server | utf8mb3 |
---------------------- ---------
-> utf8mb3
Соответствующую часть кода в phpMyAdmin можно найти в libraries/classes/Charsets.php
:
/**
* Get current server charset
*
* @param DatabaseInterface $dbi DatabaseInterface instance
* @param bool $disableIs Disable use of INFORMATION_SCHEMA
*/
public static function getServerCharset(DatabaseInterface $dbi, bool $disableIs): Charset
{
if (self::$serverCharset !== null) {
return self::$serverCharset;
}
self::loadCharsets($dbi, $disableIs);
$serverCharset = $dbi->getVariable('character_set_server');
if (! is_string($serverCharset)) {// MySQL 5.7.8 fallback, issue #15614
$serverCharset = $dbi->fetchValue('SELECT @@character_set_server;');
}
self::$serverCharset = self::$charsets[$serverCharset];
return self::$serverCharset;
}
То, что phpMyAdmin делает в методе getServerCharset
в libraries/classes/Charsets.php
(который вызывает ошибку), заключается в следующем:
- Он проверяет, определил ли он уже кодировку. Если нет,
- он загружает массив кодировок, доступных с сервера MySQL с помощью этого метода
loadCharsets
. Однако это делается либо с помощью запросаSHOW CHARACTER SET;
, либо с помощью запросаinformation_schema
. В обоих случаяхutf8
возвращается (вместоutf8mb3
), как описано выше в руководстве MySQL. - Затем он получает кодировку сервера с запросом
SHOW VARIABLES LIKE 'character_set_server';
(здесьutf8mb3
возвращается как результат, как показано выше). - Существует запасной вариант (не относящийся к нашему случаю) из-за ошибки в MySQL 5.7.8, которую мы можем игнорировать.
- Он записывает результат в переменную
self::$serverCharset
, получая элемент массива с ключом$serverCharset
(который естьutf8mb3
) из массива всех доступных кодировок сервера . Как мы знаем,utf8mb3
в массиве доступных кодировок сервера нет ключа (толькоutf8
для которого используется псевдонимutf8mb3
). Следовательно, возникает ошибка.
Как это исправить
Чтобы исправить это, либо MySQL должен вместо этого вернуться utf8
к запросу SHOW VARIABLES LIKE 'character_set_server';
, на который мы не можем легко повлиять (возможно, потребуется создать отчет об ошибке), либо нам придется обойти это в исходном коде phpMyAdmin.
Для этого я добавил
if ($serverCharset === "utf8mb3") {
$serverCharset = "utf8";
}
перед строкой
self::$serverCharset = self::$charsets[$serverCharset];
так что теперь это выглядит так:
/**
* Get current server charset
*
* @param DatabaseInterface $dbi DatabaseInterface instance
* @param bool $disableIs Disable use of INFORMATION_SCHEMA
*/
public static function getServerCharset(DatabaseInterface $dbi, bool $disableIs): Charset
{
if (self::$serverCharset !== null) {
return self::$serverCharset;
}
self::loadCharsets($dbi, $disableIs);
$serverCharset = $dbi->getVariable('character_set_server');
if (! is_string($serverCharset)) {// MySQL 5.7.8 fallback, issue #15614
$serverCharset = $dbi->fetchValue('SELECT @@character_set_server;');
}
if ($serverCharset === "utf8mb3") {
$serverCharset = "utf8";
}
self::$serverCharset = self::$charsets[$serverCharset];
return self::$serverCharset;
}
Ошибка больше не должна возникать.
Комментарии:
1. Спасибо! Это исправило фатальную ошибку. Планируете ли вы включить это исправление в будущий выпуск?
Ответ №2:
Мы ищем вас, пожалуйста, в будущем сообщайте об этих проблемах на наш трекер GitHub
См.: выпуск №16931
Вот официальное исправление: a2855079abccc05940286424d3017bf8ca9b3c7d
Решение: установите phpMyAdmin 5.1.1 или новее