Reputation: 35
I installed a new instance of PHPMyAdmin to work with MySQL8. When accessing the main page I receive an alert with the message:
Notice in ./libraries/classes/Charsets.php#154
Undefined index: utf8mb3
Backtrace
./libraries/classes/Controllers/HomeController.php#163: PhpMyAdmin\Charsets::getServerCharset(,
boolean false,)
./libraries/classes/Routing.php#186: PhpMyAdmin\Controllers\HomeController->index(array)
./index.php#18: PhpMyAdmin\Routing::callControllerForRoute(
string '/',,,)
My MySQL server and client encoding is: utf8. Any idea how I can fix it?
Upvotes: 2
Views: 5652
Reputation: 1711
We are looking for you, please in future report this issues to our GitHub tracker
See: issue #16931
Here is the official fix: a2855079abccc05940286424d3017bf8ca9b3c7d
Solution: install phpMyAdmin 5.1.1 or newer
Upvotes: 1
Reputation: 354
This seems to be caused by a bug in MySQL 8 when setting character_set_server
to utf8
in the MySQL ([mysqld]
) config.
The MySQL manual states:
MySQL immediately converts instances of utf8mb3 in statements to utf8, so in statements such as SHOW CREATE TABLE or SELECT CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLUMNS or SELECT COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS, users see the name utf8 or utf8_collation_substring.
However, the query SHOW VARIABLES LIKE 'character_set_server';
still returns
----------------------+----------+
| Variable_name | Value |
+----------------------+---------+
| character_set_server | utf8mb3 |
+----------------------+---------+
-> utf8mb3
The relevant part of the code in phpMyAdmin can be found in 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;
}
What phpMyAdmin is doing in the method getServerCharset
in libraries/classes/Charsets.php
(which is causing the error) is the following:
It checks whether it has already determined the charset. If not,
it loads an array of charsets available from the MySQL server with the method loadCharsets
. This however is done either by the query SHOW CHARACTER SET;
or by querying information_schema
. In both cases, utf8
(instead of utf8mb3
) is returned, as explained above in the MySQL manual.
Then, it gets the server charset with the query SHOW VARIABLES LIKE 'character_set_server';
(Here, utf8mb3
is returned as the result, as seen above).
There is a fallback (not relevant in our case) due to a bug in MySQL 5.7.8, which we can ignore.
It writes the result into the variable self::$serverCharset
, by getting the array element with the key $serverCharset
(which is utf8mb3
) from the array of all server charsets available . As we know, there is no key utf8mb3
in the array of the available server charsets (only utf8
which is the alias for utf8mb3
). Therefore, the error occurs.
To fix this, either MySQL should instead return utf8
on the query SHOW VARIABLES LIKE 'character_set_server';
, which isn't something we can easily influence (a bug report might have to be created), or we have to work around it in the phpMyAdmin source code.
To do this, I added
if ($serverCharset === "utf8mb3") {
$serverCharset = "utf8";
}
before the line
self::$serverCharset = self::$charsets[$serverCharset];
so that it now looks like this:
/**
* 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;
}
The error should not occur anymore.
Upvotes: 4