Вставка файлов в электронные сообщения средствами PHP

Раздел: Работа с файлами -> Работа с файлами

Обзор методов прикрепления файлов в PHP

Какой инструмент обеспечивает максимальную надежность и простоту для вложений?

Библиотека PHPMailer. Она абстрагирует работу с MIME, поддерживает множество транспортов и кодировок, а также предоставляет удобные методы для добавления вложений из файловой системы или строки.


// Установка: composer require phpmailer/phpmailer
require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);
try {
    $mail->setFrom('from@example.com', 'Отправитель');
    $mail->addAddress('to@example.com', 'Получатель');
    $mail->Subject = 'Письмо с файлом';
    $mail->addAttachment('/var/www/files/report.pdf', 'отчет.pdf');
    $mail->Body = 'Во вложении отчет.';
    $mail->send();
    echo 'Письмо отправлено';
} catch (Exception $e) {
    echo "Ошибка: {$mail->ErrorInfo}";
}
  

Типичные неполадки при использовании PHPMailer

Файл не найден. Если addAttachment указывает на несуществующий путь, возникает исключение. Решение: проверять наличие файла через file_exists() и использовать абсолютный путь.

Письмо уходит без вложения. Часто причина в том, что файл заблокирован или нет прав на чтение. Стоит задать корректные разрешения (например, 0644).

Цель использования:

PHPMailer подходит для проектов, где требуется стабильная отправка писем с вложениями любого типа и размера (в пределах лимитов почтового сервера).

Как отправить вложение, используя только встроенную функцию mail()?

Можно вручную сформировать multipart/mixed письмо. Этот подход не требует внешних зависимостей, но требует внимательности при построении заголовков и кодировке.


$boundary = md5(uniqid(time()));

$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\r\n";
$headers .= "From: from@example.com\r\n";

$message = "Это многочастное сообщение.\r\n\r\n";
$message .= "--{$boundary}\r\n";
$message .= "Content-Type: text/plain; charset=utf-8\r\n\r\n";
$message .= "Текст самого письма.\r\n\r\n";

$file = '/var/www/files/image.jpg';
$filename = basename($file);
$content = chunk_split(base64_encode(file_get_contents($file)));

$message .= "--{$boundary}\r\n";
$message .= "Content-Type: image/jpeg; name=\"{$filename}\"\r\n";
$message .= "Content-Disposition: attachment; filename=\"{$filename}\"\r\n";
$message .= "Content-Transfer-Encoding: base64\r\n\r\n";
$message .= $content . "\r\n\r\n";
$message .= "--{$boundary}--";

mail('to@example.com', 'Тема', $message, $headers);
  

Проблемы ручного формирования

Кириллическая тема. Функция mail() не кодирует тему автоматически. Используйте mb_encode_mimeheader(): $subject = mb_encode_mimeheader('Тема письма', 'UTF-8');

Большие файлы. При размере более 5-10 МБ почтовый сервер может отклонить письмо. Рекомендуется не превышать 3 МБ для стандартных хостингов.

Случаи применения:

когда недоступен Composer или требуется легковесное решение для простых вложений (небольшие PDF, изображения).

Какие альтернативные библиотеки для вложений существуют?

SwiftMailer (сейчас поддерживается как Symfony Mailer) также предоставляет удобные методы для вложений. Пример для SwiftMailer 6.x:


require 'vendor/autoload.php';

$transport = (new Swift_SmtpTransport('smtp.example.com', 587, 'tls'))
    ->setUsername('user')
    ->setPassword('pass');

$mailer = new Swift_Mailer($transport);

$message = (new Swift_Message('Письмо с вложением'))
    ->setFrom(['from@example.com' => 'Sender'])
    ->setTo(['to@example.com'])
    ->setBody('Текст письма')
    ->attach(Swift_Attachment::fromPath('/path/to/file.pdf'));

$result = $mailer->send($message);
  

Устаревание. SwiftMailer больше не обновляется. Для новых проектов рекомендуется Symfony Mailer или PHPMailer.

Когда использовать:

для проектов, уже использующих Symfony или Laravel, где интеграция с Mailer естественна.

Дополнительные примеры и сценарии

1. Множественные вложения и вложение из строки в PHPMailer

Пример

require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);
try {
    $mail->setFrom('from@example.com', 'Sender');
    $mail->addAddress('to@example.com');
    $mail->Subject = 'Несколько вложений';

    // Файл из файловой системы
    $mail->addAttachment('/files/report.pdf', 'report.pdf');
    // Вложение из строки (например, сгенерированный PDF)
    $pdfContent = file_get_contents('/files/invoice.pdf');
    $mail->addStringAttachment($pdfContent, 'invoice.pdf', 'base64', 'application/pdf');

    $mail->Body = 'Проверьте вложения.';
    $mail->send();
} catch (Exception $e) {
    echo $mail->ErrorInfo;
}
Письмо отправлено (истина)

2. Отправка через SMTP с шифрованием и авторизацией (PHPMailer)

Пример

require 'vendor/autoload.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

$mail = new PHPMailer(true);
$mail->isSMTP();
$mail->Host       = 'smtp.gmail.com';
$mail->SMTPAuth   = true;
$mail->Username   = 'user@gmail.com';
$mail->Password   = 'app_password';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port       = 587;

$mail->setFrom('user@gmail.com', 'Gmail User');
$mail->addAddress('recipient@example.com');
$mail->Subject = 'SMTP тест с вложением';
$mail->addAttachment('/tmp/file.txt', 'file.txt');
$mail->Body = 'Это письмо отправлено через Gmail SMTP.';

if ($mail->send()) {
    echo 'Успешно';
} else {
    echo $mail->ErrorInfo;
}
Успешно

3. Ручное формирование письма с поддержкой кириллицы (mail())

Пример

$boundary = md5(uniqid(time()));
$subject = mb_encode_mimeheader('Вложение с русским именем', 'UTF-8');

$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\r\n";
$headers .= "From: from@example.com\r\n";

$textPart = "--{$boundary}\r\n";
$textPart .= "Content-Type: text/plain; charset=utf-8\r\n\r\n";
$textPart .= "Текст письма.\r\n\r\n";

$file = '/var/www/images/фото.jpg';
$filename = mb_encode_mimeheader(basename($file), 'UTF-8');
$content = chunk_split(base64_encode(file_get_contents($file)));

$attachPart = "--{$boundary}\r\n";
$attachPart .= "Content-Type: image/jpeg; name=\"{$filename}\"\r\n";
$attachPart .= "Content-Disposition: attachment; filename=\"{$filename}\"\r\n";
$attachPart .= "Content-Transfer-Encoding: base64\r\n\r\n";
$attachPart .= $content . "\r\n\r\n";
$attachPart .= "--{$boundary}--";

$message = $textPart . $attachPart;

mail('to@example.com', $subject, $message, $headers);
Письмо отправлено (true)

4. Проверка существования файла перед добавлением и обработка исключений

Пример

function safeAttach(PHPMailer $mail, string $filePath, string $displayName = ''): bool {
    if (!file_exists($filePath)) {
        throw new Exception("Файл не найден: {$filePath}");
    }
    if (!is_readable($filePath)) {
        throw new Exception("Нет прав на чтение: {$filePath}");
    }
    $mail->addAttachment($filePath, $displayName);
    return true;
}

$mail = new PHPMailer(true);
try {
    $mail->setFrom('from@example.com');
    $mail->addAddress('to@example.com');
    $mail->Subject = 'Тест';
    safeAttach($mail, '/tmp/data.xlsx', 'data.xlsx');
    $mail->send();
} catch (Exception $e) {
    echo 'Ошибка: ' . $e->getMessage();
}
Ошибка: Файл не найден: /tmp/data.xlsx
- Php дата файла (получение даты файла в php)
- Php index вопрос (вопрос по index.php)
- File api php (файловое api на php)
- Root php (корневая директория сервера в php)
- Txt php (работа с текстовыми файлами php)
- Index php path (пути файлов в php)
- Start php include (подключение файлов)
- Php файлы изменение (изменение файлов в php)
- Dir php (работа с директориями в php)
- Php временный файл (работа с временными файлами в php)
- Php файл (работа с файлами в php)
- Upload php (загрузка файлов на php)
- Php include get (использование include с get параметрами)
- Php file content (чтение содержимого файла в php)
- Php file directory (php: пути к файлам и директориям)
- время файла php (получение времени изменения файла в php)
- Php file lines (чтение строк файла в php)
- Php вывод файлов (вывод содержимого файла в php)
- Disks php (работа с дисками в php)
- Php attachments (работа с вложениями файлов в php)
- Php open file (открытие файла в php)
- Php path (пути в php)
- обновление файлов php (обновление файлов в php)
- Files php name (получение имени файла в php)
- Loading php (загрузка файлов в php)
- Php управление файлами (управление файлами в php)

Работа с вложениями файлов в PHP - comments

En
Php attachments (php)