PHP Mailer compile and store message for later sending

一世执手 提交于 2019-12-24 17:28:05

问题


Can we compile and store messages as a draft in PHP mailer and then later on send each message?


回答1:


It is possible to do this with PHPMailer. After configuring the PHPMailer instance with everything you'd normally need to send the message, do not call send() - instead call preSend() (which constructs the message) and then get the message content using getSentMIMEMessage(), e.g.

$mail->preSend();
$message = $mail->getSentMIMEMessage();

$message will then contain a complete RFC822 message which you can stick in a database, queue or whatever to send later. To do the actual sending later, you could make use of PHPMailer's SMTP class directly. To see how to drive that class, look at PHPMailer's smtpSend() function.




回答2:


I don't think so PHPMailer supports this feature. But you can do this by using DB Table. Create a table in database to store messages, recipients, from, headers, etc and send them by PHPMailer later from a CRON job.




回答3:


PHPMailer can't support this, because it conserves the Email message in Object which will die after the end of the script(the HTTP protocol works that way).

If you want to send them latter (say after 15 minutes) you need to use CRON job indeed and make a script looking in the database and sending emails.

If you want to send them in the Lifetime of the script (send them after the tag) you can simply do an array of emails and foreach them at the end




回答4:


You need create

  1. special method that will do save all mail that should be sent (in db)
  2. special method that will get all unsent mails and send them
  3. add to crontab method that send unset mails

That's all.




回答5:


I stumbled on this question when trying to do this myself - I wanted to store the PHPMailer object in a database to send it later from a different server, to have a mail queue to limit number of emails sent per second and also to push back messages when there was a sending error.

The solution is easy - instead of

$phpmailerObject->send();

just do a:

$phpmailerObject->preSend();

Then serialize the object in a database. When you want to later save the mail, get the database entry, unserialize the object, and do a:

$phpmailerObject->postSend();

Internally, PHPMailer just does a preSend() and postSend() if you send() an object instance. Using preSend() before saving the object is important because you mime headers and body will be created, with all attachments and data. If you do the preSend() on a different server with a different setup, the attachment files/images may not be found and there will be an error. postSend() only sends the data with the "compiled" email.

I would also advise to create every PHPMailer instance with "true" in the constructor (to enable exceptions) and to wrap the postSend() in a try/catch-block to handle any sending/SMTP errors. I learned that the hard way.




回答6:


The PHPMailer library at this moment has the getSentMIMEMessage function which saves the message in a compact way, but the library doesn't have a counterpart yet to send saved email message.

So the best way to do at the moment what you need it's to serialize the PHPMailer object, save the string on a database or in a file and restore it after when you want to send it.

Here are the functions I created to queue mails which cannot be send in a script.

$file should contain full path and filename.

function sendQueuedMailFile($file) {
    $rfcMail = file_get_contents($file);

    $phpMailerObj = new PHPMailer();
    $phpMailerObj = unserialize( $rfcMail );

    if ( $phpMailerVar->postSend() ) {
        // If sent correctly, delete file
        unlink( $queue_folder . $fichero );
    }
}

This function saves a phpMailer object to a queue file. The phpMailer object should have all the addresses, subject, content with the values needed to do a normal mail sending before calling this function.

function queuePHPMailerToFile($phpMailerObj, $file) {
    $phpMailerObj->PreSend();
    $phpMailerObj->GetSentMIMEMessage();

    $rfcMail = serialize($phpMailerObj);

    file_put_contents($file, $rfcMail);
}

You can use the queuePHPMailerToFile function for queue mails for later sending or to save a mail which cannot be sent at this moment, and try to send it the next time you try to send one email.

This it's an example to use it for queue failed messages. queuePath should contain the folder where you like to save queued mails.

if ( $phpMailerObj->Send() ) {
    // Mail sent ok, trying to look for queued emails
    sendEmailQueue($queuePath);
} else {
    // Some problem detected, saving mail for next time
    queuePHPMailerToFile($phpMailerObj, $queuePath . DIRECTORY_SEPARATOR . date("Y-m-d_Hisu") . "_" . rand(0, 999999) . ".txt");
}

And for ending this it's the function to re-send queued files

function sendEmailQueue($queuePath) {

    if ( is_dir($queuePath) ) {
        if ( $dh = opendir($queuePath) ) {

            while ( ($file = readdir($dh)) !== false ) {

                if ( ($file == '.') or ( $file == '..' ) ) continue;

                sendQueuedMailFile($queuePath . DIRECTORY_SEPARATOR . $file);
            }
        }
    }
}


来源:https://stackoverflow.com/questions/23212634/php-mailer-compile-and-store-message-for-later-sending

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!