Sending emails through SMTP with PHP

This article is more than two years old, the content may be outdated

Hi, this is my first blog post, and I am going to describe the process (that I recently had to take) to send emails with PHP and using a SMTP server.

First of all what we need is a SMTP Server that we can get freely in Gmail or other Free Mail Services such as Zoho. Once signed up you need to know the server settings and credentials, usually the smtp server is a subdomain of said service so for example in Gmail the smtp would be: smtp.gmail.com, the port is usually 465 if the encryption used is SSL if not (TLS) would be 567. Apart from these minimal settings we need the credentials that are the username that you registered with and the password.

Be aware that in case you are using Gmail the first time you try to connect to the SMTP server its going to send an email to that account to warn you about the safety of your account being compromised but if you are sure that it is you then add it as a safe application. In other services I don't know if they warn you about this but Zoho doesn't.

Now, regarding the backend part, we need the code to compose the email (headers, content type, encoding, etc), and we have several options to choose from:

  • We could use the native mail() function. Reference
  • Choose between a wide variety of php libraries to make this part easier.

As always you are free to choose anyone and each are valid and I am going to cover both of them.

Mail function

Alright, so the mail() function depends on the php configuration to send emails. And the php configuration is set in the php.ini file that is located in the installation php folder.

You can find the setting under the [mail function] section in the php.ini file, it will be like this:

[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = localhost
; http://php.net/smtp-port
smtp_port = 25

; For Win32 only.
; http://php.net/sendmail-from
;sendmail_from = me@example.com

; For Unix only.  You may supply arguments as well (default: "sendmail -t -i").
; http://php.net/sendmail-path
;sendmail_path =

; Force the addition of the specified parameters to be passed as extra parameters
; to the sendmail binary. These parameters will always replace the value of
; the 5th parameter to mail().
;mail.force_extra_parameters =

; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
mail.add_x_header = On

; The path to a log file that will log all mail() calls. Log entries include
; the full path of the script, line number, To address and headers.
;mail.log =
; Log mail to syslog (Event Log on Windows).
;mail.log = syslog

As you can see above there is no username and password field, and that's because the mail() function doesn't support SMTP authentication what makes it pretty useless but it is worth mention it.

PHP Mail Libraries

Alright, there are tons of libraries out there that will achieve the same results, some will be simpler and others more complex or more feature-full, and depending on your needs you'll choose one, I highly recommend to use Packagist as your php libraries search engine. Jus search for "email" and libraries will show up, but I will say that two of the most popular are PHPMailer (3M downloads) and Swift Mailer (42M downloads) .

These kind of libraries are using the native mail function but they are wrapped around it and their purpose is to make it easier for you.

And for the sake of simplicity I am going to use PHPMailer as an example, but most of the libraries follow the same pattern for email creation.

So first we will have to download the library, and I will use composer to autoload the class, although you are able to git clone the library and use it by require_once "mailer_class.php";.

Then the class will be instantiated and start to use it's own methods to add meta data information, content types, subjects, from's, to's, body, etc. It will be like this for PHPMailer and Composer as the autoloader:

<?php
    
require_once "vendor/autoload.php";

$mail = new PHPMailer;

// As we are using an external SMTP server we'll have to activate this
$mail->isSMTP();

$mail->Host = 'smtp1.example.com;smtp2.example.com'; // Main and backup smtp server, you could use only one
$mail->SMTPAuth = true; // Enable smtp auth, as almost all smtp's use this
$mail->Username = 'user@example.com'; // Your username
$mail->Password = 'supersecretpassword'; // Your password
$mail->SMTPSecure = 'tls'; // The encryption protocol used by the smtp
$mail->Port = 587; // And its port

// Now  compose the mail
$mail->setFrom('from@example.com');
$mail->addAddres('recipient@example.com');
$mail->Subject = "The super interesting and explanatory subject";

$mail->msgHTML(file_get_contents('template.html'), dirname(__FILE__)); //I'll explain this below
$mail->CharSet = "UTF-8";

$mail->send(); //Send email

As you have seen above, the body is going to be an html file which contains the email content, I prefer this way because you can make more engaging emails. Usually I'll use an email designer tool that exports to html and then implement it like this. However, you can still write plain text, depending on the library it could differ, but in the case of PHPMailer it would be:

$mail->Body = "Really exciting email content";

As a conclusion I have to say that it is far better to use a well tested library to send emails and not reinventing the wheel. Furthermore the fact that the native mail function doesn't support SMTP authentication makes it useless because nowadays every SMTP Server requires authentication to be used as far as I know.