繁体   English   中英

Phpmyadmin 字符集致命错误“未定义索引:utf8mb3”

[英]Phpmyadmin Charsets fatal error 'Undefined index: utf8mb3'

我安装了一个新的 PHPMyAdmin 实例来使用 MySQL8。 访问主页时,我收到一条带有消息的警报:

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 '/',,,)

我的 MySQL 服务器和客户端编码是:utf8。 知道如何解决吗?

原因

这似乎是由 MySQL ( [mysqld] ) 配置中的character_set_server设置为utf8时 MySQL 8 中的错误引起的。

MySQL 手册指出:

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.

但是,查询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 在libraries/classes/Charsets.php (导致错误)的方法getServerCharset中执行的操作如下:

  • 它检查是否已经确定了字符集。 如果不,

  • 它使用 loadCharsets 方法从loadCharsets服务器加载一组可用的字符集。 然而,这可以通过查询SHOW CHARACTER SET; 或通过查询information_schema 在这两种情况下,都会返回utf8 (而不是utf8mb3 ),如上文 MySQL 手册中所述。

  • 然后,它通过查询SHOW VARIABLES LIKE 'character_set_server';获取服务器字符集。 (这里, utf8mb3作为结果返回,如上所示)。

  • 由于 MySQL 5.7.8 中的错误,我们可以忽略它,因此有一个回退(在我们的案例中不相关)。

  • 它通过从所有可用服务器字符集的数组中获取带有键$serverCharset (即utf8mb3 )的数组元素,将结果写入变量self::$serverCharset 众所周知,可用服务器字符集的数组中没有键utf8mb3 (只有utf8utf8mb3的别名)。 因此,会发生错误。

如何修复它

要解决此问题,MySQL 应改为在查询SHOW VARIABLES LIKE 'character_set_server';上返回utf8 ,这不是我们可以轻易影响的(可能必须创建错误报告),或者我们必须在 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;
}

该错误不应再发生。

我们正在寻找您,请在以后将此问题报告给我们的 GitHub 跟踪器

请参阅:问题 #16931

这是官方修复: a2855079abccc05940286424d3017bf8ca9b3c7d

解决方案:安装 phpMyAdmin 5.1.1 或更新版本

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM