我正在运行 Ubuntu 22.04、nginx 1.18.0、mariadb 15.1 和 PHP 8.1.2。这是我的代码database.php

<?php

$SERVER_APP = "localhost";
$DATABASE_APP = "mydb";
$USERNAME_APP = "root";
$PASSWORD_APP = "password";

function db_connect() {
    global $SERVER_APP, $DATABASE_APP, $USERNAME_APP, $PASSWORD_APP;

    try {
        $dbApp = new PDO("mysql:host=$SERVER_APP;dbname=$DATABASE_APP", $USERNAME_APP, $PASSWORD_APP);
        $dbApp->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $dbApp->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        echo "Connected to db";
        return $dbApp;
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
}

如果我从命令行执行此代码:

php -r "require 'database.php'; db_connect();"

它工作正常:

已连接到数据库

我还可以使用以下方法连接到 SQL 数据库:

mysql -u root -p

并输入相同的密码。但是当从 PHP 脚本调用上述函数时,如下所示samples.php

<?php header("Access-Control-Allow-Origin: *");
header("Content-type: application/json");
require 'database.php';

ini_set('display_errors', 1);
error_reporting(E_ALL);

$dbApp = db_connect();  
$stmt = $dbApp->prepare("SELECT * FROM sensors WHERE sampled > (now() - interval 24 hour) ORDER BY sampled;");
$stmt->execute();
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($results);

$dbApp = null;

而它又被调用自index.php

// url = 'samples.php'
function get_samples(url) {
    fetch(window.location.protocol + "//" + window.location.hostname + ":3001" + url, {
        method: "GET",
        headers: {
            "Content-Type": "application/json"
        },
    })
    .then(response => response.text())
    .then(text => {
        // do something
    })
    .catch(error => console.error(error))
}

连接数据库失败:

SQLSTATE[HY000] [1698] 拒绝用户 ‘root’@’localhost’ 访问

当然,数据库位于同一台服务器上,即localhost。如果从控制台手动调用相同的脚本时运行正常,那么什么原因会导致访问被拒绝错误?


最佳答案
1

mariadb 15.1 你确定吗?

您面临的问题可能与 MySQL 根用户在 Ubuntu 中的身份验证配置方式有关。默认情况下,在 Ubuntu 系统上,根 MySQL 用户从本地计算机访问时通常使用基于套接字的身份验证,而不是基于密码的身份验证。这意味着当您使用命令行连接时,系统会根据操作系统登录会话将用户验证为根用户,而无需密码。

但是,当通过 Web 服务器(如 Nginx 或 Apache)执行 PHP 脚本时,它不会通过套接字进行身份验证,因此无法使用您提供的密码进行身份验证。

不要使用 root 用户(不建议用于 Web 应用程序),而是专门为您的应用程序创建一个新的 MySQL 用户,并授予其必要的权限。

CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'newpassword';
GRANT ALL PRIVILEGES ON mydb.* TO 'newuser'@'localhost';
FLUSH PRIVILEGES;

1

  • 关于版本:mariadb --version mariadb Ver 15.1 Distrib 10.6.18-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper如果我没记错的话是 15.1


    –