Эта тема на forum.dklab.ru


ylativ: Скрипт динамической генерации архивов
Есть ли готовы скрипты динамической генерации zip/gzip архивов по запросу? То есть кучка файлов (скриптов) лежит в закрытом месте на сервер, по команде клиента скрипт собирает все файлы и папки в архив и отправляет в браузер на скачку.

Нет ли готовых (даже на анг. языке), кто-нибудь может знает?
Ksnk:
phpfm такое умеет. Правда его формат понимает только он сам :) Но если им самим и распаковывать - то нет проблем...

можно поискать по слову PHPZIP. Класс, который делает Зипы (не проверял, но пишет, что "как настоящие" :))
dacuan:
Класс, который позволяет создать zip-архив из нескольких файлов.
Взят из phpMyAdmin/
Недостаток: не устанавливается время создания файла в архиве.
/**
* Zip file creation class.
* Makes zip files.
*
* Based on :
*
* http://www.zend.com/codex.php?id=535&single=1
* By Eric Mueller (eric@themepark.com)
*
* http://www.zend.com/codex.php?id=470&single=1
* by Denis125 (webmaster@atlant.ru)
*
* Official ZIP file format: http://www.pkware.com/appnote.txt
*
* @access public
*/
class zipfile
{
/**
* Array to store compressed data
*
* @var array $datasec
*/
var $datasec = array();

/**
* Central directory
*
* @var array $ctrl_dir
*/
var $ctrl_dir = array();

/**
* End of central directory record
*
* @var string $eof_ctrl_dir
*/
var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";

/**
* Last offset position
*
* @var integer $old_offset
*/
var $old_offset = 0;


/**
* Adds "file" to archive
*
* @param string file contents
* @param string name of the file in the archive (may contains the path)
*
* @access public
*/
function addFile($data, $name)
{
$name = str_replace('\\', '/', $name);

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

// "local file header" segment
$unc_len = strlen($data);
$crc = crc32($data);
$zdata = gzcompress($data,9);
$zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // 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;

// "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"; // gen 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;
} // end of the 'addFile()' method


/**
* Dumps out file
*
* @return string the zipped file
*
* @access public
*/
function file()
{
$data = implode('', $this -> datasec);
$ctrldir = implode('', $this -> ctrl_dir);

return
$data .
$ctrldir .
$this -> eof_ctrl_dir .
pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk"
pack('v', sizeof($this -> ctrl_dir)) . // total # 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
} // end of the 'file()' method

} // end of the 'zipfile' class
Хотя, если скрипт должен собирать ВСЕ файлы и каталоги, то лучше архив сделать один раз и давать пользователю на него ссылку.
ylativ:
Смысл генерации в том, что в зависимости от юзера он в определенные файлы будет вставлять различную инфу...
pav:
ylativ
Попробуйте чтонибудь из этого. Помню был там класс функциональностью которую вы ищите.
ylativ:
Благодарю, буду искать.
Юрий Насретдинов:
phpfm такое умеет. Правда его формат понимает только он сам :)
Да и сжимает он не очень-то сильно :))). Хотя он использует Gzip, всё равно - он записывает всё в жутко неудобном для сжатия виде. К тому же нет поддержки вложенных директорий :)
Дмитрий Котеров:
Вот тот файл, который на dklab.ru/lib собирает архив исходников (для любой директории, в которой лежит файл .arch, доступен URL имя_директории.zip:

<?php
$marker = ".arch";

$path = dirname(__FILE__) . '/' . $_SERVER['QUERY_STRING'];
if (preg_match('/\.\./s', $path) || !is_dir($path) || !file_exists("$path/$marker")) {
Header("Status: 404 Not Found");
die("File not found: $path");
}

chdir($path);

$ext = "zip";
$arch = "/tmp/".time()."-".getmypid().".$ext";
exec("zip -r $arch . -x $marker");
$data = file_get_contents($arch);
unlink($arch);

Header("Content-Disposition: attachment; filename=".basename(dirname($path)).".$ext");
Header("Content-Length: ".strlen($data));
Header("Content-type: application/zip");
echo $data;
exit();
?>

Подключается через mod_rewrite:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]

RewriteCond %{REQUEST_FILENAME} (.*)\.zip$
RewriteRule .* - [E=dir:%1]

RewriteCond %{ENV:dir}/.arch -f
RewriteRule (.*)\.[^.]+$ /lib/download.php?$1 [L]

Эта тема на forum.dklab.ru