Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> архивация большого количества файлов 
V
    Опции темы
dark_religion
Дата 6.6.2009, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 8.9.2006

Репутация: нет
Всего: -3



Нужно заархивировать 50 тысяч картинок. размером 1 гб. что бы не произошло переполнение и лимит по времени в 30 секунд.

Помогите. Спасибо!

Добавлено через 12 минут и 54 секунды
Код

class zipfile
{
    /*
        zipfile class, for reading or writing .zip files
        See http://www.gamingg.net for more of my work
        Based on tutorial given by John Coggeshall at http://www.zend.com/zend/spotlight/creating-zip-files3.php
        Copyright (C) Joshua Townsend and licensed under the GPL
        Version 1.0
    */
    var $datasec = array(); // array to store compressed data
    var $files = array(); // array of uncompressed files
    var $dirs = array(); // array of directories that have been created already
    var $ctrl_dir = array(); // central directory
    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
    var $old_offset = 0;
    var $basedir = ".";

    function create_dir($name) // Adds a directory to the zip with the name $name
    {
        $name = str_replace("\\", "/", $name);

        $fr = "\x50\x4b\x03\x04";
        $fr .= "\x0a\x00";    // version needed to extract
        $fr .= "\x00\x00";    // general purpose bit flag
        $fr .= "\x00\x00";    // compression method
        $fr .= "\x00\x00\x00\x00"; // last mod time and date

        $fr .= pack("V",0); // crc32
        $fr .= pack("V",0); //compressed filesize
        $fr .= pack("V",0); //uncompressed filesize
        $fr .= pack("v",strlen($name)); //length of pathname
        $fr .= pack("v", 0); //extra field length
        $fr .= $name;
        // end of "local file header" segment

        // no "file data" segment for path

        // "data descriptor" segment (optional but necessary if archive is not served as file)
        $fr .= pack("V",0); //crc32
        $fr .= pack("V",0); //compressed filesize
        $fr .= pack("V",0); //uncompressed filesize

        // add this entry to array
        $this->datasec[] = $fr;

        $new_offset = strlen(implode("", $this->datasec));

        // ext. file attributes mirrors MS-DOS directory attr byte, detailed
        // at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp

        // now add to central record
        $cdrec = "\x50\x4b\x01\x02";
        $cdrec .="\x00\x00";    // version made by
        $cdrec .="\x0a\x00";    // version needed to extract
        $cdrec .="\x00\x00";    // general purpose bit flag
        $cdrec .="\x00\x00";    // compression method
        $cdrec .="\x00\x00\x00\x00"; // last mod time and date
        $cdrec .= pack("V",0); // crc32
        $cdrec .= pack("V",0); //compressed filesize
        $cdrec .= pack("V",0); //uncompressed filesize
        $cdrec .= pack("v", strlen($name) ); //length of filename
        $cdrec .= pack("v", 0 ); //extra field length
        $cdrec .= pack("v", 0 ); //file comment length
        $cdrec .= pack("v", 0 ); //disk number start
        $cdrec .= pack("v", 0 ); //internal file attributes
        $cdrec .= pack("V", 16 ); //external file attributes  - 'directory' bit set

        $cdrec .= pack("V", $this->old_offset); //relative offset of local header
        $this->old_offset = $new_offset;

        $cdrec .= $name;
        // optional extra field, file comment goes here
        // save to array
        $this->ctrl_dir[] = $cdrec;
        $this->dirs[] = $name;
    }


    function create_file($data, $name) // Adds a file to the path specified by $name with the contents $data
    {
        $name = str_replace("\\", "/", $name);

        $fr = "\x50\x4b\x03\x04";
        $fr .= "\x14\x00";    // version needed to extract
        $fr .= "\x00\x00";    // general purpose bit flag
        $fr .= "\x08\x00";    // compression method
        $fr .= "\x00\x00\x00\x00"; // last mod time and date

        $unc_len = strlen($data);
        $crc = crc32($data);
        $zdata = gzcompress($data);
        $zdata = substr($zdata, 2, -4); // fix crc bug
        $c_len = strlen($zdata);
        $fr .= pack("V",$crc); // crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize
        $fr .= pack("v", strlen($name) ); //length of filename
        $fr .= pack("v", 0 ); //extra field length
        $fr .= $name;
        // end of "local file header" segment

        // "file data" segment
        $fr .= $zdata;

        // "data descriptor" segment (optional but necessary if archive is not served as file)
        $fr .= pack("V",$crc); // crc32
        $fr .= pack("V",$c_len); // compressed filesize
        $fr .= pack("V",$unc_len); // uncompressed filesize

        // add this entry to array
        $this->datasec[] = $fr;

        $new_offset = strlen(implode("", $this->datasec));

        // now add to central directory record
        $cdrec = "\x50\x4b\x01\x02";
        $cdrec .="\x00\x00";    // version made by
        $cdrec .="\x14\x00";    // version needed to extract
        $cdrec .="\x00\x00";    // general purpose bit flag
        $cdrec .="\x08\x00";    // compression method
        $cdrec .="\x00\x00\x00\x00"; // last mod time & date
        $cdrec .= pack("V",$crc); // crc32
        $cdrec .= pack("V",$c_len); //compressed filesize
        $cdrec .= pack("V",$unc_len); //uncompressed filesize
        $cdrec .= pack("v", strlen($name) ); //length of filename
        $cdrec .= pack("v", 0 ); //extra field length
        $cdrec .= pack("v", 0 ); //file comment length
        $cdrec .= pack("v", 0 ); //disk number start
        $cdrec .= pack("v", 0 ); //internal file attributes
        $cdrec .= pack("V", 32 ); //external file attributes - 'archive' bit set

        $cdrec .= pack("V", $this->old_offset); //relative offset of local header
        $this->old_offset = $new_offset;

        $cdrec .= $name;
        // optional extra field, file comment goes here
        // save to central directory
        $this->ctrl_dir[] = $cdrec;
    }

    function read_zip($name)
    {
        // Clear current file
        $this->datasec = array();

        // File information
        $this->name = $name;
        $this->mtime = filemtime($name);
        $this->size = filesize($name);

        // Read file
        $fh = fopen($name, "rb");
        $filedata = fread($fh, $this->size);
        fclose($fh);

        // Break into sections
        $filesecta = explode("\x50\x4b\x05\x06", $filedata);

        // ZIP Comment
        $unpackeda = unpack('x16/v1length', $filesecta[1]);
        $this->comment = substr($filesecta[1], 18, $unpackeda['length']);
        $this->comment = str_replace(array("\r\n", "\r"), "\n", $this->comment); // CR + LF and CR -> LF

        // Cut entries from the central directory
        $filesecta = explode("\x50\x4b\x01\x02", $filedata);
        $filesecta = explode("\x50\x4b\x03\x04", $filesecta[0]);
        array_shift($filesecta); // Removes empty entry/signature

        foreach($filesecta as $filedata)
        {
            // CRC:crc, FD:file date, FT: file time, CM: compression method, GPF: general purpose flag, VN: version needed, CS: compressed size, UCS: uncompressed size, FNL: filename length
            $entrya = array();
            $entrya['error'] = "";

            $unpackeda = unpack("v1version/v1general_purpose/v1compress_method/v1file_time/v1file_date/V1crc/V1size_compressed/V1size_uncompressed/v1filename_length", $filedata);

            // Check for encryption
            $isencrypted = (($unpackeda['general_purpose'] & 0x0001) ? true : false);

            // Check for value block after compressed data
            if($unpackeda['general_purpose'] & 0x0008)
            {
                $unpackeda2 = unpack("V1crc/V1size_compressed/V1size_uncompressed", substr($filedata, -12));

                $unpackeda['crc'] = $unpackeda2['crc'];
                $unpackeda['size_compressed'] = $unpackeda2['size_uncompressed'];
                $unpackeda['size_uncompressed'] = $unpackeda2['size_uncompressed'];

                unset($unpackeda2);
            }

            $entrya['name'] = substr($filedata, 26, $unpackeda['filename_length']);

            if(substr($entrya['name'], -1) == "/") // skip directories
            {
                continue;
            }

            $entrya['dir'] = dirname($entrya['name']);
            $entrya['dir'] = ($entrya['dir'] == "." ? "" : $entrya['dir']);
            $entrya['name'] = basename($entrya['name']);


            $filedata = substr($filedata, 26 + $unpackeda['filename_length']);

            if(strlen($filedata) != $unpackeda['size_compressed'])
            {
                $entrya['error'] = "Compressed size is not equal to the value given in header.";
            }

            if($isencrypted)
            {
                $entrya['error'] = "Encryption is not supported.";
            }
            else
            {
                switch($unpackeda['compress_method'])
                {
                    case 0: // Stored
                        // Not compressed, continue
                    break;
                    case 8: // Deflated
                        $filedata = gzinflate($filedata);
                    break;
                    case 12: // BZIP2
                        if(!extension_loaded("bz2"))
                        {
                            @dl((strtolower(substr(PHP_OS, 0, 3)) == "win") ? "php_bz2.dll" : "bz2.so");
                        }

                        if(extension_loaded("bz2"))
                        {
                            $filedata = bzdecompress($filedata);
                        }
                        else
                        {
                            $entrya['error'] = "Required BZIP2 Extension not available.";
                        }
                    break;
                    default:
                        $entrya['error'] = "Compression method ({$unpackeda['compress_method']}) not supported.";
                }

                if(!$entrya['error'])
                {
                    if($filedata === false)
                    {
                        $entrya['error'] = "Decompression failed.";
                    }
                    elseif(strlen($filedata) != $unpackeda['size_uncompressed'])
                    {
                        $entrya['error'] = "File size is not equal to the value given in header.";
                    }
                    elseif(crc32($filedata) != $unpackeda['crc'])
                    {
                        $entrya['error'] = "CRC32 checksum is not equal to the value given in header.";
                    }
                }

                $entrya['filemtime'] = mktime(($unpackeda['file_time']  & 0xf800) >> 11,($unpackeda['file_time']  & 0x07e0) >>  5, ($unpackeda['file_time']  & 0x001f) <<  1, ($unpackeda['file_date']  & 0x01e0) >>  5, ($unpackeda['file_date']  & 0x001f), (($unpackeda['file_date'] & 0xfe00) >>  9) + 1980);
                $entrya['data'] = $filedata;
            }

            $this->files[] = $entrya;
        }

        return $this->files;
    }
    function add_file($file, $dir = ".", $file_blacklist = array(), $ext_blacklist = array())
    {
        $file = str_replace("\\", "/", $file);
        $dir = str_replace("\\", "/", $dir);

        if(strpos($file, "/") !== false)
        {
            $dira = explode("/", "{$dir}/{$file}");
            $file = array_shift($dira);
            $dir = implode("/", $dira);
            unset($dira);
        }

        while(substr($dir, 0, 2) == "./")
        {
            $dir = substr($dir, 2);
        }
        while(substr($file, 0, 2) == "./")
        {
            $file = substr($file, 2);
        }
        if(!in_array($dir, $this->dirs))
        {
            if($dir == ".")
            {
                $this->create_dir("./");
            }
            $this->dirs[] = $dir;
        }
        if(in_array($file, $file_blacklist))
        {
            return true;
        }
        foreach($ext_blacklist as $ext)
        {
            if(substr($file, -1 - strlen($ext)) == ".{$ext}")
            {
                return true;
            }
        }

        $filepath = (($dir && $dir != ".") ? "{$dir}/" : "").$file;
        if(is_dir("{$this->basedir}/{$filepath}"))
        {
            $dh = opendir("{$this->basedir}/{$filepath}");
            while(($subfile = readdir($dh)) !== false)
            {
                if($subfile != "." && $subfile != "..")
                {
                    $this->add_file($subfile, $filepath, $file_blacklist, $ext_blacklist);
                }
            }
            closedir($dh);
        }
        else
        {
            $this->create_file(implode("", file("{$this->basedir}/{$filepath}")), $filepath);
        }

        return true;
    }


    function zipped_file() // return zipped file contents
    {
        $data = implode("", $this->datasec);
        $ctrldir = implode("", $this->ctrl_dir);

        return $data.
                $ctrldir.
                $this->eof_ctrl_dir.
                pack("v", sizeof($this->ctrl_dir)). // total number of entries "on this disk"
                pack("v", sizeof($this->ctrl_dir)). // total number of entries overall
                pack("V", strlen($ctrldir)). // size of central dir
                pack("V", strlen($data)). // offset to start of central dir
                "\x00\x00"; // .zip file comment length
    }

      function enable_modify()
      {
            foreach($this->files as $fileinzip)
            {
                  if($fileinzip['dir']!="")
                        $fileinzip['dir'].="/"         ;
                  $filename =$fileinzip['dir'].$fileinzip['name'];
                  $data =$fileinzip['data'];
                  $this->create_file($data,$filename);
            }
            
      }

      function load_zip($file)
      {
            $this->read_zip($file);
            $this->enable_modify();
      }
}


Этот класс позволяет добавлять файлы к архиву. 

Код

$zipfile1 = new zipfile; // Create an object
$zipfile1->load_zip("file2.zip"); // load the zip file into memory
$zipfile1->create_file(file_get_contents("zip.class.php"), "usetest/usecode.php"); // Add a file into zip the loaded zip

/* give the modified zip to the visitor to download without saving it to server */
header("Content-type: application/zip");
header("Content-disposition: attachment;filename=\"zip.zip\"");
echo $zipfile1->zipped_file();


Но он распаковывает файл в память. кто-то может сделать, что бы он распаковывал не впамять а в файл и потом дописывал новый файл к старым и менял заголовки. 

Вообщем что бы вся работа велась не через переменные класса а через файл. 
PM MAIL   Вверх
skyboy
Дата 6.6.2009, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



под "переполнением" ты понимаешь превышение лимита на память?
превышения лимита времени выполнения решается просто:
1. либо установкой set_time_limit, либо установкой параметра max_time_execution через php.ini/.htaccess(если хостер позволяет)
2. вставка выполнения скрипта в расписание через cron/window'вый планировщик. и скрипт выполняется в некоторое время планировщиком в режиме консоли, безо всяких ограничений по времени.
я считаю второй вариант лучше(несколько раз нажав на кнопку "упаковать", человек не запустит несколько раз скрипт упаковки).
сама упаковка(если не соответствующие функции не запрещены хостером) только инициируется из PHP запуском сторонней утилиты(gzip, rar.exe или ещё что), потому ограничения на объем памяти, занимаемый PHP, никак не влияют на процесс упаковки. По идее, gzip/zip потоковый, потому не будет использовать много памяти. Тут критичнее место на диске.
Конечно, можно сделать все средствами самого php, но это нерационально по нескольким причинам: ограничение на время выполнения и объем занимаемой памяти(о котором ты и спрашивал), плюс расширение PHP должно быть установлено, что возможно не всегда.
PM MAIL   Вверх
dark_religion
Дата 6.6.2009, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 8.9.2006

Репутация: нет
Всего: -3



Можно поподробнее про (gzip, rar.exe или ещё что) 
1. что нужно для того что бы их настрить 
2. и как узнать присутствуют они на хосте или нет?
3. где можно почитать как это использовать?

Пожалуйста ответьте на все три вопроса!
PM MAIL   Вверх
dark_religion
Дата 6.6.2009, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 8.9.2006

Репутация: нет
Всего: -3



так спасибо я разобрался.

есть такая утилита называется tar. с помощью нее можно поместить много файлов в один а потом сжимать если надо. 
просто используешь например команду exec

exec ("tar cvf name.tar folder_name");

и оно все сжимает ресурсами тара единственная проблема если уж слишком большой размер файлов то можно получить тайм лимит для скрипта. Но оно работает гораздо быстрее чем пхп и нет проблем с памятью.
PM MAIL   Вверх
skyboy
Дата 8.6.2009, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Цитата(dark_religion @  6.6.2009,  16:50 Найти цитируемый пост)
если уж слишком большой размер файлов то можно получить тайм лимит для скрипта

воспользуйся планировщиком для собственно запуска сжатия. а в PHP только создавай задачу планировщика.
PM MAIL   Вверх
dark_religion
Дата 8.6.2009, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 198
Регистрация: 8.9.2006

Репутация: нет
Всего: -3



На сервере нет планировщика)
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0522 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.