PHP Mail Scripts using SMTP transport, a guide for beginners

PHP has a very simple mail function which is used very often for basic text mail messages. What if you need to attach files or if you need to send your e-mail messages via SMTP? Than it’s time to use a more advanced script. This is because the standard mail function has only limited standard capabilities. There are many reasons to use SMTP transport for sending e-mail messages from your web application, some of them are:

  • Many shared hosting providers doesn’t allow to use the PHP mail() function for security reasons
  • Your web application is more flexible if you use the Simple Message Transfer Protocol (SMTP). This way your e-mail function is not limited to the servers port or e-mail configuration anymore.
  • SMTP is much more powerful and secure (using SSL)

In this article we will compare three of the bigger PHP projects which allow to send e-mail messages via SMTP, including attachments.

  1. The Mail class included in the Zend Framework (http://framework.zend.com/)
  2. Swift Mailer (http://swiftmailer.org/)
  3. PHPMailer (https://github.com/PHPMailer/PHPMailer)

We reviewed these three PHP classes because they’re written for PHP5 and they are updated frequently. For our review we tried the provided examples and the documentation. We’re sure that all three classes are very powerful and offer many functions for almost every type of web application. Because this review should help the beginning PHP developer, this article is show-case for a few functions only.

Our test case for this review

For our example we tested all three classes to send a plain text mail message with a single image attachment, using SMTP transport with authentication. Here is the good news; as a more experienced PHP user, I was able to use the provided examples within several minutes for each of the classes.

PHPMailer

require_once 'PHPMailer5/class.phpmailer.php';

$mail = new PHPMailer();
$mail->IsSMTP(); 
$mail->Host = 'smtp.server.com';
$mail->Port = 25;
$mail->SMTPAuth = true;
$mail->Username = 'smtpUser';
$mail->Password = 'smtpPassword';
$mail->SetFrom('you@mail.com', 'Your Name');
$mail->AddAddress('contact@mailservice.us', 'Your friend');
$mail->Subject = 'PHPMailer Message';
$mail->Body = 'This e-mail is sent through PHPMailer.';
$mail->AddAttachment('path/logo.png', 'logo.png');
if(!$mail->Send()) {
  echo 'Mailer error: '.$mail->ErrorInfo;
} else {
  echo 'Message has been sent.';
}

The coding style from this example looks very different from the two others and some PHP developer would say this is not really OOP code. Right PHPMailer doesn’t have one file for each method and for the example above you need to upload only two files. I like the PHPMailer class because of all the information you get on the project’s website. Read also our PHP tutorial about how to use PHPMailer with the SMTP server from Gmail.

The three examples above should help you to make the decision which script will work the best for you. Check the links below for the documentation related to the snippets I have used in this artikel:

Zend Mail Class

ini_set('include_path', '.:/path2directory/ZendFramework/library/');
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Mail');
Zend_Loader::loadClass('Zend_Mail_Transport_Smtp');

$config = array('auth' => 'login', 
              'username' => 'smtpUser',
              'password' => 'smtpPassword');

$transport = new Zend_Mail_Transport_Smtp('smtp.server.com', $config);
$mail = new Zend_Mail();
$at = $mail->createAttachment(file_get_contents('path/logo.png'));
$at->filename = 'logo.png';                                  
$mail->setBodyText('This is the text inside the mail send by Zend_Mail using SMTP transport.');
$mail->setFrom('you@mail.com', 'Your Name');
$mail->addTo('contact@mailservice.us', 'Your friend');
$mail->setSubject('Mail Subject');
$mail->send($transport);

I don’t like the documentation from the Zend framework, you need to check many pages to get all the required code for the snippet above. You need to create a second object to send your message via SMTP. I’m missing the information on their site about how-to test the “send” function to create use a success or error message. Using the class is not very difficult, but installing the Zend Framework might be a hard job for the beginner. This class is a great solution for people already using the Zend Framework or where the the library is provided by the hosting provider.

Swift Mailer

require_once 'Swift/lib/swift_required.php';

$transport = Swift_SmtpTransport::newInstance('smtp.server.com', 25)
  ->setUsername('smtpUser')
  ->setPassword('smtpPassword');

$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::newInstance('Wonderful Subject')
  ->setFrom(array('you@mail.com' => 'Your Name'))
  ->setTo(array('contact@mailservice.us' => 'Your friend'))
  ->setBody('This is the text of the mail send by Swift using SMTP transport.');
$attachment = Swift_Attachment::newInstance(file_get_contents('path/logo.png'), 'logo.png');  
$message->attach($attachment);
$numSent = $mailer->send($message);
printf("Sent %d messages\n", $numSent);

The snippet looks similar to the code from the Zend mail class, but you have to create 4 different objects:

  1. An object for the SMTP transport (Swift_SmtpTransport)
  2. The object that will send the message (Swift_Mailer)
  3. The message object for all mail parts (Swift_Message)
  4. An object for the attachment (Swift_Attachment)

The configuration/installation is much easier than for the Zend Framework, just include one single file and you’re ready to use the class. If you like this OOP (Object Oriented Programming) style used in this class, this script might be for you.

Published in: PHP Scripts

18 Comments

    1. Hi Yannick, you’re I have totally forgotten the eZ framework. If I find the time I will add them as well.

      Thanks!

    1. Hi Alex,

      you understand that mention an example for phpmailer (my favorit e-mail script).
      Check this link:
      http://phpmailer.worxware.com/index.php?pg=exampleasmtp
      and this information about inline attachments:

      AddEmbeddedImage($path, $cid, $name = "", $encoding = "base64",
          $type = "application/octet-stream")

      Adds an embedded attachment. This can include images, sounds, and just about any other document. Make sure to set the $type to an image type. For JPEG images use “image/jpeg” and for GIF images use “image/gif”. If you use the MsgHTML() method, there is no need to use AddEmbeddedImage() method.

  1. All three examples need nearly the same amount of lines.
    From my point of view the Swift Mailer is the “worst”, mainly because of too many singletons, I don’t like that style.
    PHPMailer seems to be very easy, but I aggree, it’s “strange OOP”, some things have to be set by setter, some by assignment.

    I prefer the Zend Framework way, and I also have some comments to that:
    – you can replace the ::loadClass lines with the following lines, it will register a spl_autoloader function and the whole Zend Framework is availables, no more require_once needed somewhere:
    require_once ‘Zend/Loader/Autoloader.php’;
    $autoloader = Zend_Loader_Autoloader::getInstance();
    – to test the result of the send() function you simply have to add a try-catch around it. Zend Framework handles all errors via exceptions. In case of an error you receive a detailed exception, when using Zend_Mail a Zend_Mail_Transport_Exception or a Zend_Mail_Protocol_Exception.
    – I personally like the Zend Framework because of the good possibilities to exchange certain components, for example the transport. It is possible to write a custom transport class and then use it with Zend_Mail. I think extending the other two classes is more complicated. Configuration by array is also good if you use an .ini-file or a database for configuration settings.

    But I aggree, if you just have to send a mail quickly, it is perhaps too much overhead to upload the whole Zend Framework or just the needed classes (mainly Zend/Loader and Zend/Mail folders). Uploading 2 files and 15 lines of code is the fastest solution. Thanks for that comparison.

  2. PHPGangsta,
    thanks a lot for sharing your opinion and for your tips regarding the Zend autoloader.

    You’re right if you use the Zend framework for other parts in your application you should use the mail class as well. I like the Google part from Zend framework a lot.

  3. Using the PEAR packages don’t meet your criteria as they’re compatible with PHP 4, so I understand why you didn’t cover them. For completeness sake though, here’s the code:

     $from, "To" => $to, "Subject" => $subject);
    $smtp = Mail::factory("smtp", array ("host" => $host, "port" => $port));
    $mime = new Mail_mime();
    $mime->setTxtBody($message);
    $mime->addAttachment("/home/ken/logo.png", "image/png");
    $body = $mime->get();
    $mail = $smtp->send($to, $mime->headers($headers), $body);
    
    if (PEAR::isError($mail)) {
    echo($mail->getMessage() . "!");
    } else {
    echo("Message successfully sent to $to!\n");
    echo "Queued As (ESMTP Id): ". $smtp->queued_as. "\n";
    echo "Greeting From Mailserver: ". $smtp->greeting. "\n";
    }
    
    ?>
    
  4. Hello Ken,

    Thanks for posting the PEAR example. Actually I was looking on the PEAR site for the example code and skipped PEAR because the documentation for this class is very limited. Sure an experienced PHP developer (and PEAR user) will not have any problems to find the different methods and properties. But how about the beginning user? I see there is some barricade, there are a lot of PEAR projects a user should look for but I think this mail class isn’t one (in my opinion).

    For the people which like to use the PEAR example; don’t forget to replace the single and double quotes, they are replaced by a WordPress filter.

  5. I think you should review eZ and PEAR mail components, they both have power and flexibility to operate via SMTP.

    1. Alexandr, I will add the eZ example today. Please check my opinion about the PEAR example in my previous comment.

      1. Okay here is the example for eZ components:

        ini_set('include_path', '.:/path2directory/ezcomponents/');
        require_once 'Base/src/ezc_bootstrap.php';
        
        $mail = new ezcMailComposer();
        $mail->from = new ezcMailAddress('you@mail.com', 'Your name');
        $mail->addTo(new ezcMailAddress('contact@mailservice.us', 'Your friend'));
        $mail->subject = 'This is the subject of the example mail';
        $mail->plainText = 'This is the body of the example mail.';
        $mail->addFileAttachment('path/logo.png');
        $mail->build();
        $options = new ezcMailSmtpTransportOptions();
        $transport = new ezcMailSmtpTransport('smtp.server.com', 'smtpUser', 'smtpPassword', null, $options);
        $transport->send($mail);
        

        Since this was the first time I have used eZ components I needed to play around to get in working (checking code which files I need to upload, etc.). The good news if you follow the installation instructions, it’s very easy to setup: Just like me create the include path and include the bootstrap file and you’re done! Beside this you don’t need to upload the whole framework, the classes (you need) are enough (including autoload and Base).

        The manual is much better than for Zend, a lot of examples and information. Sure you have to handle a lot of objects, but it seem to me very clear what I have to do. Great framework, I will use it more often!

  6. Olaf: point taken, and it’s true to say there are a number of PEAR packages that would probably be used much more if their documentation was up to scratch!

    Unfortunately it’s the same old OSS problem: nobody seems to like writing documentation so doing so tends to be either forgotten about or left for too long.

    1. I think that’s why open source projects managed by companies like PHPMmailer or Swift having this great documentation, they have just the people to write them.
      The strange thing is that people like to write the documentation for PHP (the best manual I know)

  7. I can’t get phpmailer to work. When the form invokes “require_once(‘formfiles/class.phpmailer.php’);”
    it generates this error and points to the first php non-comment line of code in the class:

    syntax error, unexpected T_ECHO, expecting T_OLD_FUNCTION or T_FUNCTION or T_VARor ‘}’ in /homepages/23/d204211733/htdocs/valleywoodcrafts/formfiles/class.phpmailer.php on line 44

    Running PHP 5 on linux server hosted by 1and1

    1. Hello Phil, that’s strange…
      I’m using phpmailer with many different hosting accounts and never had this problem (remember WordPress is using phpmailer as well).
      Do you double checked all paths and do you uploaded the files again?

  8. That’s what I find so perplexing. I created a minimal form file using the guidance provided and the class.phpmailer.php was unchanged from the download. It must be something simple that I have missed.
    It does find the class file because that’s where the error originates so the path is correct.

    1. Hi Phil,

      maybe you can test the code on your local system or sandbox? I’m sure there is nothing wrong with the code, but we need to start somewhere before we can locate the problem :)

Comments are closed.