Autor Zpráva
iru
Profil *
Všechny zdravím a prosím o pomoc. Spravuji stránky ale nejsem jejich původním tvůrcem. Nevyznám se ve skriptu, kde probíhá komprese souborů. Potřebovala bych tam nastavit nulovou kompresi. Potřebuji soubory jenom sbalit do jednoho souboru, ale nezmenšovat jejich velikost. Poradíte mě, kde a co tam mám nastavit?

Tady je třída, která pracuje s kompresí souborů:

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);
$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
fimmos
Profil
Nejsem si 100%ně jistý, ale možná by stačilo oddělat řádek s $zdata = gzcompress($data);
Aesir
Profil
iru:

Takto:
$zdata = gzcompress($data, 0); 


Druhý parametr funkce určuje míru komprese a může nabývat hodnot tuším 0-9.
iru
Profil *
Díky
prochazka.zde.cz
Profil *
mam takovy dotazek: kdyz je tu rec o kompresi: Co musim splnit abych mohl provozovat kompresi souboru na svem Webu? Mam free hosting u www.pes.cz . A dalsi dotazek: kdyz uz budu mejt tu kompresi funkcni, tak mohu sim zapakovanym souborem pracovat jako s nekomprimovanym souborem? To znamena, mohu z neho cist, zapisovat atd. A nebo musim soubor rozpakovat provest patricne upravy a znovu soubor zapakovat?
Aesir
Profil
prochazka.zde.cz:

Potřebujete podporu Zlib - dozvíte se z phpinfo().

mohu sim zapakovanym souborem pracovat
- pozor výše uvedená funkce gzcompress() komprimuje řetězec, nikoliv soubor.
iru
Profil *
Aesir, tak jsem to tak udělala, je to dobré, jenže ty soubory nejdou rozbalit. Má to s tím nějakou souvislost?
iru
Profil *
Předtím totiž šly rozbalit. Tak mě napadlo, jestli k tomu není potřeba ještě něco nastavit.
iru
Profil *
Neexistuje tedy nějaká jiná možnost, aby soubory šly potom normálně přes ftp (totalcommander) stáhnout a rozbalit pro další zpracování? Prosím poraďte, opravdu si s tím nevím vůbec rady.
Aesir
Profil
iru:

Zkuste v té tříde zaměnit tento řádek:
$cdrec .= "\x08\x00"; // compression method 

na tento:
$cdrec .= "\x00\x00"; // compression method 


Bohužel neznám tolik dopodrobna formát .zip, takže nevím které všechny bity v hlavičce bude potřeba změnit se změnou kompresní metody.

PHP má však i jinou možnost, jak komprimovat soubory. V komentářích ke kompresním funkcím je několik dobře použitelných příkladů, například zde.
iru
Profil *
Díky, vyzkouším. A toto:
$zdata = gzcompress($data, 0); 
zůstane tak, jak jste mi to poradil?

PHP má však i jinou možnost, jak komprimovat soubory.

Zkusila bych i něco jiného, ale nevím, jak bych to do toho zamontovala. S kompresí nemám žádné zkušenosti.
Aesir
Profil
iru:

Ano, přesně tak. Jde o to, že změnou na řádku
$zdata = gzcompress($data, 0);

se změmil způsob komprese dat. Třída skládá soubor "ručně", včetně úvodní hlavičky a tuto je potřeba také přenastavit, ale jakým způsobem, to už nevím. Zkusil bych proto změnit právě nastavení kompresní metody v hlavičce, na řádku
$cdrec .= "\x08\x00"; // compression method 
,
tak jak jsem psal výše. Možná to bude stačit, jistý si však nejsem.
iru
Profil *
Ještě jsem si všimla tohoto řádku:
$fr .= "\x08\x00"; // compression method 

měla bych ho taky změnit, nebo ne?
Toto téma je uzamčeno. Odpověď nelze zaslat.

0