Как максимально расширить на все случаи жизни ? Для любых писем Только с PhpMimeMailParser и декодирование различных кодировок <? require_once '../vendor/autoload.php'; use PhpMimeMailParser\Parser; $eml_file = __DIR__ . '/attachments\2025\07\08\12b30715c8ccae21e2b05c2fe7faee6e/1751972486.eml'; $eml_file = __DIR__ . '/attachments/2025/07/08/9df0df4d80701d9302f892956da27d6d/1751963059.eml'; function parse_eml_full($emlFile) { $parser = new Parser(); $parser->setPath($emlFile); // Заголовки echo "<h2>Заголовки</h2><table border='1' cellpadding='5'>"; foreach ($parser->getHeaders() as $header => $value) { if (is_array($value)) $value = implode(", ", $value); echo "<tr><td><strong>" . htmlspecialchars($header) . "</strong></td><td>" . htmlspecialchars($value) . "</td></tr>"; } echo "</table>"; // От кого / Кому / Тема echo "<h3>Отправитель: " . htmlspecialchars($parser->getHeader('from')) . "</h3>"; echo "<h3>Получатель: " . htmlspecialchars($parser->getHeader('to')) . "</h3>"; echo "<h3>Тема: " . htmlspecialchars($parser->getHeader('subject')) . "</h3>"; // Тело письма echo "<h2>Тело письма (plain text)</h2>"; echo "<pre>" . htmlspecialchars($parser->getMessageBody('text')) . "</pre>"; echo "<h2>Тело письма (HTML)</h2>"; echo "<div style='border:1px solid #ccc;padding:10px;margin:10px 0;'>" . $parser->getMessageBody('html') . "</div>"; // Вложения $attachments = $parser->getAttachments(); echo "<h2>Вложения</h2>"; if (empty($attachments)) { echo "<p>Нет вложений</p>"; } else { foreach ($attachments as $attachment) { $name = $attachment->getFilename(); $size = strlen($attachment->getContent()); $savedPath = "attachments/uploads/" . $name; file_put_contents($savedPath, $attachment->getContent()); echo "<p>Файл: <strong>$name</strong> ($size байт) — <a href='$savedPath' target='_blank'>Скачать</a></p>"; } } } parse_eml_full($eml_file);

Для создания максимально универсального решения для обработки EML-файлов с использованием PhpMimeMailParser, включая поддержку различных кодировок, необходимо добавить обработку всех возможных случаев: декодирование заголовков, тел писем, вложений, работа с разными MIME-структурами и кодировками (например, base64, quoted-printable, UTF-8, Windows-1251 и т.д.). Ниже приведен расширенный код, который учитывает эти аспекты.

Основные улучшения:

  1. Декодирование заголовков: Используем mb_decode_mimeheader для корректного декодирования заголовков в любых кодировках.
  2. Обработка кодировок текста: Автоматическое определение кодировки тела письма (с использованием mb_detect_encoding) и приведение к UTF-8.
  3. Поддержка различных MIME-структур: Работа с многослойными MIME-сообщениями (multipart).
  4. Обработка вложений: Корректная работа с именами файлов в разных кодировках и сохранение вложений.
  5. Логирование ошибок: Добавлена обработка исключений для устойчивости.
  6. Универсальность: Код обрабатывает письма с отсутствующими частями (например, без HTML или текста).

Код:

php
<?php
require_once '../vendor/autoload.php';
use PhpMimeMailParser\Parser;
use PhpMimeMailParser\Attachment;
$eml_file = __DIR__ . '/attachments/2025/07/08/9df0df4d80701d9302f892956da27d6d/1751963059.eml';
function parse_eml_full($emlFile) {
try {
// Инициализация парсера
$parser = new Parser();
$parser->setPath($emlFile);
// Установка выходной кодировки
$outputEncoding = 'UTF-8';
// Декодирование заголовков
echo "<h2>Заголовки</h2><table border='1' cellpadding='5'>";
foreach ($parser->getHeaders() as $header => $value) {
if (is_array($value)) {
$value = array_map('mb_decode_mimeheader', $value);
$value = implode(", ", $value);
} else {
$value = mb_decode_mimeheader($value);
}
// Приведение к UTF-8
$value = mb_convert_encoding($value, $outputEncoding, 'auto');
echo "<tr><td><strong>" . htmlspecialchars($header) . "</strong></td><td>" . htmlspecialchars($value) . "</td></tr>";
}
echo "</table>";
// Отправитель, получатель, тема
$from = mb_decode_mimeheader($parser->getHeader('from'));
$to = mb_decode_mimeheader($parser->getHeader('to'));
$subject = mb_decode_mimeheader($parser->getHeader('subject'));
echo "<h3>Отправитель: " . htmlspecialchars(mb_convert_encoding($from, $outputEncoding, 'auto')) . "</h3>";
echo "<h3>Получатель: " . htmlspecialchars(mb_convert_encoding($to, $outputEncoding, 'auto')) . "</h3>";
echo "<h3>Тема: " . htmlspecialchars(mb_convert_encoding($subject, $outputEncoding, 'auto')) . "</h3>";
// Получение тела письма (plain text)
$textBody = $parser->getMessageBody('text');
if ($textBody) {
$textCharset = $parser->getTextCharset() ?: 'UTF-8';
$textBody = mb_convert_encoding($textBody, $outputEncoding, $textCharset);
echo "<h2>Тело письма (plain text)</h2>";
echo "<pre>" . htmlspecialchars($textBody) . "</pre>";
} else {
echo "<h2>Тело письма (plain text)</h2><p>Отсутствует</p>";
}
// Получение тела письма (HTML)
$htmlBody = $parser->getMessageBody('html');
if ($htmlBody) {
$htmlCharset = $parser->getHtmlCharset() ?: 'UTF-8';
$htmlBody = mb_convert_encoding($htmlBody, $outputEncoding, $htmlCharset);
echo "<h2>Тело письма (HTML)</h2>";
echo "<div style='border:1px solid #ccc;padding:10px;margin:10px 0;'>" . $htmlBody . "</div>";
} else {
echo "<h2>Тело письма (HTML)</h2><p>Отсутствует</p>";
}
// Обработка вложений
$attachments = $parser->getAttachments();
echo "<h2>Вложения</h2>";
if (empty($attachments)) {
echo "<p>Нет вложений</p>";
} else {
$uploadDir = __DIR__ . '/attachments/uploads/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
foreach ($attachments as $attachment) {
$filename = $attachment->getFilename();
// Декодирование имени файла
$filename = mb_decode_mimeheader($filename);
$filename = mb_convert_encoding($filename, $outputEncoding, 'auto');
// Очистка имени файла для безопасности
$filename = preg_replace('/[^A-Za-z0-9_\-\.]/', '_', $filename);
$content = $attachment->getContent();
$size = strlen($content);
$savedPath = $uploadDir . $filename;
// Сохранение файла
file_put_contents($savedPath, $content);
echo "<p>Файл: <strong>" . htmlspecialchars($filename) . "</strong> ($size байт) — <a href='attachments/uploads/" . htmlspecialchars($filename) . "' target='_blank'>Скачать</a></p>";
}
}
} catch (Exception $e) {
echo "<h2>Ошибка</h2><p>Произошла ошибка при обработке EML-файла: " . htmlspecialchars($e->getMessage()) . "</p>";
}
}
// Вызов функции
parse_eml_full($eml_file);

Что добавлено и улучшено:

  1. Декодирование заголовков:
    • Используется mb_decode_mimeheader для обработки закодированных заголовков (например, =?UTF-8?B?...?=) в любых кодировках.
    • Конвертация в UTF-8 с помощью mb_convert_encoding.
  2. Обработка кодировок тела письма:
    • Используется метод getTextCharset() и getHtmlCharset() для определения кодировки текста и HTML соответственно.
    • Автоматическая конвертация в UTF-8 для единообразного вывода.
  3. Обработка вложений:
    • Декодирование имен файлов с помощью mb_decode_mimeheader.
    • Очистка имен файлов от недопустимых символов для безопасного сохранения.
    • Проверка и создание директории для вложений.
  4. Обработка ошибок:
    • Весь код обернут в блок try-catch для перехвата возможных ошибок (например, некорректный EML-файл).
    • Вывод понятного сообщения об ошибке.
  5. Универсальность:
    • Проверка наличия текстового и HTML-тела, вывод сообщения, если они отсутствуют.
    • Корректная работа с письмами без вложений или с многослойными MIME-структурами.
  6. Безопасность:
    • Использование htmlspecialchars для предотвращения XSS-атак при выводе текста.
    • Очистка имен файлов для предотвращения проблем с файловой системой.

Дополнительные рекомендации:

  1. Логирование:
    • Добавьте логирование ошибок в файл или базу данных для отладки:
      php
      error_log($e->getMessage(), 3, __DIR__ . '/error.log');
  2. Оптимизация хранения вложений:
    • Для уникальности имен файлов можно добавлять хэш или временную метку:
      php
      $filename = time() . '_' . $filename;
  3. Поддержка больших файлов:
    • Если ожида EML-файлы большого размера, используйте потоковую обработку:
      php
      $parser->setStream(fopen($emlFile, 'r'));
  4. Кэширование:
    • Для повторной обработки EML-файлов сохраняйте результаты парсинга в базе данных или файле, чтобы не парсить заново.
  5. Поддержка других кодировок:
    • Если mb_detect_encoding не определяет кодировку, можно использовать библиотеку iconv:
      php
      $value = iconv($detectedEncoding, $outputEncoding . '//IGNORE', $value);
  6. Валидация EML-файлов:
    • Перед парсингом проверяйте, существует ли файл и доступен ли он:
      php
      if (!file_exists($emlFile) || !is_readable($emlFile)) {
      throw new Exception("Файл $emlFile не найден или недоступен");
      }

Требования:

  • Установленный пакет php-mime-mail-parser через Composer:
    bash
    composer require php-mime-mail-parser/php-mime-mail-parser
  • PHP с модулями mbstring и iconv для работы с кодировками.

Этот код максимально универсален и готов к обработке EML-файлов с любыми кодировками и структурой. Если у вас есть дополнительные требования (например, обработка специфических заголовков или форматов), напишите, и я добавлю соответствующий функционал.

2,4s
Как Grok может помочь?