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
$to | Required | The mail’s destination |
$subject | Required | The mail’s subject |
$message | Required | The mail’s text (contents or body) |
$additional_params | Optional | An 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).