In the first part, we discussed the transport layer and learned how to select an SMTP server. After choosing one, the next question is how to actually send an email. With PHP, there are many ways to implement it, such as:
- Built-in PHP mail() function.
- Independent libraries such as PHPMailer, SwiftMailer, PEAR::Mail.
- CMS tools such as WordPress, Joomla, Modx.
- The built-in tools of the frameworks such as Symfony, Laravel, etc.
- API/SDK of specialized services such as SendGrid, Mailgun, UniOne
Let's take a look at the pros and cons of each method.
Built-in PHP mail() function
Built-in mail() function is immediately available, free, and usually requires no additional configuration. If you are using commercial hosting, its administrators have already configured PHP so that mail() is automatically sent through the hosting’s SMTP server. So much for advantages.
The disadvantages list is more impressive:
- You need to know the correct details for all headers. Otherwise, there is a risk of forming an incorrect email that may not reach the addressee, end up in spam, or turn into a jumble of incomprehensible characters. Take a look at the example below. It has the wordwrap function applied. This is necessary to break the text into lines no more than 70 characters long.
- The recipient can see that the email is sent through your ISP's server.
- The mail() function is ineffective for large volumes and frequent submissions. A new connection is established for each email, so you won't achieve high sending rates. In addition, providers usually set their own limits on the emails sent (averaging at a few hundred per day).
- You are unable to get deliverability and open rate statistics.
- Many hosting providers do not allow you to reconfigure mail() to use a third-party SMTP server.
Here is an example of code for sending email using the mail() function:
<?php
$message = wordwrap('Hello, world!', 70, '\r\n', true);
mail('john@example.com', 'My hello', $message);
If you send a few emails, message format is simple, and you don't care about branding and deliverability, then you can try the mail() function. Despite its minor advantages, however, we recommend using an independent library or framework.
Classic mailing libraries (e.g., PHPMailer)
Several libraries have been written for PHP to simplify sending emails. One of the most popular is PHPMailer. It simplifies many routine tasks, for example:
- Formats email headers according to the standards.
- Ensures correct encoding of addresses and texts in different languages.
- Makes it easier to form complex emails with attachments, several formats at the same time (for example, HTML and plain text).
- Supports encryption.
- Handles errors in a more convenient way, etc.
There are other similar libraries such as SwiftMailer or PEAR::Mail.
As you can see, such libraries are more modern than the PHP mail() functions. Moreover, you can send via your own or third-party commercial SMTP server. But here, too, we will not do without drawbacks.
- The sending speed is higher than through mail(): it can reach thousands or even tens of thousands of emails per hour. If this is not enough for you, you should use the proprietary APIs of commercial services.
- Delivery statistics, reads, and transitions are available only when using commercial SMTP services.
- There are no built-in options for unsubscribing and tracking those who unsubscribed.
Here is an example of code for sending email using PHPMailer:
<?php
use PHPMailer\PHPMailer\PHPMailer;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
try {
$mail->setFrom('from@example.net', 'Website Mailer');
$mail->addAddress('joe@example.com', 'Joe');
$mail->Subject = 'My hello';
$mail->Body = 'Hello, world!';
$mail->send();
} catch (PHPMailer\PHPMailer\Exception $e) {
echo "Email sending failed: {$mail->ErrorInfo}";
}
CMS Tools (e.g., WordPress)
If you need to add your own code for sending emails, you must follow the same path as the CMS itself does. Many well-known open-source CMS use PHPMailer as described above to send an email:
- WordPress uses the PHPMailer library wrapped in the wp_mail() function.
- Joomla uses JMail from PHPMailer.
- MODX implements modMail via PHPMailer.
Here is an example of code for sending email from WordPress:
<?php
wp_mail('john@example.com', 'My hello', 'Hello, world!');
Sending goes through Sendmail or SMTP configured by your ISP in php.ini. To use external SMTP (e.g., TLS encryption and authentication), you need to add the following code:
<?php
add_action('phpmailer_init', 'send_smtp_email');
function send_smtp_email( $phpmailer ) {
$phpmailer->isSMTP();
$phpmailer->Host = 'smtp.eu1.unione.io';
$phpmailer->Port = '25';
$phpmailer->Username = '2123561';
$phpmailer->Password = 'secret_api_key';
$phpmailer->From = 'from@example.net';
$phpmailer->FromName = 'Website Mailer';
$phpmailer->SMTPAuth = true;
$phpmailer->SMTPSecure = 'tls';
}
The disadvantages, however, are identical to those of PHPMailer:
- Sending speed is higher than through mail() (it can reach thousands or even tens of thousands of emails per hour). If this is not enough for you, you should use the proprietary APIs of commercial services.
- Delivery statistics and transitions are available only when using commercial SMTP services.
- There are no built-in options for unsubscribing and tracking those who unsubscribed.
Note: If you want to send an email via third-party SMTP, then it will be easier to install one of the plugins for sending SMTP on WordPress, for example, WP Mail SMTP.
Framework tools (e.g., Symfony)
In this case, it is more convenient to use not an external library, but the one that comes with your framework. For Symfony it's Mailer, and for Laravel it's Mail. As of capabilities, they are the same as PHPMailer. However, because of close integration with the framework, these are more convenient.
Symfony Mailer supports more than just Sendmail or SMTP. It comes with pre-installed plugins for various commercial email services like SendGrid or Mailgun. Also, Symfony Twig-integrated templates for email text are supported.
Here is an example of code for sending email using Symfony Mailer:
<?php
$email = (new Symfony\Component\Mime\Email())
-
from('from@example.net')
-
to('joe@example.com')
-
subject('My hello')
-
text('Hello, world!');
/**
- @var Symfony\Component\Mailer\MailerInterface $mailer
- /
$mailer->send($email);
API/SDK services (e.g., UniOne)
Commercial email services like UniOne provide their own API and even a ready-made PHP library or ready-made examples for calling API methods.
An example of sending an email via the UniOne API:
$client = new \GuzzleHttp\Client([
'base_uri' => 'https://eu1.unione.io/en/transactional/api/v1/'
]);
$response = $client->request('POST', 'email/send.json',
[ 'json' => [
'message' => [
'api_key' => 'API_KEY',
'recipients' => [[ "email" => "joe@example.com"]],
'body' => [ "html" => "<b>Hello, world!/b>"],
'subject' => "My hello",
'from_email' => "from@example.net"
]
]
];
Along with all advantages of sending via PHPMailer, this method provides additional benefits:
- Vendors build their APIs for maximum performance, so sending rates can reach millions of emails per hour.
- The vendor's API provides additional features such as statistics, unsubscription and template management, etc.
- Technical support.
However, these benefits will cost some penny.
Bottom Line
If you need maximum speed (millions of emails per hour), real-time mail delivery, or additional features that you are ready to pay for, then the resources of an email service provider are just for you.
If the average speed (hundreds of thousands of letters per hour) is enough, and you are ready to pay for services but do not want to be attached to one vendor, then use one of the email service providers, and send emails via SMTP using one of the standard libraries such as PHPMailer or framework.
For minimal requirements, use your own server with a ready-made library/framework. And once again, we want to emphasize that we do not recommend using the standard mail() function at all.