在 CentOS 7.6 这个版本上搭建 PHP + MySQL(或者更准确地说是 MariaDB,因为 CentOS 7 默认用 MariaDB)并让网站连通数据库,核心不在于“安装”,而在于权限配置和连接参数。很多新手装完服务后,网站报错 Access denied 或 Connection refused,通常是因为没处理好这几步。
下面按实际生产环境的标准流程,把关键节点拆解清楚。
第一步:确认服务状态与监听端口
首先得确定你的数据库服务真的在跑,并且监听了正确的端口。CentOS 7 默认使用 systemd 管理。
# 检查 MySQL/MariaDB 状态
systemctl status mariadb.service
# 或者如果是纯 MySQL
systemctl status mysqld.service
# 确保开机自启
systemctl enable mariadb.service
如果状态是 active (running),接下来看它监听哪里。默认情况下,MySQL/MariaDB 只监听本地回环地址 127.0.0.1 的 3306 端口。
netstat -tlnp | grep 3306
输出应该类似:
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 1234/mysqld
注意: 如果你的网站代码和数据库在同一台服务器上,PHP 连接时主机填 localhost 或 127.0.0.1 都可以。但如果填的是域名,且没有做 DNS 解析指向本机,可能会走 TCP 而非 Unix Socket,导致性能差异或连接失败。建议开发阶段统一用 127.0.0.1。
第二步:初始化安全设置(至关重要)
刚装好的数据库,root 用户可能有空密码或者随机密码。必须运行安全脚本。
/usr/bin/mysql_secure_installation
这里会问几个问题:
- VALIDATE PASSWORD PLUGIN: 选
N(除非你有严格的合规要求,否则没必要折腾复杂密码策略)。 - Set root password?: 选
Y,设置一个强密码。记住这个密码,后面要用。 - Remove anonymous users?: 选
Y。 - Disallow root login remotely?: 选
Y。这一点很重要,生产环境严禁 root 远程登录。 - Remove test database?: 选
Y。 - Reload privilege tables now?: 选
Y。
第三步:创建专用数据库和用户(不要直接用 root)
这是最容易出错的地方。很多教程直接让你用 root 连数据库,这在 Web 应用里是大忌。一旦网站被注入攻击,黑客就拥有了服务器的最高权限。
我们需要创建一个专门的库和用户。
-
登录数据库:
mysql -u root -p # 输入刚才设置的 root 密码 -
执行 SQL 语句(假设你的网站叫
my_website):-- 1. 创建数据库,指定字符集为 utf8mb4(支持 emoji 等完整 Unicode) CREATE DATABASE my_website DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 2. 创建用户 'web_user',允许从 localhost 连接 -- 注意:密码要够复杂,这里用示例 CREATE USER 'web_user'@'127.0.0.1' IDENTIFIED BY 'YourStrongPassword123!'; -- 3. 授权该用户仅对 my_website 库有所有权限 GRANT ALL PRIVILEGES ON my_website.* TO 'web_user'@'127.0.0.1'; -- 4. 刷新权限,立即生效 FLUSH PRIVILEGES; -- 5. 退出 EXIT;
关键点解释:
'web_user'@'127.0.0.1':限制了只能从本机 IP 连接。如果你未来要做主从复制或者容器化部署,可能需要改为'%'或特定内网 IP,但初期务必限制。utf8mb4:现在建站标配,避免中文乱码和表情符号报错。
第四步:PHP 侧的配置与测试
确保你的 PHP 安装了 MySQL 扩展。CentOS 7.6 上通常是 php-mysqlnd 或 php-mysqli。
# 检查是否已安装
php -m | grep mysql
如果没有输出,需要安装:
yum install php-mysqlnd
# 重启 Apache/Nginx + PHP-FPM
systemctl restart httpd # 或 nginx
systemctl restart php-fpm
编写测试脚本
在网站根目录(如 /var/www/html/)下创建一个 test_db.php:
<?php
$host = '127.0.0.1'; // 必须用 127.0.0.1,不要用 localhost,避免 socket 路径问题
$dbname = 'my_website';
$username = 'web_user';
$password = 'YourStrongPassword123!';
// 使用 mysqli 连接
$conn = new mysqli($host, $username, $password, $dbname);
// 检查连接
if ($conn->connect_error) {
die("连接失败: " . $conn->connect_error);
} else {
echo "数据库连接成功!";
// 可选:查一下当前时间,验证读写能力
$result = $conn->query("SELECT NOW()");
if ($row = $result->fetch_row()) {
echo "<br>当前服务器时间: " . $row[0];
}
}
$conn->close();
?>
访问 http://你的IP/test_db.php。
- 如果显示“连接成功”:说明网络、权限、账号密码都没问题。
- 如果报
Access denied:90% 是用户名、密码错了,或者用户主机限制不对(比如你建的是'web_user'@'localhost',但 PHP 连的是127.0.0.1,在某些 MySQL 版本中这两者被视为不同用户)。 - 如果报
Can't connect to local MySQL server through socket:PHP 试图通过 Unix Socket 连接,但找不到文件。解决方法是在 PHP 连接字符串中强制指定127.0.0.1,或者修改php.ini中的mysqli.default_socket指向实际的 socket 路径(通常在/var/lib/mysql/mysql.sock)。
第五步:常见坑位排查
-
SELinux 拦截:
CentOS 7 默认开启 SELinux。如果上述步骤都对了还是连不上,可能是 SELinux 阻止了 Apache/Nginx 访问数据库 socket 或发起网络连接。临时测试方法:
setenforce 0如果关掉后能连上了,说明是 SELinux 问题。生产环境不建议直接关闭,而是设置布尔值:
setsebool -P httpd_can_network_connect_db 1 -
防火墙端口:
如果你打算从其他机器连接这台数据库,需要开放 3306 端口:firewall-cmd --permanent --add-port=3306/tcp firewall-cmd --reload但再次强调,Web 服务器和数据库在同一台机器时,不需要开放 3306 到公网,甚至不需要对内网开放,只用 localhost 通信最安全。
-
PHP 版本兼容性:
CentOS 7.6 默认的 PHP 是 5.4 或 7.0(取决于你是否加了第三方源如 Remi)。现代框架(Laravel, ThinkPHP 等)通常需要 PHP 7.2+。如果 PHP 版本太低,可能根本不支持新的 MySQL 认证协议(caching_sha2_password),导致连接失败。遇到这种情况,要么升级 PHP,要么将 MySQL 用户的认证插件改回mysql_native_password:ALTER USER 'web_user'@'127.0.0.1' IDENTIFIED WITH mysql_native_password BY 'YourStrongPassword123!'; FLUSH PRIVILEGES;
总结
连接成功的标志不是“服务启动了”,而是“PHP 能拿着正确的账号密码,通过正确的 IP 地址,拿到数据库的返回结果”。
按照 创建独立用户 -> 授权特定库 -> 使用 127.0.0.1 连接 -> 排除 SELinux 这个逻辑走,基本不会出问题。别偷懒用 root 直连,这对网站安全来说是埋雷。
云技术博客