Create PHP script for sending mails

By using the PHP mail() function, you can create a web service for sending mails to your destinations (newsletter subscribers, 2FA loggers, …).

Function basics

This is the declaration of PHP mail() function, it is runned by 5 parameters, and return a boolean value (True if the mail was sent successully).

mail( string $to,
      string $subject,
      string $message,
      array|string $additional_params = [],
      string $additional_params = ""): bool
$toRequiredThe mail’s destination
$subjectRequiredThe mail’s subject
$messageRequiredThe mail’s text (contents or body)
$additional_paramsOptionalAn array of strings, containing parameters such as : the mail’s sender, Cc, Bcc, Content-type, …

Implementation

Create a new txt file and save it like (mail.php), and write the PHP opening and closing tags :

<?php

?>

Now, let’s define the variables which will be filled with data gotten from the headers of any received HTTP request (either GET or POST), by using the server global variable “$_REQUEST” along with specific parameter to retreive its value. Also, we have to use a conditional expression to check if the value is not null by using the “isset” function.

The primary receiver ($to)

For the receiver variable ($to) which will be used in the destination parameter, it accept only basic email syntax with no names. We can add many receivers, by separating their mails with commas “, ” like this example :

john@example.com, sally@example.com

For security concerns, we need to implement input sanitizing, by using a filter for sanitizing the input email address.

We can use the function directly, but this will make the script accept only one destination, like the following :

<?php 
$to = ( isset( $_REQUEST['to'] ) ? filter_var( $_REQUEST['to'], FILTER_SANITIZE_EMAIL)  : '' );
...
?>

Otherwise, we can separate the destinations string into an array, then we sanitize each row and restore the string in the end. Like the following :

<?php
$to = ( isset( $_REQUEST['to'] ) ?  $_REQUEST['to'] : '' );
foreach (explode(", ", $to) as $value) {
        $mails[] = filter_var($value, FILTER_SANITIZE_EMAIL); 
    }
$to = (implode(", ", $mails));
...
?>

Additional addresses

Now, we will implement additional emails variables : the sender (from :), the Cc and the Bcc.

These variables will be sent through the $additional_params in the email header. And here, we can add names to the addresses. The following syntaxes are accepted :

  • john@example.com
  • johny@example.com, sally@example.com
  • Mary <mary@example.com>, Kelly <kelly@example.com>

You can see their implementation by using the “isset” function to get data from the request :

$from = ( isset( $_REQUEST["from"] ) ? ( $_REQUEST["from"] ) : '' );
$cc = ( isset( $_REQUEST["cc"] ) ? ( $_REQUEST["cc"] ) : '' );
$bcc = ( isset( $_REQUEST["bcc"] ) ? ( $_REQUEST["bcc"] ) : '' );

The subject, the content and the content type

And in the same way, we will implement the variables for the email’s subject :

$subject = ( isset( $_REQUEST['subject'] ) ? ( $_REQUEST['subject'] ) : '' );

But for the content (the mail body), we must keep in mind that POST headers have a limited chars length. So for sending very long texts, it is better to use the request’s body.
We will set a condition to fill the content variable from the request header (if it is not empty) or from the request’s body through the function “file_get_contents()” from the PHP stream “php://input”, like this :

$txt = ( isset( $_REQUEST['txt'] ) ? ( $_REQUEST['txt'] ) : file_get_contents('php://input') );

Wanna look more professional ? Send an HTML content in your mails. This feature is enabled by setting the Content type in the mail’s header as “text/html”.

Just set the variable for the content type, and the rest will be arranged the header array later :

$ct = ( isset( $_REQUEST["ct"] ) ? ( $_REQUEST["ct"] ) : '' );

Setting the additional parameters

We will fill the additional parameters in an array variable (such as “$header”), that will contain the content type and the additional addresses (from, cc, bcc), like the following :

// Define the Content-type
if ( $ct == 'html' ) {
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=UTF-8'; 
}

// Define the additional addresses
if ( $from <> '' ) { $headers[] = "From: $from"; }
if ( $cc <> '' ) { $headers[] = "Cc: $cc"; }
if ( $bcc <> '' ) { $headers[] = "Bcc: $bcc"; }

// In case the other variables were null, add an empty row to avoid runtime errors
$headers[] = '';

The main function of the script

Finally, we will call the “mail” function with previous parameters, and we will use its returned boolean value as a response if the sending is done or failed.

...
if ( mail($to, $subject, $txt, implode("\r\n", $headers)) ) {
		echo '1';
	} else {
		echo '0'; 
	}
?>

Don’t forget the closing tag in the end of the script.

The final script

In the end, you will get a script like this :

<?php
// Only basic syntax for the receiver : $to = 'johny@example.com, sally@example.com'
$to = ( isset( $_REQUEST['to'] ) ?  $_REQUEST['to'] : '' );
foreach (explode(", ", $to) as $value) {
        $mails[] = filter_var($value, FILTER_SANITIZE_EMAIL); 
    }
$to = (implode(", ", $mails));

// Accept both basic syntax and 
// advanced syntax with names : 'Mary <mary@example.com>, Kelly <kelly@example.com>'
$from = ( isset( $_REQUEST["from"] ) ? ( $_REQUEST["from"] ) : '' );
$cc = ( isset( $_REQUEST["cc"] ) ? ( $_REQUEST["cc"] ) : '' );
$bcc = ( isset( $_REQUEST["bcc"] ) ? ( $_REQUEST["bcc"] ) : '' );


$subject = ( isset( $_REQUEST['subject'] ) ? ( $_REQUEST['subject'] ) : '' );
$txt = ( isset( $_REQUEST['txt'] ) ? ( $_REQUEST['txt'] ) : file_get_contents('php://input') );


// ct=html
$ct = ( isset( $_REQUEST["ct"] ) ? ( $_REQUEST["ct"] ) : '' );


// Define the Content-type
if ( $ct == 'html' ) {
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=UTF-8'; 
}

// Define message receivers
if ( $to <> '' ) { $headers[] = "To: $to"; }
if ( $from <> '' ) { $headers[] = "From: $from"; }
if ( $cc <> '' ) { $headers[] = "Cc: $cc"; }
if ( $bcc <> '' ) { $headers[] = "Bcc: $bcc"; }

$headers[] = '';


if ( mail($to, $subject, $txt, implode("\r\n", $headers)) ) {
		echo '1';
	} else {
		echo '0'; 
	}
?> 

N. B.

You can also restrict the requests kind to be received, by changing the global variable for a specific parameter or in the whole script.
You can change “$_REQUEST” by either :

  • “$_GET” (to receive only GET requests), or
  • “$_POST” (to receive only POST requests).

Deploying and using the service

Now, you have to deploy the final script to a PHP hosting server with enabled mailing services. Just put the script file in the folder corresponding to its future address.

There are three methods for using it :

  • Direct navigation in any web browser to the script URL and passing parameters as a GET request, such (‘https://yoursite/mail.php?to=person1@gmail.com&’).
  • Calling the script from another script or web page, for example, in a contact form or a CMS plugin. In fact, this can be very useful for a WordPress contact form plugin instead of using the “wp_mail()” function that could be messed with filters for changing sender mail and name.
  • The PHP script can also act as a RESTful service, so you can send a request with parameters to this script and receive a response by using a REST client in a web or native app (desktop or mobile app).

See also

Leave a Reply