Saltar al contenido

Hacer asincrónico el mail() de PHP

Nuestro equipo de redactores ha estado mucho tiempo buscando para darle resolución a tu búsqueda, te dejamos la soluciones de modo que deseamos servirte de gran apoyo.

Solución:

Tiene muchas maneras de hacer esto, pero manejar el hilo no es necesariamente la elección correcta.

  • register_shutdown_function: la función de apagado se llama después de enviar la respuesta. No es realmente asíncrono, pero al menos no ralentizará su solicitud. En cuanto a la implementación, ver el ejemplo.
  • Piscina rápida: usando Symfony, puedes usar fácilmente el carrete.
  • Cola: registre los correos que se enviarán en un sistema de cola (se puede hacer con RabbitMQ, MySQL, redis o cualquier cosa), luego ejecute un cron que consuma la cola. Podría hacerse con algo tan simple como una tabla MySQL con campos como from, to, message, sent (establecido booleano en true cuando haya enviado el correo electrónico).

Ejemplo con register_shutdown_function

 $subject, 'to' => $to, 'message' => $message ];
  

  public static function send() 
  
    foreach(self::$mails as $mail) 
      mail($mail['to'], $mail['subject'], $mail['message']);
    
  


//In your script you can call anywhere
MailSpool::addMail('Hello', '[email protected]', 'Hello from the spool');


register_shutdown_function('MailSpool::send');

exit(); // You need to call this to send the response immediately

php-fpm

Debe ejecutar php-fpm para que fastcgi_finish_request esté disponible.

echo "I get output instantly";
fastcgi_finish_request(); // Close and flush the connection.
sleep(10); // For illustrative purposes. Delete me.
mail("[email protected]", "lol", "Hi");

Es bastante fácil poner en cola cualquier código arbitrario para procesarlo después de finalizar la solicitud al usuario:

$post_processing = [];
/* your code */
$email = "[email protected]";
$subject = "lol";
$message = "Hi";

$post_processing[] = function() use ($email, $subject, $message) 
  mail($email, $subject, $message);
;

echo "Stuff is going to happen.";

/* end */

fastcgi_finish_request();

foreach($post_processing as $function) 
  $function();

Trabajador de fondo hipster

Instantáneamente agote el tiempo de espera de un curl y deje que la nueva solicitud se ocupe de él. Estaba haciendo esto en hosts compartidos antes de que fuera genial. (nunca es genial)

if(!empty($_POST)) 
  sleep(10);
  mail($_POST['email'], $_POST['subject'], $_POST['message']);
  exit(); // Stop so we don't self DDOS.


$ch = curl_init("http://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);

curl_setopt($ch, CURLOPT_TIMEOUT, 1);
curl_setopt($ch, CURLOPT_NOSIGNAL, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
  'email' => '[email protected]',
  'subject' => 'foo',
  'message' => 'bar'
]);

curl_exec($ch);
curl_close($ch);

echo "Expect an email in 10 seconds.";

Utilice AWS SES con PHPMailer.

Esta forma es muy rápida (cientos de mensajes por segundo) y no se requiere mucho código.

$mail = new PHPMailer;
$mail->isSMTP();                                      // Set mailer to use SMTP
$mail->Host = 'ssl://email-smtp.us-west-2.amazonaws.com';  // Specify main and backup SMTP servers

$mail->SMTPAuth = true;                               // Enable SMTP authentication

$mail->Username = 'blah';                 // SMTP username
$mail->Password = 'blahblah';                           // SMTP password


$mail->SMTPSecure = 'tls';                            // Enable TLS encryption, `ssl` also accepted
$mail->Port = 443; 

No estoy seguro de haber interpretado correctamente tu pregunta, pero espero que esto ayude.

Si haces scroll puedes encontrar los informes de otros administradores, tú además tienes la habilidad dejar el tuyo si lo deseas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *