| Всем привет и с новым годом!
Сделал скрипт, который собирает файлы с почты mail.ru и закидывает их в орпеделенную папку на сервере. Все работает, вот только если приложенный файл является архивом, а в нем файлы с именами на русском, то на выходе получается следующее, например, в архиве "Копия прайс.zip" заархивирован файл "Копия прайс.csv". После срабатывания скрипта получаю файл "Љ®ЇЁп Їа ©б.csv". Подскажите пожалуйста как решить эту проблему? Огромное спасибо!!!
<?php
function decode_header($header, $out_charset) //декодирование имен файлов и заголовков
{
preg_match_all('/=\\?(.+?)\\?(.+?)\\?(.+?)((\\s)|\\?=|$)/', $header, $matches);
for($i = 0; $i < count($matches[0]); $i++)
{
switch( strtoupper($matches[2][$i]) )
{
case 'B': $matches[3][$i] = imap_base64($matches[3][$i]); break;
case 'QP': $matches[3][$i] = imap_qprint($matches[3][$i]); break;
default:
trigger_error('Unknown encoding: ' . $matches[2][$i]);
return false;
}
$matches[3][$i] .= $matches[5][$i];
if( strtoupper($matches[1][$i]) != strtoupper($out_charset) )
{
$matches[3][$i] = iconv($matches[1][$i], $out_charset . '//IGNORE', $matches[3][$i]);
}
}
return str_replace($matches[0], $matches[3], $header);
}
function DeArhive($FileName,$Folder)//функция разархивирования - надо указать имя файла (путь и имя файла) и путь куда разархивировать файлы
{
$zip = zip_open($FileName);
$folder = substr(str_replace("\\", "/", __FILE__), 0, strrpos(str_replace("\\", "/", __FILE__), "/"))."/".$Folder;
//echo "Папка <b>".$folder."</b><br />\n";
$files = 0;
$folders = 0;
if ($zip) {
while ($zip_entry = zip_read($zip)) {
echo "<br />\n";
$name = $folder . zip_entry_name($zip_entry);
if($name[strlen($name) - 1] == '/') {
mkdir($name, 0755);
$folders++;
} elseif (zip_entry_open($zip, $zip_entry, "r")) {
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
$file = fopen($name, "w");
if ($file) {
fwrite($file, $buf);
fclose($file);
$files++;
} else {
//echo "Ошибка при открытии файла <b>".$name."</b>";
}
zip_entry_close($zip_entry);
}
}
//echo "Готово! Разархивировано <b>".$files."</b> файлов и <b>".$folders."</b> папок";
zip_close($zip);
} else {
//echo "Ошибка при открытии архива!";
}
}
function CheckArhive($Folder) //функция находит файлы-архивы и запускает функцию разархивирования - надо указать путь к папке, где искать архивы
{
// Открываем директорию
$dir = opendir($Folder);
// В цикле считываем её содержимое
while(($file = readdir($dir)))
{
$file=(string)$file;
if($file!="." && $file!="..")
if(is_resource(zip_open($Folder."".$file)))DeArhive($Folder."".$file,'FilesImap/');
}
//закрываем директорию
closedir($dir);
}
// Первый аргумент imap_open() - сервер и путь к почтовому ящику на этом сервере
// Например, для MAIL.RU выглядит так:
define( 'MAILBOX', '{pop.mail.ru:110/pop3}INBOX' );
// ...
define( 'USER','test-code@mail.ru' );
define( 'PASS','*****' );
// Возможные виды кодирования данных
// Ввод этих констант нужен только для дальнейшего улучшения читабельности кода
define( 'ENC_7BIT', 0 );
define( 'ENC_8BIT', 1 );
define( 'ENC_BINARY', 2 );
define( 'ENC_BASE64', 3 ); // Чаще всего для передачи вложений их кодируют в base64
define( 'ENC_QUOTED_PRINTABLE', 4 );
define( 'ENC_OTHER', 5 );
// Если IMAP-библиотека не подключена или отсутствует в этой сборке
if( !function_exists('imap_open') )
{
die( 'IMAP lib does not exist' );
}
// Создание файла для записи timestamp'а
if( !is_file('upload_timestamp.txt') )
{
if( is_writable('.') )
{
fclose(fopen('upload_timestamp.txt', 'w'));
}
else
{
die( 'Could not mk "upload_timestamp.txt"' );
}
}
// Массив для attachment'ов (вложений)
$attachment = array();
$upload_timestamp = (int) file_get_contents( 'upload_timestamp.txt' );
//На время DEBUG'а
$upload_timestamp = 0;
// Проверка ящика не чаще, чем раз в 3 минуты
if( $upload_timestamp < time() - 180 )
{
// Соединение с почтовым сервером
if( !($mbox = imap_open(MAILBOX, USER, PASS)) )
{
die( 'Could not open mailbox' );
}
// Получение кол-ва писем на сервере
$num_msg = imap_num_msg( $mbox );
// Перебор всех писем
for($i = $num_msg; $i > 0; $i--)
{
// Структура письма
$structure = imap_fetchstructure($mbox, $i);
// Перебор частей писем (письмо, состоящее из одной части не содержит аттачей)
for($p = 0; isset($structure->parts) && $p < count($structure->parts); $p++)
{
// Если это вложение, ...
if( $structure->parts[$p]->ifdisposition && strtoupper($structure->parts[$p]->disposition) == 'ATTACHMENT' )
{
// ..., то получаем его
$buffer = imap_fetchbody($mbox, $i, $p + 1, FT_PEEK);
// Раскодирование
switch( $structure->parts[$p]->encoding )
{
case ENC_BASE64: $buffer = imap_base64($buffer); break;
// ...
}
// Запихивем в массив имя файла, которое было на клиентской машине, и его содержимое
$attachment[] = array(
'filename' => $structure->parts[$p]->parameters[0]->value,
'content' => $buffer
);
}
else if( $structure->parts[$p]->ifsubtype && strtoupper($structure->parts[$p]->subtype) == 'PLAIN' )
{
// Письмо без вложений - не записываеется в массив
}
}
}
// Закрытие соединения
imap_close( $mbox );
}
// Запись timestamp'а последней проверки почтового ящика
$fh = fopen('upload_timestamp.txt', 'w');
fwrite($fh, time());
fclose($fh);
for($i=0;$i<count($attachment);$i++)
{
$attachment[$i]['filename']=decode_header($attachment[$i]['filename'], 'windows-1251');
$fh=fopen('FilesImap/'.$attachment[$i]['filename'],'wb');
fwrite($fh,$attachment[$i]['content']);
fclose($fh);
}
CheckArhive('FilesImap/');
?>
|
| |