PHP как получать письма через Imap?

Тема в разделе "Как сделать...", создана пользователем jabbaxatt, 29 дек 2014.

  1. jabbaxatt

    jabbaxatt Добрый модератор

    Moderator
    Регистр.:
    21 янв 2009
    Сообщения:
    890
    Симпатии:
    418
    Соединяюсь успешно:
    Код:
     
    $loginx = "email@mypddyandexdomain.ru";
    $passwordx = "myparol";
    $serverx = "{imap.yandex.ru:993/imap/ssl}";
    
    IF ($connection = imap_open($serverx, $loginx, $passwordx))
    {Echo 'Соединение успешно';}
    else   {   Echo 'ошибка соединения';   }
    
    
    А дальше возникают вопросы.
    1) Как получать чистый текст письма и заголовка.
    2) Как получить письма от определённого (e-mail) не выкачивая все OVER 9000 писем с ящика
    3) Как разделять письма от этого определённого e-mail на цепочки переписки. Я ему написал про кошек, он мне ответил про кошек я ему ответил..... А потом он создал новое письмо, написал мне про новый год я ему ответил уже в новой цепочке.

    Я могу пройтись в цикле по всем письмам
    Код:
     
      $count = imap_num_msg($connection);
    
      for($i = 1; $i <= $count; $i++) {
      $overview = imap_fetch_overview($connection, $i);
          if (is_array($overview)) {
             foreach ($overview as $val)
             {
              $msgno=$val->msgno; // идентификатор msgno текущего письма
             }
       };
    
    
      // а дальше надо получать тело и хеадер письма в нормальном виде независимо от кодировок.
      // Стандартные команды типа
      $header_pisma=imap_fetchheader($connection,$msgno);
    // выдают весь заголовок в тексте, там уйма лишней информации, и непонятно как быть с кодировками
      // 2)  пока не знаю как решать вопрос получения писем связанных с определённым E-mail. Курить функцию imap_search? Примеров бы...
    // 3) По вопрос 3 пока тоже не нашёл
     
    
     
  2. Denixxx

    Denixxx

    Регистр.:
    7 фев 2014
    Сообщения:
    247
    Симпатии:
    194
    Для этого в письме есть поле «тема».
     
    jabbaxatt нравится это.
  3. jabbaxatt

    jabbaxatt Добрый модератор

    Moderator
    Регистр.:
    21 янв 2009
    Сообщения:
    890
    Симпатии:
    418
    А как быть с кодировкой тела письма?

    Если заголовок нормально решается через функцию imap_mime_header_decode

    то тело письма определить не могу. Особенно если кодировка тела письма не совпадает с кодировкой заголовка письма.
     
  4. Denixxx

    Denixxx

    Регистр.:
    7 фев 2014
    Сообщения:
    247
    Симпатии:
    194
    Кодировка письма и темы — это отдельная тема. Дело в том, что по стандарту тема кодируется в koi8-r, а всё остальное письмо — как получится (utf или cp). Я однажды уйму времени потратил, когда решал вопрос с кракозябликами в теме письма — разные браузеры и клиенты воспринимали по-разному. Выход был найден: кодирование всех полей в base64 — все клиенты это корректно читают с исходной utf8. И этот велосипед работает уже 4 года без сбоев. См. код на Гитхабе, строки 84-105, фунция rcms_send_mail: Перейти по ссылке
     
    jabbaxatt нравится это.
  5. jabbaxatt

    jabbaxatt Добрый модератор

    Moderator
    Регистр.:
    21 янв 2009
    Сообщения:
    890
    Симпатии:
    418
    Мне ведь не отправить письмо нужно. Мне нужно раскодировать уже отправленные разными людьми письма, в т.ч. и отправленные хрен его знает как. Выкачать их с помощью Imap и получить тело письма приведённое к UTF-8

    Например

    При использовании
    imap_body получаю

    ----
    --047d7b471fe2a6dadd050b5bf5fb Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 0J/RgNC+0YHRgtC+INGC0LXQutGB0YIg0L/QuNGB0YzQvNCwINCx0LXQtyDQstGL0LXQsdC+0L3Q vtCyLg0K --047d7b471fe2a6dadd050b5bf5fb Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 PGRpdiBkaXI9Imx0ciI+0J/RgNC+0YHRgtC+INGC0LXQutGB0YIg0L/QuNGB0YzQvNCwINCx0LXQ tyDQstGL0LXQsdC+0L3QvtCyLjxicj48L2Rpdj4NCg== --047d7b471fe2a6dadd050b5bf5fb--
    ---

    Т.е. здесь текст письма это
    ---
    PGRpdiBkaXI9Imx0ciI+0J/RgNC+0YHRgtC+INGC0LXQutGB0YIg0L/QuNGB0YzQvNCwINCx0LXQ tyDQstGL0LXQsdC+0L3QvtCyLjxicj48L2Rpdj4NCg== --047d7b471fe2a6dadd050b5bf5fb--
    ----
    Судя по всему в кодировке KOI8-R

    При использовании
    imap_fetchbody получаю

    0J/RgNC+0YHRgtC+INGC0LXQutGB0YIg0L/QuNGB0YzQvNCwINCx0LXQtyDQstGL0LXQsdC+0L3Q vtCyLg0K

    Вроде тоже KOI8-R хотя и по другому.

    Но привести к UTF-8 не могу

    Функции
    imap_base64
    base64_decode
    iconv

    Мне не помогли.
     
  6. Denixxx

    Denixxx

    Регистр.:
    7 фев 2014
    Сообщения:
    247
    Симпатии:
    194
    Может это поможет.
    В заголовке письма может быть обозначен разделитель boundary — типа так «boundary="dfhjfjcnm"»
    И потом можно этим разделителем explode делать.
    К сожалению я в imap пересылке не силён — эти сведения из обычного mailto протокола, хз есть ли в imap такое.

    А может Вам вместо imap_body попробовать imap_fetchstructure?
    Перейти по ссылке
    Там вроде уже всё поделенное массивом возвращается.