0

我在 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,介于两者之间?

任何想法我还能检查什么或什么可能导致这种情况?

4

1 回答 1

0

我猜这max_execution_time是你的 PHP 安装,默认为 30 秒,它碰巧总是在这里失败,因为这是你的代码中唯一需要这么长时间的东西。

尝试在您的 php.ini 中增加它或set_time_limit()预先调用。

于 2017-08-24T09:19:24.467 回答