Unix Socket连接MySQL必须显式使用unix_socket参数,如"mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=test";host设为localhost或127.0.0.1均不可靠,前者可能触发DNS解析,后者强制走TCP。

Unix Socket连接MySQL的DSN写法必须用unix_socket参数
PHP中PDO连接MySQL走Unix Socket,不能靠把host设成localhost或127.0.0.1来“碰运气”——前者在某些PHP版本里会触发DNS解析,后者强制走TCP。唯一可靠的方式是显式使用unix_socket参数:
$pdo = new PDO(
"mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=test",
$user,
$pass,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
-
unix_socket是PDO MySQL驱动识别Unix Socket的**唯一合法键名**,拼错(如socket、unixsocket)会导致静默降级为TCP连接 - 路径必须与MySQL实际监听路径完全一致,常见位置有
/var/run/mysqld/mysqld.sock(Debian/Ubuntu)、/tmp/mysql.sock(macOS或源码编译安装) - 如果MySQL配置了
skip-networking,TCP连接会被禁用,但Unix Socket仍可用;此时unix_socket是唯一可行路径
MySQLi连接Unix Socket时host和port必须设为null
MySQLi构造函数对参数更敏感,host和port的值直接决定底层是否启用Socket模式:
$mysqli = new mysqli(
null, // host → 必须为 null 或空字符串
$user,
$pass,
'testdb',
null, // port → 必须为 null
'/var/run/mysqld/mysqld.sock' // 第6个参数:sock路径
);
- 若
host填'localhost',MySQLi会尝试Unix Socket,但受系统glibc配置影响,可能 fallback 到IPv6解析,引发延迟 - 若
host填'127.0.0.1'或port设为3306,则**必定走TCP**,unix_socket参数无效(MySQLi不支持该参数) - 第6个参数是唯一指定Socket路径的位置,漏掉或传错类型(如传整数)会导致
mysqli_connect_error()返回空字符串
权限问题常被忽略:PHP进程用户必须能读写Socket文件及其父目录
即使DSN和路径都正确,PDOException报错Connection refused或No such file or directory,大概率是权限卡住:
- Socket文件本身需有读写权限(如
srw-rw----),且属组包含PHP运行用户(如www-data) - 父目录(如
/var/run/mysqld/)必须对PHP用户**可执行(x)**,否则无法进入目录访问socket文件 - Docker中必须显式挂载Socket文件(
-v /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysqld.sock),且挂载后UID/GID需匹配,否则容器内PHP进程无权访问 - 临时验证方式:
sudo -u www-data mysql -S /var/run/mysqld/mysqld.sock -e "SELECT 1;",成功说明权限无问题
MySQL用户权限必须匹配@localhost而非@'%'
通过Unix Socket连接时,MySQL服务端**永远将客户端视为localhost来源**,与IP无关。这意味着:
- 数据库用户必须显式授权给
username@localhost,而不是username@'%'或username@'127.0.0.1' - 执行
GRANT ALL ON test.* TO 'user'@'localhost' IDENTIFIED BY 'pass'; FLUSH PRIVILEGES;才有效 - 若只创建了
user@'%',连接会报错Access denied for user 'user'@'localhost',这是最典型的权限误配现象 - 注意:MySQL 8.0+默认认证插件改为
caching_sha2_password,老版本PHP可能不兼容,必要时加ALTER USER 'user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'pass';
Unix Socket连接看似只是改个路径,但涉及MySQL配置、PHP驱动行为、Linux文件权限、MySQL权限模型四层耦合。任意一层断开,都会表现为“连不上”或“连得慢”,而错误信息往往模糊——比如Connection refused可能是路径错、权限缺、用户没授权,甚至MySQL根本没在监听那个socket。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











