PHP PDO通过Unix Socket连接PostgreSQL失败,求排查方案
解决Apache下PHP无法连接PostgreSQL Unix套接字的问题
遇到的错误:
SQLSTATE[08006] [7] connection to server on socket "/tmp/.s.PGSQL.5432" failed: No such file or directory
命令行执行PHP脚本可正常连接,但通过Apache(curl访问)触发上述错误,已排查套接字文件存在、关闭SELinux和防火墙,问题仍未解决。
环境配置
- PostgreSQL 14
- Fedora Linux 36(Workstation Edition)
- PHP 4.1.12
- Apache 2.2
已尝试操作
- 确认套接字文件存在且权限正常:
[xxx@mybox~]$ sudo ls -al /tmp/.s.* srwxrwxrwx. 1 postgres postgres 0 Nov 28 12:10 /tmp/.s.PGSQL.5432 -rw-------. 1 postgres postgres 48 Nov 28 12:10 /tmp/.s.PGSQL.5432.lock
- 命令行执行测试脚本
php /var/www/html/lamp/connect.php可正常连接并返回数据 - curl访问脚本
curl http://localhost/lamp/connect.php触发错误 - 关闭SELinux(当前为Permissive模式)和防火墙,问题依旧:
[peter@fedora ~]$ getenforce Permissive
$ firewall-cmd --state not running
测试脚本connect.php代码:
<?php require_once 'config.php'; function connect(string $host, string $db, string $user, string $password): PDO { try { $dsn = "pgsql:host=/tmp;port=5432;dbname=$db"; // make a database connection return new PDO( $dsn, $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); } catch (PDOException $e) { die($e->getMessage()); } } return connect($host, $db, $user, $password);
排查方向及解决方案
1. 关闭Apache的PrivateTmp隔离
Fedora系统中Apache默认开启PrivateTmp,会让Apache进程使用独立的临时目录,无法访问系统全局/tmp下的PostgreSQL套接字:
- 编辑Apache主配置文件
/etc/httpd/conf/httpd.conf,查找PrivateTmp=true配置,改为PrivateTmp=false或直接注释该行 - 重启Apache服务:
sudo systemctl restart httpd
2. 迁移PostgreSQL套接字到非临时目录
若不想修改Apache配置,可将PostgreSQL套接字目录迁移到Apache可访问的路径:
- 编辑PostgreSQL配置文件
/var/lib/pgsql/14/data/postgresql.conf,修改套接字目录参数:
unix_socket_directories = '/var/run/postgresql'
- 创建目录并设置权限:
sudo mkdir -p /var/run/postgresql sudo chown postgres:postgres /var/run/postgresql sudo chmod 775 /var/run/postgresql
- 重启PostgreSQL服务:
sudo systemctl restart postgresql-14 - 修改PHP脚本的DSN,将
host=/tmp改为host=/var/run/postgresql
3. 验证Apache进程的目录访问权限
- 查看Apache运行用户:
ps aux | grep httpd,第一列即为进程所属用户 - 检查
/tmp目录权限:sudo ls -ld /tmp,确保权限包含其他用户执行位(如drwxrwxrwt)
4. 检查PHP pgsql扩展配置
- 查看
php.ini或/etc/php.d/pgsql.ini,确认pgsql.socket参数指向正确的套接字路径,或留空使用默认值
内容的提问来源于stack exchange,提问作者Big Pete
相关产品推荐
相关产品推荐

