Описание использованных функций (
func.php):
";
}
//вывод содержимого объекта на экран
function debugObj($obj){
echo "<";
echo "pre style='color:green'>";
print_r($obj);
echo "";
echo "pre>";
}
//получение заголовка письма в виде объекта
function getHeader($mbox,$uid){
return imap_rfc822_parse_headers(getHeaderRaw($mbox,$uid));
}
//получение заголовка письма
function getHeaderRaw($mbox,$uid){
return imap_fetchbody($mbox, $uid, '0', FT_UID);
}
//раскодировка заголовка
function getDecodedHeader($text){
//imap_mime_header_decode - декодирует элементы MIME-шапки в виде массива
//У каждого элемента указана кодировка(charset) и сам текст(text)
$elements = imap_mime_header_decode($text);
$ret = "";
//перебираем элементы
for ($i=0; $icharset;//кодировка
$text = $elements[$i]->text;//закодированный текст
if($charset == 'default'){
//если элемент не кодирован, то значение кодировки default
$ret .= $text;
}else{
//приводим всё кодировке к UTF-8
$ret .= iconv($charset,"UTF-8",$text);
}
}
return $ret;
}
//получение содержимого письма в виде простого текста
function getTextBody($imap,$uid){
return getPart($imap, $uid, "TEXT/PLAIN");
}
//получение содержимого письма в виде формате html
function getHtmlBody($imap,$uid){
return getPart($imap, $uid, "TEXT/HTML");
}
//получение части письма
function getPart($imap, $uid, $mimetype) {
//получение структуры письма
$structure = imap_fetchstructure($imap, $uid, FT_UID);
if ($structure) {
if ($mimetype == getMimeType($structure)) {
$partNumber = 1;
//imap_fetchbody - извлекает определённый раздел тела сообщения
$text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
$charset = $structure->parameters[0]->value;//кодировка символов
//0 - 7BIT; 1 - 8BIT; 2 - BINARY; 3 - BASE64; 4 - QUOTED-PRINTABLE; 5 - OTHER
switch ($structure->encoding) {
case 3:
//imap_base64 - декодирует BASE64-кодированный текст
$text = imap_base64($text);
break;
case 4:
//imap_qprint - конвертирует закавыченную строку в 8-битную строку
$text = imap_qprint($text);
break;
}
if($mimetype == 'TEXT/PLAIN'){
$text = iconv($charset,"UTF-8",$text);
}
if($mimetype == 'TEXT/HTML'){
$text = iconv($charset,"UTF-8",$text);
}
return $text;
}
}
return false;
}
//MIME-тип передается числом, а подтип - текстом.
//Функция приводит все в текстовый вид.
//Например: если type = 0 и subtype = "PLAIN",
//то функция вернет "TEXT/PLAIN".
//TEXT - 0, MULTIPART - 1, .. , APPLICATION - 3 и т.д.
function getMimeType($structure) {
$primaryMimetype = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION",
"AUDIO", "IMAGE", "VIDEO", "OTHER");
if ($structure->subtype) {
return $primaryMimetype[(int)$structure->type] . "/" . $structure->subtype;
}
return "TEXT/PLAIN";
}
//перевести текст в дату MySQL
function strToMysqlDate($text){
$unixTimestamp=strtotime($text);
return date("Y-m-d H:i:s", $unixTimestamp);
}
//заполняем ассоциативный массив, где ключом является тип адреса,
//а значение массив адресов
function getAddress($header,$type,&$map){
//проверка существования типа в заголовке
if(property_exists($header,$type)){
$arr = $header->$type;
if(is_array($arr) && count($arr) > 0){
$map[$type] = $arr;
}
}
}
//загрузка вложений
function loadAttaches($mbox,$uid,$message_id){
//получаем структуру сообщения
$struct = imap_fetchstructure($mbox,$uid,FT_UID);
$attachCount = 0;
if(!$struct->parts) return $attachCount;
//перебираем части сообщения
foreach($struct->parts as $number => $part){
//ищем части, у которых ifdisposition равно 1 и disposition равно ATTACHMENT,
//все остальные части игнорируем. Также стоит заметить, что значение поля
//disposition может быть как в верхнем, так и в нижнем регистрах,
//т.е. может быть "attachment" и "ATTACHMENT". Поэтому в коде всё приведено
//к верхнему регистру
if(!$part->ifdisposition
|| strtoupper($part->disposition) != "ATTACHMENT")continue;
//получаем название файла
$filename = getDecodedHeader($part->dparameters[0]->value);
//получаем содержимое файла в закодированном виде
$text = imap_fetchbody($mbox, $uid, $number + 1, FT_UID);
//декодирование содержимого файла
switch ($part->encoding) {
case 3:
$text = imap_base64($text);
break;
case 4:
$text = imap_qprint($text);
break;
}
//оригинальное название файла будем сохранять в базе данных.
//Разные письма могут иметь вложения с одинаковыми названиями,
//поэтому в файловой системе будем сохранять файла с уникальным именем,
//сохранив при этом расширение файла
$file_path = getStoreDirectory() . getUid() . getFileExtension($filename);
file_put_contents($file_path,$text);
$content_type = getMimeType($part);//MIME-тип файла
$filesize = strlen($text);//размер файла
//записываем информацию о файле в базу данных. Напомню, что в
//базу сохраняется не сам файл, а относительный путь к файлу
$sql = "INSERT INTO attachments(message_id,file_name,mime_type,
file_size,location)" .
"VALUES('$message_id',
'" . mysql_real_escape_string($filename) . "',
'" . mysql_real_escape_string($content_type) . "',
$filesize,
'" . mysql_real_escape_string($file_path) . "')";
$res_ins = mysql_query($sql) or die(mysql_error());
$attachCount++;
}
return $attachCount;
}
//Функция для получения пути к директории, где будут храниться файлы.
//Файлы будут сохраняться в поддиректории, созданной по
//текущей дате. Например, 2014-07-31. Это позволит
//не держать файлы в одной директории. Много файлом в
//одной директории замедляет чтение директории
function getStoreDirectory(){
global $FILES;
$date_folder = "$FILES/" . date('Y-m-d') . "/";
if(!file_exists($date_folder)) mkdir($date_folder);
return $date_folder;
}
//генерация уникального идентификатора
function getUid(){
if (function_exists('com_create_guid')){
return str_replace("}", "", str_replace("{", "", com_create_guid()));
} else {
mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid =
substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr($charid,16, 4).$hyphen
.substr($charid,20,12);
}
return strtolower($uuid);
}
//получаем расширение файла
function getFileExtension($filename){
$arr = explode(".",$filename);
return count($arr) > 1 ? "." . end($arr) : "";
}
?>
Файл для подключения к базе данных (
connect.php):
Исходный код можно скачать
здесь
Спасибо за скрипт, однако есть ошибки:
При внесении записей в mailbox необходимо в запрос добавить поле last_message_uid, иначе появляется лишний аргумент в VALUE.
Кроме того некорректно грузятся письма, а именно в большинстве писем не грузится тело письма. Причину пока не нашел.
Буду благодарен, если подскажете где рыть.
Да, и функция getMimeType в вашей записи должна всегда возвращать «TEXT/PLAIN».
очень понравился ваш скрипт. допилю веб морду к базе и буду использовать.
ошибка в sql «INSERT INTO mailboxes(email,password,host,port,is_ssl,is_deleted) VALUES», не хватает еще «last_message_uid».
спасибо за Вашу работу
Спасибо за скрипт. Согласен с замечаниями выше.
Копать по поводу тела письма тут: getPart();
Пока не копал. Как докопаю выложу.
Привет, лучший скрипт из всех что я встречал. Вот если бы другие тоже было бы описаны типы…
Может это поможет
http://www.linuxscope.net/articles/mailAttachmentsPHP.html
По поводу того что не все тела писем читаются: в getPart вырежьте флаг FT_UID — без него всё прекрасно.
function getPart($imap, $uid, $mimetype) {
//получение структуры письма
$structure = imap_fetchstructure($imap, $uid, FT_UID);
if ($structure) {
if ($mimetype = getMimeType($structure)) {
$partNumber = 1;
//imap_fetchbody — извлекает определённый раздел тела сообщения
$text = imap_fetchbody($imap, $uid, $partNumber, FT_UID);
// $charset = $structure->parameters[0]->value;//кодировка символов
//0 — 7BIT; 1 — 8BIT; 2 — BINARY; 3 — BASE64; 4 — QUOTED-PRINTABLE; 5 — OTHER
// switch ($structure->encoding) {
// case 3:
//imap_base64 — декодирует BASE64-кодированный текст
$text = imap_base64($text);
// break;
// case 4:
// //imap_qprint — конвертирует закавыченную строку в 8-битную строку
// $text = imap_qprint($text);
// break;
// }
// if($mimetype == ‘TEXT/PLAIN’){
// $text = iconv($charset,»UTF-8″,$text);
// }
// if($mimetype == ‘TEXT/HTML’){
// $text = iconv($charset,»UTF-8″,$text);
// }
return $text;
}
}
return false;
}
Спасибо за скрипт.