简体   繁体   中英

Sending (relatively) large volumes of html e-mail with php

What is the best way/class to send a lot of html e-mail?

(Every mail needs to contain information (from a mysql database) that is linked to the address to which it's sent)

First I store the information I need in a transient table (not temporary , just a normal table that I drop after I'm done).

Then I generate the mails, deleting the processed records as I go, and put the generated mails into an "outbox" table.

Lastly, a script fires off every N minutes taking M records out the "outbox" table: it sends a mail, and then deletes that mail from the outbox table.

Why the transient table? Because the server on which this all happens has very strict time constraints. Using the above method allows me to partially generate the mails; you can safely re-run the generation phase without worrying about duplicate mails being generated. So in spite of the server killing the job, the script makes progress.

The sending script sends (60 / N)*M mails an hour, again to work within the constraints of the server.

I would suggest using the Pear packages Mail ( http://pear.php.net/package/Mail ) and Mail_Mime ( http://pear.php.net/package/Mail_Mime ).

If you need a queuing system, you could try gearman ( http://gearman.org/ )

I use Zend_Mail . The following example (from the docs ) shows how to send multiple mails over a single SMTP connection:

// Create transport
$config = array('name' => 'sender.example.com');
$transport = new Zend_Mail_Transport_Smtp('mail.example.com', $config);

// Set From & Reply-To address and name for all emails to send.
Zend_Mail::setDefaultFrom('sender@example.com', 'John Doe');
Zend_Mail::setDefaultReplyTo('replyto@example.com','Jane Doe');

// Loop through messages
for ($i = 0; $i < 5; $i++) {
    $mail = new Zend_Mail();
    $mail->addTo('studio@example.com', 'Test');

    $mail->setSubject(
        'Demonstration - Sending Multiple Mails per SMTP Connection'
    );
    $mail->setBodyText('...Your message here...');
    $mail->send($transport);
}

// Reset defaults
Zend_Mail::clearDefaultFrom();
Zend_Mail::clearDefaultReplyTo();

You would just need to modify the loop to fetch data from your database specific to each message to send. Furthermore, you won't need the entire framework to make use of Zend_Mail .

Take a look at: http://framework.zend.com/manual/en/zend.mail.multiple-emails.html

I think the first consideration is that is likely to take some time to process - so should not be done as a synchronous web request - see

Best way to manage long-running php script?

There are then all sorts of issues about creating HTML emails. You might want to have a look at one of the off-the-shelf packages such as phpmailer for generating the email itself. Alternatively, if the content is very complicated, you might consider setting it up as a web page, perhaps using a templating system - but remember to restrict any external access to it. eg

<?php
if ($_SERVER["REMOTE_ADDR"]!='127.0.0.1') {
   die ('NO ACCESS!');
}
$send_to=$_GET['email'];
$dbh=mysql_connect(...);
....

Then in your script:

....
$content=file('http://localhost/generate_email.php?email='
    . urlencode($db_row['recipient']));
mail($db_row['recipient'], $subject, $content);

HTH

C.

我喜欢Karim的想法,尽管我会try/catch通过$mail->send($transport)进行try/catch ,这样您可以跟踪已发送的内容和未发送的内容,并进行相应记录或在相关内容中进行标记数据库。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM