Intereting Posts
Использование многомерных массивов PHP для преобразования MySQL в JSON Выберите опцию в PHP, не вернувшись обратно Как подсчитать, сколько врачей забронировано каждым пациентом? Запрос активной записи Codeigniter занимает слишком много времени для загрузки данных из базы данных Отбрасывание десятичных знаков PHP без округления PHP cURL: HTTP-заголовки показывают 302 и файлы cookie, файлы cookie сохраняются и отправляются, появляются одни и те же заголовки? Являются ли PHP DateInterval сопоставимыми с DateTime? Получение расширения домена из URL? Можете ли вы сказать PHP, чтобы отправлять заголовки (например, 500), когда возникает ошибка? Получить все переменные $ _POST, начиная с определенного текста Как изменить размер изображения с помощью php? Пропущенные массивы теряют все, кроме первого элемента Получить данные из php в скрипт c # Laravel 5.3 Тесные отношения Разрешение неправильной кодировки символов при отображении результатов базы данных MySQL после обновления до PHP 5.3

php imap – получить тело и сделать простой текст

Я использую функцию imap PHP для получения писем из почтового ящика POP3 и вставки данных в базу данных MySQL.

Вот код PHP:

$inbox = imap_open($hostname,$username,$password) or die('Cannot connect: ' . imap_last_error()); $emails = imap_search($inbox,'ALL'); if($emails) { $output = ''; rsort($emails); foreach($emails as $email_number) { $header=imap_headerinfo($inbox,$email_number); $from = $header->from[0]->mailbox . "@" . $header->from[0]->host; $toaddress=$header->toaddress; $replyto=$header->reply_to[0]->mailbox."@".$header->reply_to[0]->host; $datetime=date("Ymd H:i:s",$header->udate); $subject=$header->subject; //remove the " from the $toaddress $toaddress = str_replace('"','',$toaddress); echo '<strong>To:</strong> '.$toaddress.'<br>'; echo '<strong>From:</strong> '.$from.'<br>'; echo '<strong>Subject:</strong> '.$subject.'<br>'; //get message body $message = (imap_fetchbody($inbox,$email_number,1.1)); if($message == '') { $message = (imap_fetchbody($inbox,$email_number,1)); } } 

Он работает нормально, однако на некоторых электронных сообщениях в теле я получаю = между словами или =20 между словами. И в других случаях электронные письма будут просто пустыми, даже если они не пустые при отправке.

Это происходит только при использовании определенных электронных писем.

Как я могу обойти это и просто сделать письмо полностью открытым текстом?

Related of "php imap – получить тело и сделать простой текст"

Это происходит потому, что письма обычно закодированы в кодировке Quoted-printable . The = – мягкий разрыв строки и =20 – пробел. Я думаю, вы могли бы использовать quoted_printable_decode () в сообщении, чтобы он отображался правильно. О пустых электронных письмах, я не знаю, мне понадобится более подробная информация.

В основном :

 //get message body $message = quoted_printable_decode(imap_fetchbody($inbox,$email_number,1.1)); 

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

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

ImapReader.class.php Вот исходный код.

 <?php class ImapReader { private $host; private $port; private $user; private $pass; private $box; private $box_list; private $errors; private $connected; private $list; private $deleted; const FROM = 0; const TO = 1; const REPLY_TO = 2; const SUBJECT = 3; const CONTENT = 4; const ATTACHMENT = 5; public function __construct($host = null, $port = '143', $user = null, $pass = null) { $this->host = $host; $this->port = $port; $this->user = $user; $this->pass = $pass; $this->box = null; $this->box_list = null; $this->errors = array (); $this->connected = false; $this->list = null; $this->deleted = false; } public function __destruct() { if ($this->isConnected()) { $this->disconnect(); } } public function changeServer($host = null, $port = '143', $user = null, $pass = null) { if ($this->isConnected()) { $this->disconnect(); } $this->host = $host; $this->port = $port; $this->user = $user; $this->pass = $pass; $this->box_list = null; $this->errors = array (); $this->list = null; return $this; } public function canConnect() { return (($this->connected == false) && (is_string($this->host)) && (!empty($this->host)) && (is_numeric($this->port)) && ($this->port >= 1) && ($this->port <= 65535) && (is_string($this->user)) && (!empty($this->user)) && (is_string($this->pass)) && (!empty($this->pass))); } public function connect() { if ($this->canConnect()) { $this->box = @imap_open("{{$this->host}:{$this->port}/imap/ssl/novalidate-cert}INBOX", $this->user, $this->pass); if ($this->box !== false) { $this->_connected(); } else { $this->errors = array_merge($this->errors, imap_errors()); } } return $this; } public function boxList() { if (is_null($this->box_list)) { $list = imap_getsubscribed($this->box, "{{$this->host}:{$this->port}}", "*"); $this->box_list = array (); foreach ($list as $box) { $this->box_list[] = $box->name; } } return $this->box_list; } public function fetchAllHeaders($mbox) { if ($this->isConnected()) { $test = imap_reopen($this->box, "{$mbox}"); if (!$test) { return false; } $num_msgs = imap_num_msg($this->box); $this->list = array (); for ($id = 1; ($id <= $num_msgs); $id++) { $this->list[] = $this->_fetchHeader($mbox, $id); } return true; } return false; } public function fetchSearchHeaders($mbox, $criteria) { if ($this->isConnected()) { $test = imap_reopen($this->box, "{$mbox}"); if (!$test) { return false; } $msgs = imap_search($this->box, $criteria); if ($msgs) { foreach ($msgs as $id) { $this->list[] = $this->_fetchHeader($mbox, $id); } } return true; } return false; } public function isConnected() { return $this->connected; } public function disconnect() { if ($this->connected) { if ($this->deleted) { imap_expunge($this->box); $this->deleted = false; } imap_close($this->box); $this->connected = false; $this->box = null; } return $this; } /** * Took from khigashi dot oang at gmail dot com at php.net * with replacement of ereg family functions by preg's ones. * * @param string $str * @return string */ private function _fix($str) { if (preg_match("/=\?.{0,}\?[Bb]\?/", $str)) { $str = preg_split("/=\?.{0,}\?[Bb]\?/", $str); while (list($key, $value) = each($str)) { if (preg_match("/\?=/", $value)) { $arrTemp = preg_split("/\?=/", $value); $arrTemp[0] = base64_decode($arrTemp[0]); $str[$key] = join("", $arrTemp); } } $str = join("", $str); } if (preg_match("/=\?.{0,}\?Q\?/", $str)) { $str = quoted_printable_decode($str); $str = preg_replace("/=\?.{0,}\?[Qq]\?/", "", $str); $str = preg_replace("/\?=/", "", $str); } return trim($str); } private function _connected() { $this->connected = true; return $this; } public function getErrors() { $errors = $this->errors; $this->errors = array (); return $errors; } public function count() { if (is_null($this->list)) { return 0; } return count($this->list); } public function get($nbr = null) { if (is_null($nbr)) { return $this->list; } if ((is_array($this->list)) && (isset($this->list[$nbr]))) { return $this->list[$nbr]; } return null; } public function fetch($nbr = null) { return $this->_callById('_fetch', $nbr); } private function _fetchHeader($mbox, $id) { $header = imap_header($this->box, $id); if (!is_object($header)) { continue; } $mail = new stdClass(); $mail->id = $id; $mail->mbox = $mbox; $mail->timestamp = (isset($header->udate)) ? ($header->udate) : (''); $mail->date = date("d/m/YH:i:s", (isset($header->udate)) ? ($header->udate) : ('')); $mail->from = $this->_fix(isset($header->fromaddress) ? ($header->fromaddress) : ('')); $mail->to = $this->_fix(isset($header->toaddress) ? ($header->toaddress) : ('')); $mail->reply_to = $this->_fix(isset($header->reply_toaddress) ? ($header->reply_toaddress) : ('')); $mail->subject = $this->_fix(isset($header->subject) ? ($header->subject) : ('')); $mail->content = array (); $mail->attachments = array (); $mail->deleted = false; return $mail; } private function _fetch($mail) { $test = imap_reopen($this->box, "{$mail->mbox}"); if (!$test) { return $mail; } $structure = imap_fetchstructure($this->box, $mail->id); if ((!isset($structure->parts)) || (!is_array($structure->parts))) { $body = imap_body($this->box, $mail->id); $content = new stdClass(); $content->type = 'content'; $content->mime = $this->_fetchType($structure); $content->charset = $this->_fetchParameter($structure->parameters, 'charset'); $content->data = $this->_decode($body, $structure->type); $content->size = strlen($content->data); $mail->content[] = $content; return $mail; } else { $parts = $this->_fetchPartsStructureRoot($mail, $structure); foreach ($parts as $part) { $content = new stdClass(); $content->type = null; $content->data = null; $content->mime = $this->_fetchType($part->data); if ((isset($part->data->disposition)) && ((strcmp('attachment', $part->data->disposition) == 0) || (strcmp('inline', $part->data->disposition) == 0))) { $content->type = $part->data->disposition; $content->name = null; if (isset($part->data->dparameters)) { $content->name = $this->_fetchParameter($part->data->dparameters, 'filename'); } if (is_null($content->name)) { if (isset($part->data->parameters)) { $content->name = $this->_fetchParameter($part->data->parameters, 'name'); } } $mail->attachments[] = $content; } else if ($part->data->type == 0) { $content->type = 'content'; $content->charset = null; if (isset($part->data->parameters)) { $content->charset = $this->_fetchParameter($part->data->parameters, 'charset'); } $mail->content[] = $content; } $body = imap_fetchbody($this->box, $mail->id, $part->no); if (isset($part->data->encoding)) { $content->data = $this->_decode($body, $part->data->encoding); } else { $content->data = $body; } $content->size = strlen($content->data); } } return $mail; } private function _fetchPartsStructureRoot($mail, $structure) { $parts = array (); if ((isset($structure->parts)) && (is_array($structure->parts)) && (count($structure->parts) > 0)) { foreach ($structure->parts as $key => $data) { $this->_fetchPartsStructure($mail, $data, ($key + 1), $parts); } } return $parts; } private function _fetchPartsStructure($mail, $structure, $prefix, &$parts) { if ((isset($structure->parts)) && (is_array($structure->parts)) && (count($structure->parts) > 0)) { foreach ($structure->parts as $key => $data) { $this->_fetchPartsStructure($mail, $data, $prefix . "." . ($key + 1), $parts); } } $part = new stdClass; $part->no = $prefix; $part->data = $structure; $parts[] = $part; } private function _fetchParameter($parameters, $key) { foreach ($parameters as $parameter) { if (strcmp($key, $parameter->attribute) == 0) { return $parameter->value; } } return null; } private function _fetchType($structure) { $primary_mime_type = array ("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER"); if ((isset($structure->subtype)) && ($structure->subtype) && (isset($structure->type))) { return $primary_mime_type[(int) $structure->type] . '/' . $structure->subtype; } return "TEXT/PLAIN"; } private function _decode($message, $coding) { switch ($coding) { case 2: $message = imap_binary($message); break; case 3: $message = imap_base64($message); break; case 4: $message = imap_qprint($message); break; case 5: break; default: break; } return $message; } private function _callById($method, $data) { $callback = array ($this, $method); // data is null if (is_null($data)) { $result = array (); foreach ($this->list as $mail) { $result[] = $this->_callById($method, $mail); } return $result; } // data is an array if (is_array($data)) { $result = array (); foreach ($data as $elem) { $result[] = $this->_callById($method, $elem); } return $result; } // data is an object if ((is_object($data)) && ($data instanceof stdClass) && (isset($data->id))) { return call_user_func($callback, $data); } // data is numeric if (($this->isConnected()) && (is_array($this->list)) && (is_numeric($data))) { foreach ($this->list as $mail) { if ($mail->id == $data) { return call_user_func($callback, $mail); } } } return null; } public function delete($nbr) { $this->_callById('_delete', $nbr); return; } private function _delete($mail) { if ($mail->deleted == false) { $test = imap_reopen($this->box, "{$mail->mbox}"); if ($test) { $this->deleted = true; imap_delete($this->box, $mail->id); $mail->deleted = true; } } } public function searchBy($pattern, $type) { $result = array (); if (is_array($this->list)) { foreach ($this->list as $mail) { $match = false; switch ($type) { case self::FROM: $match = $this->_match($mail->from, $pattern); break; case self::TO: $match = $this->_match($mail->to, $pattern); break; case self::REPLY_TO: $match = $this->_match($mail->reply_to, $pattern); break; case self::SUBJECT: $match = $this->_match($mail->subject, $pattern); break; case self::CONTENT: foreach ($mail->content as $content) { $match = $this->_match($content->data, $pattern); if ($match) { break; } } break; case self::ATTACHMENT: foreach ($mail->attachments as $attachment) { $match = $this->_match($attachment->name, $pattern); if ($match) { break; } } break; } if ($match) { $result[] = $mail; } } } return $result; } private function _nmatch($string, $pattern, $a, $b) { if ((!isset($string[$a])) && (!isset($pattern[$b]))) { return 1; } if ((isset($pattern[$b])) && ($pattern[$b] == '*')) { if (isset($string[$a])) { return ($this->_nmatch($string, $pattern, ($a + 1), $b) + $this->_nmatch($string, $pattern, $a, ($b + 1))); } else { return ($this->_nmatch($string, $pattern, $a, ($b + 1))); } } if ((isset($string[$a])) && (isset($pattern[$b])) && ($pattern[$b] == '?')) { return ($this->_nmatch($string, $pattern, ($a + 1), ($b + 1))); } if ((isset($string[$a])) && (isset($pattern[$b])) && ($pattern[$b] == '\\')) { if ((isset($pattern[($b + 1)])) && ($string[$a] == $pattern[($b + 1)])) { return ($this->_nmatch($string, $pattern, ($a + 1), ($b + 2))); } } if ((isset($string[$a])) && (isset($pattern[$b])) && ($string[$a] == $pattern[$b])) { return ($this->_nmatch($string, $pattern, ($a + 1), ($b + 1))); } return 0; } private function _match($string, $pattern) { return $this->_nmatch($string, $pattern, 0, 0); } } 

ImapReader.demo.php Вот пример использования

 <?php require_once("ImapReader.class.php"); $box = new ImapReader('example.com', '143', 'somebody@example.com', 'xxxxxxxxxxxx'); $box ->connect() ->fetchAllHeaders() ; echo $box->count() . " emails in mailbox\n"; for ($i = 0; ($i < $box->count()); $i++) { $msg = $box->get($i); echo "Reception date : {$msg->date}\n"; echo "From : {$msg->from}\n"; echo "To : {$msg->to}\n"; echo "Reply to : {$msg->from}\n"; echo "Subject : {$msg->subject}\n"; $msg = $box->fetch($msg); echo "Number of readable contents : " . count($msg->content) . "\n"; foreach ($msg->content as $key => $content) { echo "\tContent " . ($key + 1) . " :\n"; echo "\t\tContent type : {$content->mime}\n"; echo "\t\tContent charset : {$content->charset}\n"; echo "\t\tContent size : {$content->size}\n"; } echo "Number of attachments : " . count($msg->attachments) . "\n"; foreach ($msg->attachments as $key => $attachment) { echo "\tAttachment " . ($key + 1) . " :\n"; echo "\t\tAttachment type : {$attachment->type}\n"; echo "\t\tContent type : {$attachment->mime}\n"; echo "\t\tFile name : {$attachment->name}\n"; echo "\t\tFile size : {$attachment->size}\n"; } echo "\n"; } echo "Searching '*Bob*' ...\n"; $results = $box->searchBy('*Bob*', ImapReader::FROM); foreach ($results as $result) { echo "\tMatched: {$result->from} - {$result->date} - {$result->subject}\n"; } 

наслаждаться

 $data = imap_fetchbody($this->imapStream, $Part->uid, $Part->path, FT_UID | FT_PEEK); if ($Part->format === 'quoted-printable' && $data) { $data = quoted_printable_decode($data); } 

Это необходимо для писем с

Content-Transfer-Encoding: цитируемый-печатный

Но для писем с

Content-Transfer-Encoding: 8 бит

просто imap_fetchbody достаточно.

Выше код был взят из компонента cake-php, созданного для извлечения почтовых ящиков из почтовых ящиков через IMAP.

Что касается пустых писем, проверьте кодировку почты.

Если это двоичная кодированная почта, тогда вы получите пустые письма при попытке вставить их в текстовое поле mysql.

Попробуйте перевести каждую почту на UTF-8, а затем вставьте ее

iconv (mb_detect_encoding ($ mail_content, mb_detect_order (), true), "UTF-8", $ mail_content);

Я пробовал все эти ответы, но никто не работал на меня. Затем я нажал первую заметку, внесенную пользователем на эту страницу PHP:

http://php.net/manual/en/function.imap-fetchstructure.php

и это работает для всех моих дел. Довольно старый ответ кстати.