mysqli是否在PHP 7.4中支持caching_sha2_password?

时间:2019-12-07 23:27:27

标签: php mysql authentication mysqli php-7.4

当我尝试从PHP 7.3升级到PHP 7.4时,收到此错误:

  

执行caching_sha2身份验证109时服务器意外响应

正如我所看到的,这表明PHP 7.4 MySQLi正在尝试使用caching_sha2_password插件。 This article指出PHP MySQLi不支持该插件(它也暗示了对该插件的未来支持),但是由于PHP 7.4是新的并且似乎正在尝试使用它,因此我认为它应该可以工作。错误消息也与不支持的错误消息不同(拒绝访问身份验证方法未知)。

因此,我将MySQL身份验证插件更改为caching_sha2_password(使用与以前相同的密码):

ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '';
FLUSH PRIVILEGES;

但这会导致另一个错误:

  

拒绝用户'root'@'localhost'的访问(使用密码:是)。

切换回PHP 7.3和mysql_native_password可以再次使用。

我为两个插件使用了相同的密码,在相同的网站上使用了相同的php.ini更改。 但是,我没有更改任何mysqli配置。 MySQL的日志不显示任何内容,而apache2日志仅显示“访问被拒绝”错误消息。

php7.4-mysqli是否支持caching_sha2_password

为什么我的密码被拒绝以及如何解决? See my follow-up question

此外,如果MySQLi仍不支持该插件:我该如何使用mysql_native_password

2 个答案:

答案 0 :(得分:5)

我对此进行了测试,PHP 7.4中的mysqli确实支持caching_sha2_password。

php -v
PHP 7.4.0 (cli) (built: Nov 29 2019 16:18:44) ( NTS )

这是我编写的一个简单的PHP脚本,用于连接在docker容器(使用端口6603)中运行的MySQL 8.0.17:

<?php
error_reporting(E_ALL);
$conn = new mysqli('127.0.0.1', 'root', 'root', '', 6603);
$result = $conn->query("SELECT NOW()");
$now = $result->fetch_row()[0];
echo "$now\n";

我确认我的MySQL实例正在使用caching_sha2_password:

mysql> select user,host,plugin from mysql.user where user='root';
+------+-----------+-----------------------+
| user | host      | plugin                |
+------+-----------+-----------------------+
| root | %         | caching_sha2_password |
| root | localhost | caching_sha2_password |
+------+-----------+-----------------------+

mysql> select @@default_authentication_plugin;
+---------------------------------+
| @@default_authentication_plugin |
+---------------------------------+
| caching_sha2_password           |
+---------------------------------+

运行我的PHP脚本,成功了。

php my.php
2019-12-08 18:11:58

但是,当我尝试像您一样将密码更改为''时,我能够重现相同的错误:

  

PHP警告:mysqli :: __ construct():执行caching_sha2 auth时服务器意外响应:在第5行的/Users/bkarwin/Documents/SO/my.php中为0

当我恢复密码时,将其设置为非空白字符串,就可以解决此问题。

请勿使用空密码。

答案 1 :(得分:3)

有两种方法可以实现

  1. 您正在使用int userInput = Convert.ToInt32(Console.ReadLine()); bool exists= false; foreach (KeyValuePair<int,Library> lib in dictionary) { if (userInput == lib.Key) { Console.WriteLine("You chose book = {0}",lib.Value.bookName); exists = true; } } if(!exists){ Console.WriteLine("Wrong Input"); } 身份验证方法。通过使用MySQL CLI界面连接到MySQL,PHP就是本机使用它的方式。 MySQL自己的客户端将始终支持其自己的身份验证方法。
  2. 您正在使用7.4下的MySQLND。显然this was an improvement to the native driver没有宣布

      

    是的,由于对ext / hash的高度依赖,目前仅在7.4中。

    There are still some possible issues with it.