
Каждый раз настраивая локальный вебсервер, сталкиваюсь с вопросом о заглушке для Sendmail.
Есть прекрасное решение для Windows: fake sendmail for windows (sendmail.exe) http://glob.com.au/sendmail/
На хабре есть статья об этом решении: PHP mail под Windows http://habrahabr.ru/post/26518/
Ещё одно решение под Windows: Test Mail Server Tool http://www.toolheap.com/test-mail-server-tool/
Так же есть статья для линуксоидов: Sendmail-заглушка для Linux http://habrahabr.ru/post/49665/
Лично мне больше понравилось решение на чистом PHP, о котором и пойдёт дальнейшее описание.
Особенность этого решения в том, что для его настройка минимальна, можно даже обойтись без самого файла, если конечно вам нет нужды знать содержимое сообщения. На мой взгляд, такой метод стоит того, что бы о нём знали другие разработчики PHP.
Вопрос в том, что является вашим приоритетом как разработчика, ваши потребности от заглушки, а также ваш уровень знаний и умений.
Из плюсов:
- Отсутствие сторонних сервисов
- Кроссплатформенное решение для OS на которой установлен PHP
- Минимальный размер файла заглушки
- Минимальная настройка
- Вся логика заглушки доступна для редактирования на PHP
- Сохранение сообщения в файле
Из минусов:
- Отсутствие пересылки на реальный почтовый ящик
- Отсутствие удобного доступа к отправленным сообщениям
Список аргументов и возможностей заглушки:
- --dir <Путь к папке> — Папка для файлов
- --file <имя файла> — Сохранять каждое сообщение в конкретном общем файле
- --prepend — Добавлять новое сообщение в начало общего файла
- --open — Автоматически открывать файл сообщения в Notepad
Параметры для PHP.INI файла:
[mail function]
;SMTP = localhost
;smtp_port = 25
;sendmail_from = me@example.com
sendmail_path = "php.exe C:\sendmail.php --dir C:\mail --open"
Если путь к php.exe прописан в PATH, то можно не указывать его в PHP.INI иначе желательно изменить php.exe на <Путь к папке с PHP>\php.exe
sendmail_path = "C:\server\bin\php\php.exe C:\sendmail.php --dir C:\mail --open"
На линукс можно сразу указать путь к файлу, не забыв предварительно сделать его запускаемым: chmod 755 sendmail.php
sendmail_path = "/home/someuser/sendmail.php --dir /tmp/mail"
Сам 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);
}
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.'.txt';
return file_exists($mail_dir.'/'.$fn) ? mkname(++$i) : $fn;
}
Как я и обещал, есть также возможность обойтись совсем без файла.
sendmail_path = "C:\server\bin\php\php.exe -r 'echo 1;'"
Либо использовать упрощённый вариант решения
sendmail_path = "C:\server\bin\php\php.exe C:\sendmail.php"
sendmail.php:
#!/usr/bin/env php
<?php
$mail = '';
while (false !== ($line = fgets(STDIN))) {
$mail .= $line;
}
file_put_contents("c:/mail/mail.txt", $mail . PHP_EOL . str_repeat("-=", 20) . PHP_EOL, FILE_APPEND);
Буду рад, если Вам это будет полезным.