我有一个应用程序在PHP 7.2上使用PHPMailer发送电子邮件,我必须发送大约50封电子邮件,大约需要40秒才能完成,我认为这很多,因为根据文档,它最多可以发送300封电子邮件。第二...我尝试使用本地电子邮件服务器和Google SMTP服务(这是我们需要的,因为它将使用GSuite电子邮件作为发件人)。该函数接收一个包含每个客户所需数据的数组,但是我创建了smtp对象及其在循环外的配置,对每个客户执行一次的唯一方法是send(),如果我注释该行,它将只需不到1秒的时间即可完成,因此连接不会延迟执行,它只是send()本身。我做错了什么吗?我对该库没有太多经验,并且它是基于基本示例的,因此我不确定是否可以添加或更改任何配置以加快此速度。
public static function ejecutarEnvio($datosCorreo) {
try {
$mail = new PHPMailer(true);
// Configuración general
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->isSMTP();
$mail->CharSet = 'utf-8';
$mail->Host = $_SESSION["smtp_host"];
$mail->Username = $_SESSION["smtp_user"];
$mail->Password = $_SESSION["smtp_pass"];
$mail->Port = $_SESSION["smtp_port"];
if ($_SESSION["smtp_secure"]=="TLS")
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
elseif ($_SESSION["smtp_secure"]=="SSL")
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->SMTPAuth = true;
$mail->SMTPKeepAlive = true;
$mail->isHTML(true);
$mail->setFrom($_SESSION["no_reply"], $_SESSION["no_reply_name"]);
// envío independiente
for ($i = 0; $i < count($datosCorreo); $i++) {
$datos = $datosCorreo[$i];
// se cargan todas las variables que pueden cambiar en el arreglo de objetos para enviar correo
if(filter_var(trim($datos['destinatario1']), FILTER_VALIDATE_EMAIL))
$mail->addAddress(trim($datos['destinatario1']));
if(filter_var(trim($datos['destinatario2']), FILTER_VALIDATE_EMAIL))
$mail->addCC(trim($datos['destinatario2']));
if(filter_var(trim($datos['destinatario3']), FILTER_VALIDATE_EMAIL))
$mail->addCC(trim($datos['destinatario3']));
$mail->addReplyTo($datos['replyto']);
$mail->Subject = $datos['titulo'];
$mail->Body = $datos['mensaje'];
// se cargan todas las variables que pueden cambiar en el arreglo de objetos para enviar correo
try {
// intento hacer el envio del correo, lo hago dentro de un try independiente para que solo afecte al objeto actual
if ($mail->send())
$datosCorreo[$i]['mensaje_correo'] = "";
else
throw new Exception("Error enviando el correo. " . $mail->ErrorInfo);
} catch (Exception $e) {
$datosCorreo[$i]['mensaje_correo'] = $e->getMessage();
}
$mail->clearAddresses();
}
$mail->SmtpClose();
} catch (Exception $e) {
for ($i = 0; $i < count($datosCorreo); $i++) {
$datosCorreo[$i]['mensaje_correo'] = "Error configurando el envío de correo. " . $e->getMessage();;
}
}
return $datosCorreo;
}
感谢您的帮助!
答案 0 :(得分:0)
PHPMailer Wiki具有广泛的advice on sending to lists,并提供了一个示例,演示了how to send to lists efficiently。
最重要的是,不是每次都创建一个新实例,而是重新使用一个实例,这使您可以启用SMTP keepalive。
$mail->SMTPKeepAlive = true;
我可以在这里看到您正在执行此操作,但是您还可以执行其他操作。通过SMTP发送到localhost时,您无需使用身份验证或加密,因此可以将其禁用:
$mail->SMTPAuth = false;
$mail->SMTPSecure = false;
$mail->SMTPAutoTLS = false;
这将消除多次往返。
花费send
花费时间的原因是,PHPMailer在此之前几乎没有做任何事情-一切都已设置。
您正在验证循环中的电子邮件地址-addAddress()
和addCC
已经这样做了,因此您在重复工作;而是检查其返回值,并continue
;如果地址不正确,则忽略。
此结构是多余的:
try {
// intento hacer el envio del correo, lo hago dentro de un try independiente para que solo afecte al objeto actual
if ($mail->send())
$datosCorreo[$i]['mensaje_correo'] = "";
else
throw new Exception("Error enviando el correo. " . $mail->ErrorInfo);
} catch (Exception $e) {
$datosCorreo[$i]['mensaje_correo'] = $e->getMessage();
}
您可以将其简化为这个原因,因为您已经要求PHPMailer将错误抛出异常(通过将true
传递给构造函数),因此它将永远不会达到您抛出自己的异常的地步:
try {
$mail->send();
// intento hacer el envio del correo, lo hago dentro de un try independiente para que solo afecte al objeto actual
$datosCorreo[$i]['mensaje_correo'] = "";
} catch (Exception $e) {
$datosCorreo[$i]['mensaje_correo'] = $e->getMessage();
}
我毫不费力地每秒发送数百封邮件,任何体面的本地邮件服务器都应该能够每秒处理数千封邮件,因此这不是原因,但您应该检查一下。
要找出瓶颈在任何代码中的位置,我建议在IDE中使用探查器,而不要使用随机定时调用。它会立即告诉您问题出在哪里。带有qcachegrind或PHPStorm的xdebug对此非常有效。