mail() runs like a dog because, as you say, it will close the socket after each mail is sent, thus making it have to re-open again.
mail is good because its portable, but its not very good at sending multiple emails and also its very easy to fraff up the mail headers and cause your mail to be flagged as spam. also you must take into account your hosts send limit, and try to throttle the amount of emails sent by using sleep. Its all abit of a pain tbh.
SwiftMailer can do this properly, I haven't used PHPMailer so I can't say if it will or not.
First I think I should explain how mail() works across platforms.
If you are on a sane OS mail() uses sendmail (unless configured to use SMTP in the php config)
However if you are using a redmond operating system, for what ever reason (sane reasons for using windows so far have escaped my knowledge), mail() will be using SMTP anyway as sendmail doesn't exist on winblows, 'coz its bad :).
Swiftmailer provides tools for connecting to both SMTP and sendmail (which ends up being smtp anyway ... but I digress)
OK!
You will need to know either of the 2 following:
1. The path of the installed MTA binary of your server (sendmail, Postfix, Exim) if different from default: /usr/sbin/sendmail
2. SMTP server details
For this example I'm gonna use the sendmail method, using the default binary.
PHP Code:
//Create the Transport
$transport = Swift_SendmailTransport::newInstance();
/*to specify the binary just stick it in the params for 'newInstance()'
* e.g. $transport = Swift_SendmailTransport::newInstance('/<path>/sendmail <flags>');
*/
//Create the Mailer using the transport above
$mailer = Swift_Mailer::newInstance($transport);
//Create the message
$message = Swift_Message::newInstance('This is an imaginative subject')
->setFrom(array('noreply@xxx.xxx' => 'The amazing Bob Carolgees mailing list!'))
->setBody('Here is the message itself')
;
//this is my array of addresses!
$to = array(
'receiver@domain.org',
'sam@domain.org' => 'Sam'
);
foreach ($to as $address => $name)
{
if (is_int($address)) {
$message->setTo($name);
} else {
$message->setTo(array($address => $name));
}
$mailer->send($message);
}
You can also add a failed list:
PHP Code:
//Create the Transport
$transport = Swift_SendmailTransport::newInstance();
//Create the Mailer using the transport above
$mailer = Swift_Mailer::newInstance($transport);
//Create the message
$message = Swift_Message::newInstance('This is an imaginative subject')
->setFrom(array('xxx@xxx.xxx' => 'Bob Carolgees'))
->setBody('Here is the message itself')
;
//this is my array of addresses!
$to = array(
'receiver@domain.org',
'sam@domain.org' => 'Sam Roberts'
);
$fail = array();
foreach ($to as $address => $name)
{
if (is_int($address)) {
$message->setTo($name);
} else {
$message->setTo(array($address => $name));
}
$mailer->send($message, $fail);
}
$fail will hold an array of emails that the system couldnt send to.
more info on sending mails and transport types:
Send Docs
Plugins are by far the best reason to use Swift.
more information:
Plugin Docs