2017-05-20 5 views
0

Hallo ich bin versucht, mehrere E-Mails mit PhpMailer für ein Benachrichtigungssystem zu senden. Um Probleme mit der Zeitverzögerung zu vermeiden, wenn ein Benutzer ein Formular abschickt, habe ich beschlossen, alle E-Mails, die sie in einer mysql-Tabelle speichern, in Warteschlange zu stellen. Dann benutze ich einen Cron-Job, um die Warteschlange zu senden. Dies ist das Skript, das ich mit Cron-Job renneBenutze Cron Job für Hintergrund php

include('config/config.php'); 

require_once(ROOT_PATH.'/helper/phpmailer/PHPMailerAutoload.php'); 

    $mail = new PHPMailer; 

    $mail->isSMTP(); 
    $mail->SMTPAuth = true; 
    $mail->isHTML(true); 
    $mail->Host = SSE_HOST; 
    $mail->Username = SSE_USER;  
    $mail->Password = SSE_PASSWORD; 
    $mail->SMTPSecure = SSE_SECURE; 
    $mail->Port = 465; 
    $mail->SetFrom(SSE_FROM, SSE_FROM_NAME); 
    $mail->addReplyTo(SSE_REPLY, 'Invia Risposta'); 

$result = mysqli_query($conn, "SELECT queue_emails_email, queue_emails_subject, queue_emails_body FROM queue_emails WHERE queue_emails_status = '1' "); 

    foreach ($result as $row) { 

     $mail->addAddress($row['queue_emails_email']); 
     $subject = $row['queue_emails_subject']; 
     $mail->Subject = $subject; 
     $mail->MsgHTML($row['queue_emails_body']); 


    if (!$mail->send()) { 
     echo "Mailer Error (" . str_replace("@", "&#64;", $row["queue_emails_email"]) . ') ' . $mail->ErrorInfo . '<br />'; 
     break; //Abandon sending 
    } else { 
     echo "Message sent to :" . $row['queue_emails_email'] . ' (' . str_replace("@", "&#64;", $row['queue_emails_email']) . ')<br />'; 
     //Mark it as sent in the DB 
     mysqli_query($conn, "UPDATE queue_emails SET queue_emails_status = '0' WHERE queue_emails_email = '" . 
      mysqli_real_escape_string($conn, $row['queue_emails_email']) . "'"); 

    } 
    // Clear all addresses and attachments for next loop 
    $mail->clearAddresses(); 

    } 

Diese die MySQL-Tabelle ist queue_emails Struktur:

queue_emails_id int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT, 
queue_emails_email varchar(255) NOT NULL, 
queue_emails_status int(2) DEFAULT '1', 
queue_emails_subject TEXT NOT NULL, 
queue_emails_body TEXT NOT NULL 

Nun meine Frage: Wenn ich mehr als eine Nachricht habe mit anderer Körper aber dieselbe E-Mail-Adresse, was passiert, wenn der Cron-Job-Prozess unterbrochen wird? Ich habe auf meinem localhost mit Mailtrap getestet und es scheint gut zu funktionieren, aber ich würde gerne wissen, ist diese Methode kann auf einem Live-Server gut sein. Ich glaube nicht, dass meine Warteschlange größer als 200-300 E-Mails sein würde. Vielen Dank für Ihre Hilfe

+0

Warum fügen Sie nicht einfach eine ID-Spalte zu Ihrer Tabelle und UPDATE basierend auf dieser ID, nicht die E-Mail-Adresse? –

+0

Hallo @ TodorSimeonov danke für Ihre schnelle Antwort. Entschuldigung, ich verstehe nicht, was Sie meinen, indem Sie eine ID hinzufügen (ist das die Benutzer-ID)? – pippo

+0

In Ihrer DB-Tabelle 'queue_emails' - fügen Sie dort eine Spalte hinzu, die AUTO INCREMENT sein kann, und es wird eine eindeutige ID jeder E-Mail-Nachricht sein, die Sie senden müssen. Dann können Sie mit 'queue_emails_status = '0' genau diese Zeile mit der E-Mail-Nachricht aktualisieren, die Sie gerade gesendet haben, aber alle anderen Nachrichten an diesen Benutzer (Adresse) bleiben in der Warteschlange. Es spielt keine Rolle, ob die gesamte Tabelle mit der gleichen E-Mail-Adresse gefüllt ist. –

Antwort

0

Es ist gut, dass Ihre Tabelle eine separate eindeutige ID enthält, so dass Sie keine Änderungen an der Datenbankstruktur vornehmen müssen. Sie müssen nur Ihren ID-Wert abrufen und verwenden. Ändern Sie bitte Ihre SELECT wie folgt aus:

$result = mysqli_query($conn, "SELECT queue_emails_id, queue_emails_email, 
    queue_emails_subject, queue_emails_body FROM queue_emails WHERE 
    queue_emails_status = '1' "); 

dann später, wenn Sie die UPDATE Gebrauch machen dies:

mysqli_query($conn, "UPDATE queue_emails SET queue_emails_status = '0' 
    WHERE queue_emails_id = '" . intval($row['queue_emails_id']) . "'"); 

Es ist nur so einfach. Jetzt können Sie sicher sein, dass Sie den Status Null auf die richtige Nachricht setzen, unabhängig davon, wie viele Nachrichten an die gleiche Adresse in Ihrer Warteschlange gesendet werden, und Sie werden keine Nachricht verlieren.

Übrigens würde Ihr Code Nachrichten für die gleiche E-Mail-Adresse verlieren, wenn mehrere in der Warteschlange sind. Es wird alle als gesendet gesetzt, egal ob der cron Job abgeschlossen ist oder unterbrochen wird. Angenommen, Sie haben die folgenden Meldungen haben:

to: [email protected] 
to: [email protected] 
to: [email protected] 
to: [email protected] 
to: [email protected] 

Ihre Abfrage dieser Liste zurückkehren, werden Sie beginnen, das Senden von Nachrichten und die erste Nachricht an [email protected] senden. Wenn $mail->send() OK zurückgibt, werden alle Nachrichten an john @ yahoo mit Status = 0 aktualisiert. So wird John nur eine Nachricht erhalten und die 2. und die 5. Nachricht wird verloren gehen (nicht an John senden).

In Ihrer Frage sagen Sie, dass 200-300 Nachrichten in der Warteschlange sein könnten. Ich weiß nicht, wie oft Sie diesen Code nennen, ich würde es nicht mehr als 5 Minuten nennen, damit meine Benutzer ihre Post pünktlich erhalten, aber wenn es zu oft ist, bedeutet das, dass Sie viele E-Mails pro Tag gehen . Denken Sie darüber nach, müssen Sie sie alle in Ihrer Tabelle mit Status = 0 behalten oder Sie können sie löschen, um Platz zu sparen.

+0

Hallo Tudor vielen vielen Dank für Ihre Hilfe, ich werde es später testen und Sie wissen lassen.In Bezug auf Ihre Überlegung denke ich, dass ich den Code alle 15 Minuten anrufen werde, um auch Cron-Überlappung zu vermeiden (ich bin Suche auf Google mehr Info darüber auch) dann ist mein Plan, einen anderen Cron vielleicht einmal am Tag laufen zu lassen, um alle Reihen mit Status = 0 zu entfernen und Datenbank auf diese Weise sauber zu halten – pippo