Как прикрепить архив к письму php mail()
Пишу на процедурном php. Есть скрипт для генерации бэкапов сайта и создания архива с этими данными. Затем скрипт должен прикрепить этот файл к письму. Не понимаю, как это сделать с архивом.
<?php
$backup_folder = '/home/t/tipo4ek/backup'; // куда будут сохранятся файлы
$backup_name = 'lyubimoff-projects_backup_' . date("d-m-Y"); // имя архива
$dir = '/home/t/tipo4ek/'; // что бэкапим
$delay_delete = 30 * 24 * 3600; // время жизни архива (в секундах)
$mail_to = '[email protected]';
$mail_subject = 'lyubimoff-projects backup';
$mail_message = '';
$mail_headers = 'MIME-Version: 1.0' . "\r\n";
$mail_headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$mail_headers .= 'From: lyubimoff-projects.ru <[email protected]>' . "\r\n";
function backupFiles($backup_folder, $backup_name, $dir)
{
$fullFileName = $backup_folder . '/' . $backup_name . '.tar.gz';
shell_exec("tar -cvf " . $fullFileName . " " . $dir . "/* ");
return $fullFileName;
}
function deleteOldArchives($backup_folder, $delay_delete)
{
$this_time = time();
$files = glob($backup_folder . "/*.tar.gz*");
$deleted = array();
foreach ($files as $file) {
if ($this_time - filemtime($file) > $delay_delete) {
array_push($deleted, $file);
unlink($file);
}
}
return $deleted;
}
$start = microtime(true); // запускаем таймер
$deleteOld = deleteOldArchives($backup_folder, $delay_delete); // удаляем старые архивы
$doBackupFiles = backupFiles($backup_folder, $backup_name, $dir); // делаем бэкап файлов
// добавляем в письмо отчеты
if ($doBackupFiles) {
$mail_message .= 'site backuped successfully<br/>';
$mail_message .= 'Files: ' . $doBackupFiles . '<br/>';
}
if ($deleteOld) {
foreach ($deleteOld as $val) {
$mail_message .= 'File deleted: ' . $val . '<br/>';
}
}
$time = microtime(true) - $start; // считаем время, потраченое на выполнение скрипта
$mail_message .= 'script time: ' . $time . '<br/>';
echo 'nice!';
mail($mail_to, $mail_subject, $mail_message, $mail_headers); // и отправляем письмо
?>
Пути определяются верно, архив создается, как прикрепить архив к письму?
Ответы (1 шт):
Автор решения: Meow
→ Ссылка
Написал функцию на основе https://stackoverflow.com/a/6275152/14196309, чтобы Вам было проще разобраться. Добавьте её в свой код, а те участки где формируются заголовки и происходит отправка письма через mail() - удалите.
function sendMailWithAttachment(
string $fromName,
string $fromMail,
string $toMail,
string $replyTo,
string $subject,
string $message,
string $filePath
): void
{
if (empty($filePath) || !file_exists($filePath)) {
$errorMsg = sprintf(
'Ошибка, не удалось найти файл для вложения. Путь: %s',
$filePath
);
throw new Exception($errorMsg);
}
$eol = PHP_EOL;
$uid = md5(uniqid(time()));
$fileName = basename($filePath);
$fileHandle = fopen($filePath, "r");
$contents = fread($fileHandle, filesize($filePath));
fclose($fileHandle);
$contents = chunk_split(base64_encode($contents));
$headers = "From: " . $fromName . ' <' . $fromMail . '>' . $eol;
$headers .= "Reply-To: " . $replyTo . $eol;
$headers .= "MIME-Version: 1.0" . $eol;
$headers .= "Content-Type: multipart/mixed; boundary=\"";
$headers .= $uid . "\"";
$body = "--" . $uid . $eol;
$body .= "Content-Type: text/html; charset=\"iso-8859-1\"" . $eol;
$body .= "Content-Transfer-Encoding: 8bit" . $eol . $eol;
$body .= $message . $eol;
$body .= "--" . $uid . $eol;
$body .= "Content-Type: application/octet-stream;";
$body .= " name=\"" . $fileName . "\"" . $eol;
$body .= "Content-Transfer-Encoding: base64" . $eol;
$body .= "Content-Disposition: attachment" . $eol . $eol;
$body .= $contents . $eol;
$body .= "--" . $uid . "--";
if (mail($toMail, $subject, $body, $headers) === false) {
$errorMsg = sprintf(
'Ошибка, не удалось отправить сообщение. Подробности: %s',
error_get_last()['message'] ?? 'n\a'
);
throw new Exception($errorMsg);
}
}
Пример использования, остается только подставить ваши переменные.
sendMailWithAttachment(
'Имя Фамилия',
'[email protected]',
'[email protected]',
'[email protected]',
'Тема письма',
'Текст сообщения',
__DIR__ . '/tmp/backup.tar.gz'
);