我在PHP 7.0上使用最新的PHPMailer 5.2.24(问题与旧版本相同)。
使用Exchange 2016通过SMTP发送邮件。大约95%的邮件按预期工作,但每当从Exchange到最终DATA END命令的250响应持续时间超过30秒时,流似乎就会中止。
PHPMailer中的超时设置为300,在日志中我可以确认超时不是问题。
事实上,据我所知,所有邮件都是成功发送的(我在30个案例中约有30个证实了这一点)。
$this->mailer->isSMTP();
$this->mailer->Timeout = 300;
$this->mailer->Host = 'mail.myhost.com';
$this->mailer->SMTPAuth = true;
$this->mailer->Username = 'Domain\\Username';
$this->mailer->Password = '*****';
$this->mailer->SMTPSecure = 'tls';
$this->mailer->Port = 587;
低级日志示例:(我在class.smtp.php的get_lines()中添加了2个自定义调试输出,以显示fgets()返回false并显示stream_get_meta_data())
2017-08-23 13:46:05 Level 1; message: CLIENT -> SERVER: .
2017-08-23 13:46:35 Level 4; message: SMTP -> get_lines(): $data is ""
2017-08-23 13:46:35 Level 4; message: SMTP -> get_lines(): $str === false
2017-08-23 13:46:35 Level 4; message: SMTP -> [timed_out => false, blocked => 1, eof => 1, stream_type => tcp_socket/ssl, mode => r+, unread_bytes => 0, seekable => false]
2017-08-23 13:46:35 Level 2; message: SERVER -> CLIENT:
2017-08-23 13:46:35 Level 1; message: SMTP ERROR: DATA END command failed:
在响应速度超过30秒的其他情况下,它看起来像:
2017-08-23 23:25:02 Level 1; message: CLIENT -> SERVER: .
2017-08-23 23:25:28 Level 4; message: SMTP -> get_lines(): $data is ""
2017-08-23 23:25:28 Level 4; message: SMTP -> get_lines(): $str is "250 2.6.0 <...> [InternalId=10677288697896, Hostname=myhost] 32443 bytes in 26.353, 1,202 KB/sec Queued mail for delivery"
2017-08-23 23:25:28 Level 2; message: SERVER -> CLIENT: 250 2.6.0 <...> [InternalId=10677288697896, Hostname=myhost] 32443 bytes in 26.353, 1,202 KB/sec Queued mail for delivery
2017-08-23 23:25:28 Level 1; message: CLIENT -> SERVER: QUIT
那可能是什么
$str = fgets($this->smtp_conn, 515);
因为它不是流的超时而不是php运行时超时,在30秒(执行后30秒,而不是脚本启动)之后导致失败。 (这里没有抛出异常,我从原始PHPMailer代码中的fgets()中删除了@来确认这一点)
脚本在没有max_execution_time的情况下运行。
我的Exchange管理员不知道是什么导致这种情况,我没有意义开始,因为我甚至不知道流中断的位置 - PHP,Webserver,Exchange,介于两者之间?
任何想法我还能检查什么或可能导致什么?
答案 0 :(得分:0)
我猜这是PHP安装的max_execution_time
,默认为30秒,而且它总是在这里失败,因为这是代码中唯一需要花费很长时间的东西。
尝试在php.ini中增加它或事先调用set_time_limit()
。