No need to disconnect with version 4?

Swift Mailer is a fantastic library for sending email with php. Discuss this library or ask any questions about it here.

Moderators: Chris Corbyn, General Moderators

Post Reply
GryphonLeon
Forum Newbie
Posts: 8
Joined: Tue Jul 10, 2007 5:38 am

No need to disconnect with version 4?

Post by GryphonLeon »

Hi,

I've used version 3 for quite a while now and am in the process of upgrading to version 4.
One thing I noticed is that the documentation for version 4 doesn't mention disconnecting after an email was sent.

I've always used $swift->disconnect(); for version 3, simply because I like to keep things clean.

Is it also possible to disconnect with version 4, and if so, how? Or is it done automatically?

Thanks!
Leon
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: No need to disconnect with version 4?

Post by Chris Corbyn »

It happens automatically yes :) Something that PHP4 could really do very well.

If you *need* to force a disconnect, keep the transport handy:

Code: Select all

$smtp = new Swift_SmtpTransport( ... );
 
$mailer = new Swift_Mailer($smtp);
 
$mailer->send( ... );
 
//It's called "stop()" since it's not strictly a "connection" anymore, Transports are a bit more abstract than that in v4
$smtp->stop();
Another thing to note: in version 4, Swift Mailer connects to the SMTP server (or any other transport) as late as possible (i.e. whilst sending). In version 3 it connected as soon as the "Swift" object was created.

EDIT | And if you want to know if the SMTP connection is connected or not (or any other transport for that matter):

Code: Select all

if ($smtp->isStarted()) {
  echo "SMTP connected is connected\n";
}
 
GryphonLeon
Forum Newbie
Posts: 8
Joined: Tue Jul 10, 2007 5:38 am

Re: No need to disconnect with version 4?

Post by GryphonLeon »

That's excellent, thanks for the detailed answer Chris! I'm still working on my code to switch to v4, but so far so good!
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Re: No need to disconnect with version 4?

Post by Chris Corbyn »

GryphonLeon wrote:That's excellent, thanks for the detailed answer Chris! I'm still working on my code to switch to v4, but so far so good!
No problem. In terms of "migrating to v4", a practice I always try to follow (even when using my own library, i.e. Swift Mailer) is to add another layer of abstraction between the library and your code.

In other words, from the set of features Swift offers, you're not likely to use all of them at any one time, so wrap the logic for using Swift inside your own classes (or functions).

This minimizes the code you need to change when big changes like this happen. A simple example may be just creating a function wrapper if all you need is plain-text emails:

Code: Select all

function create_mailer() {
  return new Swift_Mailer(new Swift_SmtpTransport('localhost'));
}
 
function send_email($to, $from, $subject, $body, $headers = array()) {
  //Add Swift Mailer code here
  $message = new Swift_Message($subject, $body);
  $message->setTo($to);
  $message->setFrom($from);
  foreach ($headers as $name => $value) {
    $message->getHeaders()->addTextHeader($name, $value);
  }
  
  $mailer = create_mailer();
  
  return $mailer->send($message);
}
Now throughout your code you only need to invoke something like:

Code: Select all

if (send_email(
  'recipient@domain.tld', 'me@domain.tld',
  'Your Account', 'We have banned you from our site. Goodbye',
  array(
    'X-My-Header' => 'whatever'
  )))
{
  echo "Message sent\n";
}
And the only code you need to change when upgrading is the send_email() function and anything it calls.

I'm going to document this, along with a number of other "common best practices" in the documentation (which I'd like to offer in PDF book form if I can find a technical editor, since my writing isn't that great - though not terrible!).
GryphonLeon
Forum Newbie
Posts: 8
Joined: Tue Jul 10, 2007 5:38 am

Re: No need to disconnect with version 4?

Post by GryphonLeon »

Good point Chris :) I already created my own wrapper for v3, so it wasn't hard to change to v4 at all. In some php files I didn't use the wrapper for various reasons, so I had to change my code there as well. But, it's all pretty straight forward!

Here's my wrapper, in case anyone finds it useful ($smtphost, $smtpuser, $smtppw are defined in the config.php file):

Code: Select all

function send_email($to,$from,$subject,$msg,$htmlmsg='',$attach_arr='') {
    // Sends an email to one recipient with SMTP or PHP's mail function. $to,$from,$subject,$msg should always be defined.
    // Only $msg is defined --> plain text email; Only $htmlmsg is defined --> html email; Both $msg and $htmlmsg are defined --> MIME/Multipart email;
    // If attachments are included, it will send a MIME/Multipart email, so make sure you also set both the $msg and $htmlmsg variables when attaching files.
    // $to and $from can be either a string (email address), or an array with two fields, email and name ($to['email'], $to['name']).
    // The attach_arr (optional) should be defined as followed: $attach_arr[] = array(pathtofile => $pathtofile, filename => $fileatt_name, type => $fileatt_type);
    $pathFix = dirname(__FILE__); // needed to make sure files like config.php can always be included, no matter in what directory functions.php is being included in
    require("$pathFix/config.php");
    $path_to_swift = $pathFix.'/../../inc/email';
    require_once("$path_to_swift/swift_required.php");
    if($smtphost != '') { // send with SMTP
        if($smtpuser != '' && $smtppw != '') { // add SMTP authentication
            $transport = Swift_SmtpTransport::newInstance($smtphost)->setUsername($smtpuser)->setPassword($smtppw);
        }
        else {
            $transport = Swift_SmtpTransport::newInstance($smtphost);
        }
    }
    else { // send with PHP's mail() function
        $transport = Swift_MailTransport::newInstance();
    }
    $mailer = Swift_Mailer::newInstance($transport);
    // create new message with subject
    $message = Swift_Message::newInstance()->setSubject($subject);
    // define sender
    if(is_array($from)) {
        $message->setFrom(array($from['email'] => $from['name']));
    }
    else {
        $message->setFrom($from);
    }
    // define recipient
    if(is_array($to)) {
        $message->setTo(array($to['email'] => $to['name']));
    }
    else {
        $message->setTo($to);
    }
    // define actual message/body
    if((!empty($msg)) && (!empty($htmlmsg))) { // MIME/Multipart email
        $message->setBody($htmlmsg, 'text/html'); // create html message
        $message->addPart($msg, 'text/plain'); // add plain text message
        if(!empty($attach_arr)) { // add attachment(s)
            for($row=0; $row<count($attach_arr); $row++) {
                $message->attach(Swift_Attachment::fromPath($attach_arr[$row]['pathtofile'])->setFilename($attach_arr[$row]['filename'])->setContentType($attach_arr[$row]['type']));
            }
        }
    }
    else { // HTML or plain text email
        if(!empty($htmlmsg)) { // HTML email
            $message->setBody($htmlmsg, 'text/html'); // create html message
        }
        else { // Plain text email
            $message->setBody($msg, 'text/plain'); // create plain text message
        }
    }
    //Send the message
    $result = $mailer->send($message);
    return $result;
}
Thanks again Chris!
Post Reply