linux上搭php+mysql成功的关键在于四点对齐:web服务器与php的通信方式、php版本与扩展兼容性、mysql服务状态与权限配置、三者间路径/端口/用户权限的显式匹配;任一缺失都会导致phpinfo()正常但mysqli_connect()报错。

直接说结论:Linux上搭PHP+MySQL,不是“装完就跑”,关键在四点对齐——Web服务器与PHP的通信方式、PHP版本与扩展的兼容性、MySQL服务状态与权限配置、以及三者间路径/端口/用户权限的显式匹配。漏掉任一环,phpinfo()能跑,mysqli_connect()必报错。
Apache/Nginx怎么连PHP:别只装php-fpm就以为完事
Apache默认用libapache2-mod-php(Ubuntu)或mod_php(RHEL),走模块直连;Nginx必须配php-fpm,走FastCGI代理。两者不能混用,也不能靠“自动识别”。
- Apache下装了
php8.1-fpm但没禁用libapache2-mod-php?请求会进错处理链,phpinfo()显示但数据库连接超时 - Nginx配置里
fastcgi_pass写成127.0.0.1:9000,但php-fpm实际监听/run/php/php8.1-fpm.sock?502 Bad Gateway立刻出现 - Ubuntu 22.04+默认
php-fpm服务名是php8.1-fpm,不是php-fpm;CentOS 8+用php-fpm但需确认systemctl status php-fpm是否真在运行
PHP扩展不是“越多越好”:mysqli和pdo_mysql必须显式启用
装PHP时只跑sudo apt install php8.1,mysql扩展根本不会装。哪怕php -v成功,mysqli_connect()也会抛Fatal error: Uncaught Error: Call to undefined function mysqli_connect()。
- Ubuntu/Debian必须加装:
php8.1-mysql(提供mysqli)和php8.1-pdo(PDO基础);缺php8.1-pdo-mysql,PDO::mysql驱动就不存在 - CentOS/RHEL启用Remi源后,
php-mysqlnd替代旧版php-mysql,它支持原生驱动,但要求MySQL服务开启skip-networking=off(否则本地socket连接失败) -
php -m | grep -E "^(mysqli|pdo|mysql)"要同时看到三行输出,才算真正就绪;光有pdo没pdo_mysql,new PDO('mysql:host=localhost',...)直接挂
MySQL root密码和socket路径:localhost ≠ 127.0.0.1
PHP代码里写mysqli_connect('localhost', 'root', 'xxx'),连不上≠密码错。Linux下localhost强制走Unix socket,127.0.0.1才走TCP——而MySQL默认只监听socket,不开放TCP端口。
- 查MySQL监听:
sudo ss -tlnp | grep :3306,没输出说明TCP关闭;sudo ss -lnp | grep mysql应看到/var/run/mysqld/mysqld.sock之类路径 - PHP连接时若用
localhost,必须确保php.ini里mysqli.default_socket或pdo_mysql.default_socket指向真实socket路径(如/var/run/mysqld/mysqld.sock),否则连不上 - 重置root密码后,如果用
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx';,记得FLUSH PRIVILEGES;;否则PHP仍按旧认证插件尝试握手,报Authentication plugin 'caching_sha2_password' cannot be loaded
测试脚本别只写phpinfo():三行代码验通路
phpinfo()只证明PHP解析器工作,不证明MySQL可达。真正验证得用能触发实际连接的代码,且必须覆盖错误捕获。
- 最小验证脚本(存为
/var/www/html/test_db.php):
<?php $host = 'localhost'; // 或 '127.0.0.1'
$user = 'root';
$pass = 'your_real_password';
$dsn = "mysql:host=$host;dbname=mysql;charset=utf8mb4";
try {
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
echo "✅ PDO 连接成功<br>";
$stmt = $pdo->query("SELECT VERSION()");
echo "MySQL 版本:" . $stmt->fetchColumn();
} catch (PDOException $e) {
echo "❌ 连接失败:" . $e->getMessage();
}>
- 执行前确认:
chown -R www-data:www-data /var/www/html/(Ubuntu)或chown -R apache:apache /var/www/html/(RHEL),否则Web服务器进程无权读脚本 - 浏览器访问该地址,看到✅才真通;任何❌信息里的关键词(如
Connection refused、No such file or directory、Access denied)直接对应上面三步的排查点
最常被跳过的细节:PHP-FPM pool配置里listen.owner和listen.group没设成Web服务器用户(如www-data),导致Nginx无法访问.sock文件——错误日志里只有connect() to unix:/run/php/php8.1-fpm.sock failed (13: Permission denied),但没人去看ls -l /run/php/的实际属主。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











