How to test email sending in PHP on Windows

Emailing is an important feature of a website. Email can be used to confirm registration, recover a password, send a notification, etc. When writing your web application, or for debugging purposes, you may need to check the work of sending emails on your local computer.

To send emails in PHP, the mail function is used. For the success of this function, the PHP interpreter call an external mail program and gives it a sent email. This is usually sendmail on Linux.

As you can guess, this is not very applicable to Windows, and even more so to the web server on the local computer. Therefore, to test the function of sending letters, a mail cap was invented.

The mail cap is a program that replaces the role of the program for sending letters – it accepts a letter from PHP, but does not try to send it anywhere, but saves it to disk. In the future, this letter can be opened and so you can check the correctness of using the mail function.

Installing email program for PHP in Windows

I installed the web server according to this tutorial, if you did it in another way, then replace the paths to the files with yours.

In the C:\Server\bin\ folder, create a new directory called Sendmail. Now in this directory, create the file sendmail.php with the following contents:

#!/usr/bin/env php
 *  [mail function]
 *  ;SMTP = localhost
 *  ;smtp_port = 25
 *  ;sendmail_from =
 *  sendmail_path = php.exe sendmail.php --dir C:\mail --open
$is_windows = stristr(PHP_OS, 'WIN');
$options = getopt("", ['open', 'prepend', 'file:', 'dir:']);
$is_open = isset($options['open']);
$is_prepend = isset($options['prepend']);
$is_onefile = isset($options['file']);
$mail_dir = isset($options['dir']) ? $options['dir'] : sys_get_temp_dir() . '/mail';
$file_name = isset($options['file']) ? $options['file'] : mkname();
$file_path = $mail_dir . '/' . $file_name;
if (!is_dir($mail_dir)) {
    mkdir($mail_dir, 0777, TRUE);
    if (!is_dir($mail_dir)) {
        die('Mail folder [' . $mail_dir . '] not created');
$stream = $is_onefile ? PHP_EOL . str_repeat("-=", 10) . date('Y-m-d H:i:s') . str_repeat("-=", 10) . PHP_EOL : '';
while (false !== ($line = fgets(STDIN))) {
    //$stream .= ($is_windows ? str_replace("\n", PHP_EOL, $line) : $line);
    $stream .= $line;
if ($is_prepend && file_exists($file_path)) {
    $file_contents = file_get_contents($file_path);
    $stream .= $file_contents;
file_put_contents($file_path, $stream, $is_prepend ? 0 : FILE_APPEND);
if ($is_open && $is_windows) {
    pclose(popen("start /B notepad " . $file_path, "r"));
function mkname($i = 0) {
    global $mail_dir;
    $fn = 'mail_' . date('Y-m-d_H-i-s_') . $i . '.eml';
    return file_exists($mail_dir . '/' . $fn) ? mkname( ++$i) : $fn;

Open the PHP configuration file, it is located here C:\Server\bin\PHP\php.ini. And add one line there:

sendmail_path = "C:\Server\bin\PHP\php.exe C:\Server\bin\Sendmail\sendmail.php --dir C:\Server\bin\Sendmail\emails"

Save the file and restart the server.

c:\Server\bin\Apache24\bin\httpd.exe -k restart

Ok, now all sent emails will be saved in the directory C:\Server\bin\Sendmail\emails\

To simulate sending electronic letters, use the following code:

$to      = '';
$subject = 'the subject';
$message = 'hello';
$headers = 'From:' . "\r\n" .
    'Reply-To:' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

mail($to, $subject, $message, $headers);

The sent email is saved to the file mail_2019-06-03_15-14-06_0.eml. This file for correct display needs to be opened by the mail program.

You can also open it with any text editor – there you will see the headers of the mail protocol and the text of the letter, in this case there will be:

Subject: the subject
X-PHP-Originating-Script: 0:test4.php
X-Mailer: PHP/7.3.4


Recommended for you:

Leave a Reply

Your email address will not be published.