Отправка писем — это важная функция веб-сайта. Email может использоваться для подтверждения регистрации, восстановления пароля, отправки уведомления и пр. При написании своего веб-приложения, либо для целей отладки, может понадобиться проверка работы отправки писем на локальном компьютере.
Для отправки писем в PHP используется функция mail. Для успешной работы этой функции, интерпретатор PHP обращается к внешней почтовой программе и передаёт ей отправляемое письмо. Обычно это sendmail в Linux.
Как можно догадаться, это не очень применимо к Windows, и уж тем более к веб-серверу на локальном компьютере. Поэтому для тестирования функции отправки писем придумана почтовая заглушка.
Почтовая заглушка — это программа, которая подменяет роль программы для отправки писем — она принимает письмо от PHP, но не пытается его никуда отправить, а сохраняет на диск. В дальнейшем это письмо можно открыть и проверить корректность использования функции mail.
Установка почтовой заглушки для PHP в Windows
Я устанавливал веб-сервер по этой инструкции, если вы это делали другим способом, то замените пути до файлов на ваши.
В каталоге C:\Server\bin\ создайте новый каталог с названием Sendmail. Теперь в этом каталоге создайте файл sendmail.php со следующим содержимым:
#!/usr/bin/env php <?php /* PHP.INI * [mail function] * ;SMTP = localhost * ;smtp_port = 25 * ;sendmail_from = me@example.com * 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; }
Откройте конфигурационный файл PHP, он размещён здесь C:\Server\bin\PHP\php.ini. И добавьте туда одну строчку:
sendmail_path = "C:\Server\bin\PHP\php.exe C:\Server\bin\Sendmail\sendmail.php --dir C:\Server\bin\Sendmail\emails"
Сохраните файл и перезапустите сервер.
c:\Server\bin\Apache24\bin\httpd.exe -k restart
Отлично, теперь все отправленные письма будут сохраняться в каталоге C:\Server\bin\Sendmail\emails\
Для имитации отправки письма используйте следующий код:
<?php $to = 'nobody@example.com'; $subject = 'the subject'; $message = 'hello'; $headers = 'From: webmaster@example.com' . "\r\n" . 'Reply-To: webmaster@example.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion(); mail($to, $subject, $message, $headers);
Отправленное письмо сохранено в файл mail_2019-06-03_15-14-06_0.eml. Этот файл для правильного отображения нужно открыть почтовой программой.
Также его можно открыть любым текстовым редактором — там вы увидите заголовки почтового протокола и текст письма, в данном случае там будет:
To: nobody@example.com Subject: the subject X-PHP-Originating-Script: 0:test4.php From: webmaster@example.com Reply-To: webmaster@example.com X-Mailer: PHP/7.3.4 hello