网站执行PHP脚本无法连接smtp.gmail.com:465,CLI运行正常求助
解决网站环境PHP无法连接smtp.gmail.com的问题
这个问题我之前排查过好几次,核心矛盾点在于网站运行的PHP进程和你命令行里的PHP,使用的网络/解析配置完全不一样,所以才会出现命令行正常但网站里报错的情况。下面是具体的排查和解决步骤:
先确认核心问题:域名解析失败
你看到的getaddrinfo failed本质是域名解析不了,先验证这一点:
- 写一个简单的测试脚本
dns-test.php:<?php $ip = gethostbyname('smtp.gmail.com'); var_dump($ip); ?> - 把这个脚本放到网站目录下,通过浏览器访问;同时在命令行执行
php dns-test.php。 - 如果浏览器返回
bool(false),命令行返回正常IP,那确实是Web环境的PHP无法解析这个域名。
针对性解决方法
1. 给Web环境的PHP指定可靠的DNS服务器
Web服务器的PHP进程(比如Apache的mod_php、PHP-FPM)可能没有使用系统默认的DNS,或者默认DNS出问题了。可以强制让它用公共DNS:
- 临时方案(在脚本里加):在建立连接前添加一行:
putenv('RES_OPTIONS="nameserver=8.8.8.8 nameserver=8.8.4.4"'); - 永久方案(修改PHP配置):如果是PHP-FPM,找到对应的pool配置文件(比如
www.conf),添加:
然后重启PHP-FPM服务。env[RES_OPTIONS] = "nameserver=8.8.8.8 nameserver=8.8.4.4"
2. 检查SELinux的限制(针对CentOS/RHEL类系统)
SELinux经常会阻止Web进程发起网络请求,尤其是DNS解析和Socket连接:
- 先临时关闭SELinux测试:
sudo setenforce 0,然后刷新网站测试脚本。 - 如果问题解决了,就把规则永久打开:
(如果用的是PHP-FPM,可能需要对应调整sudo setsebool -P httpd_can_network_connect 1php_fpm_can_network_connect这个布尔值)
3. 对比命令行和Web PHP的配置差异
有时候两个环境的PHP配置不一样,导致网络行为不同:
- 命令行执行
php -i | grep -A 5 "resolv",记录下DNS相关配置。 - 在网站里访问
phpinfo()页面,搜索resolv,对比和命令行的差异,重点看RES_OPTIONS、hosts配置项。
4. 临时应急方案:直接用IP连接
先通过命令行nslookup smtp.gmail.com拿到SMTP服务器的IP,然后把脚本里的ssl://smtp.gmail.com:465改成ssl://[拿到的IP]:465。不过这个是临时方案,因为Gmail的SMTP IP可能会变动,不推荐长期使用。
验证
修改后再运行你的测试脚本,应该就能正常建立Socket连接了。
内容的提问来源于stack exchange,提问作者user1128677
相关产品推荐
相关产品推荐

