PHP и работа с архивами.

12
Loko
На сайте с 28.01.2007
Offline
101
932

Вот, например, есть файлы и папки, имена их занесены в массив. Нужно все эти файлы и папки упаковать в zip-архив с наименьшими энергетическими затратами.

Как примерно это будет выглядеть? буду рад всему - ссылкам, алгоритмам, готовым решениям. Заранее спасибо.

wdsg
На сайте с 09.02.2009
Offline
31
#1
Проектирование и разработка сложных IT-систем. Вожусь с проблемными задачами.
T.R.O.N
На сайте с 18.05.2004
Offline
314
#2
Loko:
Нужно все эти файлы и папки упаковать в zip-архив с наименьшими энергетическими затратами.

почему PHP (не понятно из текста)

Есть доступ к крону или башу? Может просто пустить обычны архиватор?

Упаковыварь архивы по Web сервером можно (http://php.russofile.ru/ru/authors/unsort/zip/) типа этого, но это, ИМХО, кощунство, ибо никогда непонятно сколько сие займет времени, и сервак может просто оборвать задачу по таймауту

От воздержания пока никто не умер. Хотя никто и не родился! Prototype.js был написан теми, кто не знает JavaScript, для тех, кто не знает JavaScript (Richard Cornford)
A
На сайте с 11.05.2009
Offline
99
#3

Можно попробовать как здесь: Создание zip на php

P.S. нет такой страны Белоруссия, есть Беларусь

Loko
На сайте с 28.01.2007
Offline
101
#4
T.R.O.N:
Есть доступ к крону или башу? Может просто пустить обычны архиватор?

Извините за ламерство, а где и как это узнать и как потом с этим работать? :)

T.R.O.N:
Упаковыварь архивы по Web сервером можно (http://php.russofile.ru/ru/authors/unsort/zip/) типа этого

Да с этим разбирался. Тоже не очень нравится. :)

aravak:
Можно попробовать как здесь: Создание zip на php

Спасибо, буду разбираться.

aravak:
P.S. нет такой страны Белоруссия, есть Беларусь

Возможно, но слово-то есть. И его многие употребляют неверно, что раздражает.

Dreammaker
На сайте с 20.04.2006
Offline
569
#5

Loko, вот класс из CodeIgniter'а. Как пользоваться http://codeigniter.com/user_guide/libraries/zip.html (только внесите изменения согласно тому что не внутри фреймворка будет использоваться).


<?php
/**

* CodeIgniter

*

* An open source application development framework for PHP 4.3.2 or newer

*

* @package CodeIgniter

* @author ExpressionEngine Dev Team

* @copyright Copyright (c) 2008, EllisLab, Inc.

* @license http://codeigniter.com/user_guide/license.html

* @link http://codeigniter.com

* @since Version 1.0

* @filesource

*/



// ------------------------------------------------------------------------



/**

* Zip Compression Class

*

* This class is based on a library I found at Zend:

* http://www.zend.com/codex.php?id=696&single=1

*

* The original library is a little rough around the edges so I

* refactored it and added several additional methods -- Rick Ellis

*

* @package CodeIgniter

* @subpackage Libraries

* @category Encryption

* @author ExpressionEngine Dev Team

* @link http://codeigniter.com/user_guide/libraries/zip.html

*/

class CI_Zip {



var $zipdata = '';

var $directory = '';

var $entries = 0;

var $file_num = 0;

var $offset = 0;



function CI_Zip()

{

log_message('debug', "Zip Compression Class Initialized");

}



// --------------------------------------------------------------------



/**

* Add Directory

*

* Lets you add a virtual directory into which you can place files.

*

* @access public

* @param mixed the directory name. Can be string or array

* @return void

*/

function add_dir($directory)

{

foreach ((array)$directory as $dir)

{

if ( ! preg_match("|.+/$|", $dir))

{

$dir .= '/';

}



$this->_add_dir($dir);

}

}



// --------------------------------------------------------------------



/**

* Add Directory

*

* @access private

* @param string the directory name

* @return void

*/

function _add_dir($dir)

{

$dir = str_replace("\\", "/", $dir);



$this->zipdata .=

"\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"

.pack('V', 0) // crc32

.pack('V', 0) // compressed filesize

.pack('V', 0) // uncompressed filesize

.pack('v', strlen($dir)) // length of pathname

.pack('v', 0) // extra field length

.$dir

// below is "data descriptor" segment

.pack('V', 0) // crc32

.pack('V', 0) // compressed filesize

.pack('V', 0); // uncompressed filesize



$this->directory .=

"\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00"

.pack('V',0) // crc32

.pack('V',0) // compressed filesize

.pack('V',0) // uncompressed filesize

.pack('v', strlen($dir)) // length of pathname

.pack('v', 0) // extra field length

.pack('v', 0) // file comment length

.pack('v', 0) // disk number start

.pack('v', 0) // internal file attributes

.pack('V', 16) // external file attributes - 'directory' bit set

.pack('V', $this->offset) // relative offset of local header

.$dir;



$this->offset = strlen($this->zipdata);

$this->entries++;

}



// --------------------------------------------------------------------



/**

* Add Data to Zip

*

* Lets you add files to the archive. If the path is included

* in the filename it will be placed within a directory. Make

* sure you use add_dir() first to create the folder.

*

* @access public

* @param mixed

* @param string

* @return void

*/

function add_data($filepath, $data = NULL)

{

if (is_array($filepath))

{

foreach ($filepath as $path => $data)

{

$this->_add_data($path, $data);

}

}

else

{

$this->_add_data($filepath, $data);

}

}



// --------------------------------------------------------------------



/**

* Add Data to Zip

*

* @access private

* @param string the file name/path

* @param string the data to be encoded

* @return void

*/

function _add_data($filepath, $data)

{

$filepath = str_replace("\\", "/", $filepath);



$uncompressed_size = strlen($data);

$crc32 = crc32($data);



$gzdata = gzcompress($data);

$gzdata = substr($gzdata, 2, -4);

$compressed_size = strlen($gzdata);



$this->zipdata .=

"\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"

.pack('V', $crc32)

.pack('V', $compressed_size)

.pack('V', $uncompressed_size)

.pack('v', strlen($filepath)) // length of filename

.pack('v', 0) // extra field length

.$filepath

.$gzdata; // "file data" segment



$this->directory .=

"\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00"

.pack('V', $crc32)

.pack('V', $compressed_size)

.pack('V', $uncompressed_size)

.pack('v', strlen($filepath)) // length of filename

.pack('v', 0) // extra field length

.pack('v', 0) // file comment length

.pack('v', 0) // disk number start

.pack('v', 0) // internal file attributes

.pack('V', 32) // external file attributes - 'archive' bit set

.pack('V', $this->offset) // relative offset of local header

.$filepath;



$this->offset = strlen($this->zipdata);

$this->entries++;

$this->file_num++;

}



// --------------------------------------------------------------------



/**

* Read the contents of a file and add it to the zip

*

* @access public

* @return bool

*/

function read_file($path, $preserve_filepath = FALSE)

{

if ( ! file_exists($path))

{

return FALSE;

}



if (FALSE !== ($data = file_get_contents($path)))

{

$name = str_replace("\\", "/", $path);



if ($preserve_filepath === FALSE)

{

$name = preg_replace("|.*/(.+)|", "\\1", $name);

}



$this->add_data($name, $data);

return TRUE;

}

return FALSE;

}



// ------------------------------------------------------------------------



/**

* Read a directory and add it to the zip.

*

* This function recursively reads a folder and everything it contains (including

* sub-folders) and creates a zip based on it. Whatever directory structure

* is in the original file path will be recreated in the zip file.

*

* @access public

* @param string path to source

* @return bool

*/

function read_dir($path)

{

if ($fp = @opendir($path))

{

while (FALSE !== ($file = readdir($fp)))

{

if (@is_dir($path.$file) && substr($file, 0, 1) != '.')

{

$this->read_dir($path.$file."/");

}

elseif (substr($file, 0, 1) != ".")

{

if (FALSE !== ($data = file_get_contents($path.$file)))

{

$this->add_data(str_replace("\\", "/", $path).$file, $data);

}

}

}

return TRUE;

}

}



// --------------------------------------------------------------------



/**

* Get the Zip file

*

* @access public

* @return binary string

*/

function get_zip()

{

// Is there any data to return?

if ($this->entries == 0)

{

return FALSE;

}



$zip_data = $this->zipdata;

$zip_data .= $this->directory."\x50\x4b\x05\x06\x00\x00\x00\x00";

$zip_data .= pack('v', $this->entries); // total # of entries "on this disk"

$zip_data .= pack('v', $this->entries); // total # of entries overall

$zip_data .= pack('V', strlen($this->directory)); // size of central dir

$zip_data .= pack('V', strlen($this->zipdata)); // offset to start of central dir

$zip_data .= "\x00\x00"; // .zip file comment length



return $zip_data;

}



// --------------------------------------------------------------------



/**

* Write File to the specified directory

*

* Lets you write a file

*

* @access public

* @param string the file name

* @return bool

*/

function archive($filepath)

{

if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE)))

{

return FALSE;

}



flock($fp, LOCK_EX);

fwrite($fp, $this->get_zip());

flock($fp, LOCK_UN);

fclose($fp);



return TRUE;

}



// --------------------------------------------------------------------



/**

* Download

*

* @access public

* @param string the file name

* @param string the data to be encoded

* @return bool

*/

function download($filename = 'backup.zip')

{

if ( ! preg_match("|.+?\.zip$|", $filename))

{

$filename .= '.zip';

}



$zip_content =& $this->get_zip();



$CI =& get_instance();

$CI->load->helper('download');



force_download($filename, $zip_content);

}



// --------------------------------------------------------------------



/**

* Initialize Data

*

* Lets you clear current zip data. Useful if you need to create

* multiple zips with different data.

*

* @access public

* @return void

*/

function clear_data()

{

$this->zipdata = '';

$this->directory = '';

$this->entries = 0;

$this->file_num = 0;

$this->offset = 0;

}



}



/* End of file Zip.php */

/* Location: ./system/libraries/Zip.php */

p.s. Удалил первую строчку из класса, чтобы не материлось, что не внутри фреймворка не работает.

Dreammaker
На сайте с 20.04.2006
Offline
569
#7
FOXI.BY:
готовый скрипт архивирования файлов на php

помню, что мне чем-то PclZip не понравился, вот только чем - не помню :)

[Удален]
#8
Dreammaker:
помню, что мне чем-то PclZip не понравился, вот только чем - не помню :)

Да вроде работает нормально :)

Loko
На сайте с 28.01.2007
Offline
101
#9

Освоил PclZip. Хочется узнать, сильно-ли я потеряю в производительности, если буду использовать его? :). Задача - периодически собирать в архив ~100 небольших файлов.

A
На сайте с 11.05.2009
Offline
99
#10

а файлы по размеру примерно какие?? если небольшие, то по сути сильно напрягать не будет

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий