skip to Main Content

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: PhpMyAdminCharsets::getServerCharset(,
boolean false,)
./libraries/classes/Routing.php#186: PhpMyAdminControllersHomeController->index(array)
./index.php#18: PhpMyAdminRouting::callControllerForRoute(
string '/',,,)

My MySQL server and client encoding is: utf8.
Any idea how I can fix it?

2

Answers


  1. Cause

    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.

    How to fix it

    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.

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search