updated archive library via composer
This commit is contained in:
parent
0f7eafd90c
commit
2b6c681901
|
@ -54,16 +54,16 @@
|
|||
},
|
||||
{
|
||||
"name": "splitbrain/php-archive",
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/splitbrain/php-archive.git",
|
||||
"reference": "a0fbfc2f85ed491f3d2af42cff48a9cb783a8549"
|
||||
"reference": "89b4cba038e8cf01af3a8180572f19b8e4afaa31"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-archive/zipball/a0fbfc2f85ed491f3d2af42cff48a9cb783a8549",
|
||||
"reference": "a0fbfc2f85ed491f3d2af42cff48a9cb783a8549",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-archive/zipball/89b4cba038e8cf01af3a8180572f19b8e4afaa31",
|
||||
"reference": "89b4cba038e8cf01af3a8180572f19b8e4afaa31",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -97,7 +97,7 @@
|
|||
"unzip",
|
||||
"zip"
|
||||
],
|
||||
"time": "2015-02-25 20:15:02"
|
||||
"time": "2015-06-30 19:12:21"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
|
|
@ -1,53 +1,4 @@
|
|||
[
|
||||
{
|
||||
"name": "splitbrain/php-archive",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/splitbrain/php-archive.git",
|
||||
"reference": "a0fbfc2f85ed491f3d2af42cff48a9cb783a8549"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-archive/zipball/a0fbfc2f85ed491f3d2af42cff48a9cb783a8549",
|
||||
"reference": "a0fbfc2f85ed491f3d2af42cff48a9cb783a8549",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.5.*"
|
||||
},
|
||||
"time": "2015-02-25 20:15:02",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"splitbrain\\PHPArchive\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Andreas Gohr",
|
||||
"email": "andi@splitbrain.org"
|
||||
}
|
||||
],
|
||||
"description": "Pure-PHP implementation to read and write TAR and ZIP archives",
|
||||
"keywords": [
|
||||
"archive",
|
||||
"extract",
|
||||
"tar",
|
||||
"unpack",
|
||||
"unzip",
|
||||
"zip"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "easybook/geshi",
|
||||
"version": "v1.0.8.15",
|
||||
|
@ -95,5 +46,54 @@
|
|||
"highlighter",
|
||||
"syntax"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "splitbrain/php-archive",
|
||||
"version": "1.0.2",
|
||||
"version_normalized": "1.0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/splitbrain/php-archive.git",
|
||||
"reference": "89b4cba038e8cf01af3a8180572f19b8e4afaa31"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/splitbrain/php-archive/zipball/89b4cba038e8cf01af3a8180572f19b8e4afaa31",
|
||||
"reference": "89b4cba038e8cf01af3a8180572f19b8e4afaa31",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.5.*"
|
||||
},
|
||||
"time": "2015-06-30 19:12:21",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"splitbrain\\PHPArchive\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Andreas Gohr",
|
||||
"email": "andi@splitbrain.org"
|
||||
}
|
||||
],
|
||||
"description": "Pure-PHP implementation to read and write TAR and ZIP archives",
|
||||
"keywords": [
|
||||
"archive",
|
||||
"extract",
|
||||
"tar",
|
||||
"unpack",
|
||||
"unzip",
|
||||
"zip"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -18,24 +18,29 @@ Use composer:
|
|||
Usage
|
||||
-----
|
||||
|
||||
The usage for the Zip and Tar classes are basically the same. Here are some examples for working with TARs to get
|
||||
you started. Check the source code comments for more info
|
||||
The usage for the Zip and Tar classes are basically the same. Here are some
|
||||
examples for working with TARs to get you started. Check the source code
|
||||
comments for more info
|
||||
|
||||
```php
|
||||
require_once 'vendor/autoload.php';
|
||||
use splitbrain\PHPArchive\Tar;
|
||||
|
||||
// To list the contents of an existing TAR archive, open() it and use contents() on it:
|
||||
// To list the contents of an existing TAR archive, open() it and use
|
||||
// contents() on it:
|
||||
$tar = new Tar();
|
||||
$tar->open('myfile.tgz');
|
||||
$toc = $tar->contents();
|
||||
print_r($toc); // array of FileInfo objects
|
||||
|
||||
// To extract the contents of an existing TAR archive, open() it and use extract() on it:
|
||||
// To extract the contents of an existing TAR archive, open() it and use
|
||||
// extract() on it:
|
||||
$tar = new Tar();
|
||||
$tar->open('myfile.tgz');
|
||||
$tar->extract('/tmp');
|
||||
|
||||
// To create a new TAR archive directly on the filesystem (low memory requirements), create() it,
|
||||
// To create a new TAR archive directly on the filesystem (low memory
|
||||
// requirements), create() it:
|
||||
$tar = new Tar();
|
||||
$tar->create('myfile.tgz');
|
||||
$tar->addFile(...);
|
||||
|
@ -43,8 +48,8 @@ $tar->addData(...);
|
|||
...
|
||||
$tar->close();
|
||||
|
||||
// To create a TAR archive directly in memory, create() it, add*() files and then either save()
|
||||
// or getData() it:
|
||||
// To create a TAR archive directly in memory, create() it, add*()
|
||||
// files and then either save() or getArchive() it:
|
||||
$tar = new Tar();
|
||||
$tar->create();
|
||||
$tar->addFile(...);
|
||||
|
@ -54,8 +59,8 @@ $tar->save('myfile.tgz'); // compresses and saves it
|
|||
echo $tar->getArchive(Archive::COMPRESS_GZIP); // compresses and returns it
|
||||
```
|
||||
|
||||
Differences between Tar and Zip: Tars are compressed as a whole while Zips compress each file individually. Therefore
|
||||
you can call ```setCompression``` before each ```addFile()``` and ```addData()``` functions.
|
||||
Differences between Tar and Zip: Tars are compressed as a whole, while Zips compress each file individually. Therefore
|
||||
you can call ```setCompression``` before each ```addFile()``` and ```addData()``` function call.
|
||||
|
||||
The FileInfo class can be used to specify additional info like ownership or permissions when adding a file to
|
||||
an archive.
|
|
@ -7,6 +7,8 @@ namespace splitbrain\PHPArchive;
|
|||
*
|
||||
* Creates or extracts Zip archives
|
||||
*
|
||||
* for specs see http://www.pkware.com/appnote
|
||||
*
|
||||
* @author Andreas Gohr <andi@splitbrain.org>
|
||||
* @package splitbrain\PHPArchive
|
||||
* @license MIT
|
||||
|
@ -308,45 +310,45 @@ class Zip extends Archive
|
|||
throw new ArchiveIOException('Archive has been closed, files can no longer be added');
|
||||
}
|
||||
|
||||
// prepare the various header infos
|
||||
$dtime = dechex($this->makeDosTime($fileinfo->getMtime()));
|
||||
$hexdtime = pack(
|
||||
'H*',
|
||||
$dtime[6].$dtime[7].
|
||||
$dtime[4].$dtime[5].
|
||||
$dtime[2].$dtime[3].
|
||||
$dtime[0].$dtime[1]
|
||||
);
|
||||
// prepare info and compress data
|
||||
$size = strlen($data);
|
||||
$crc = crc32($data);
|
||||
if ($this->complevel) {
|
||||
$fmagic = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00";
|
||||
$cmagic = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00";
|
||||
$data = gzcompress($data, $this->complevel);
|
||||
$data = substr($data, 2, -4); // strip compression headers
|
||||
} else {
|
||||
$fmagic = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00";
|
||||
$cmagic = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00";
|
||||
$data = gzcompress($data, $this->complevel);
|
||||
$data = substr($data, 2, -4); // strip compression headers
|
||||
}
|
||||
$csize = strlen($data);
|
||||
$offset = $this->dataOffset();
|
||||
$name = $fileinfo->getPath();
|
||||
$time = $fileinfo->getMtime();
|
||||
|
||||
// write local file header
|
||||
$this->writebytes($this->makeLocalFileHeader(
|
||||
$time,
|
||||
$crc,
|
||||
$size,
|
||||
$csize,
|
||||
$name,
|
||||
(bool) $this->complevel
|
||||
));
|
||||
|
||||
// we store no encryption header
|
||||
|
||||
// write data
|
||||
$this->writebytes($fmagic);
|
||||
$this->writebytes($hexdtime);
|
||||
$this->writebytes(pack('V', $crc).pack('V', $csize).pack('V', $size)); //pre header
|
||||
$this->writebytes(pack('v', strlen($name)).pack('v', 0).$name.$data); //file data
|
||||
$this->writebytes(pack('V', $crc).pack('V', $csize).pack('V', $size)); //post header
|
||||
$this->writebytes($data);
|
||||
|
||||
// we store no data descriptor
|
||||
|
||||
// add info to central file directory
|
||||
$cdrec = $cmagic;
|
||||
$cdrec .= $hexdtime.pack('V', $crc).pack('V', $csize).pack('V', $size);
|
||||
$cdrec .= pack('v', strlen($name)).pack('v', 0).pack('v', 0);
|
||||
$cdrec .= pack('v', 0).pack('v', 0).pack('V', 32);
|
||||
$cdrec .= pack('V', $offset);
|
||||
$cdrec .= $name;
|
||||
$this->ctrl_dir[] = $cdrec;
|
||||
$this->ctrl_dir[] = $this->makeCentralFileRecord(
|
||||
$offset,
|
||||
$time,
|
||||
$crc,
|
||||
$size,
|
||||
$csize,
|
||||
$name,
|
||||
(bool) $this->complevel
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -361,14 +363,24 @@ class Zip extends Archive
|
|||
return;
|
||||
} // we did this already
|
||||
|
||||
// write footer
|
||||
if ($this->writeaccess) {
|
||||
$offset = $this->dataOffset();
|
||||
// write central directory
|
||||
$offset = $this->dataOffset();
|
||||
$ctrldir = join('', $this->ctrl_dir);
|
||||
$this->writebytes($ctrldir);
|
||||
$this->writebytes("\x50\x4b\x05\x06\x00\x00\x00\x00"); // EOF CTRL DIR
|
||||
$this->writebytes(pack('v', count($this->ctrl_dir)).pack('v', count($this->ctrl_dir)));
|
||||
$this->writebytes(pack('V', strlen($ctrldir)).pack('V', strlen($offset))."\x00\x00");
|
||||
|
||||
// write end of central directory record
|
||||
$this->writebytes("\x50\x4b\x05\x06"); // end of central dir signature
|
||||
$this->writebytes(pack('v', 0)); // number of this disk
|
||||
$this->writebytes(pack('v', 0)); // number of the disk with the start of the central directory
|
||||
$this->writebytes(pack('v',
|
||||
count($this->ctrl_dir))); // total number of entries in the central directory on this disk
|
||||
$this->writebytes(pack('v', count($this->ctrl_dir))); // total number of entries in the central directory
|
||||
$this->writebytes(pack('V', strlen($ctrldir))); // size of the central directory
|
||||
$this->writebytes(pack('V',
|
||||
$offset)); // offset of start of central directory with respect to the starting disk number
|
||||
$this->writebytes(pack('v', 0)); // .ZIP file comment length
|
||||
|
||||
$this->ctrl_dir = array();
|
||||
}
|
||||
|
||||
|
@ -492,18 +504,7 @@ class Zip extends Archive
|
|||
$header['comment'] = '';
|
||||
}
|
||||
|
||||
if ($header['mdate'] && $header['mtime']) {
|
||||
$hour = ($header['mtime'] & 0xF800) >> 11;
|
||||
$minute = ($header['mtime'] & 0x07E0) >> 5;
|
||||
$seconde = ($header['mtime'] & 0x001F) * 2;
|
||||
$year = (($header['mdate'] & 0xFE00) >> 9) + 1980;
|
||||
$month = ($header['mdate'] & 0x01E0) >> 5;
|
||||
$day = $header['mdate'] & 0x001F;
|
||||
$header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
|
||||
} else {
|
||||
$header['mtime'] = time();
|
||||
}
|
||||
|
||||
$header['mtime'] = $this->makeUnixTime($header['mdate'], $header['mtime']);
|
||||
$header['stored_filename'] = $header['filename'];
|
||||
$header['status'] = 'ok';
|
||||
if (substr($header['filename'], -1) == '/') {
|
||||
|
@ -518,12 +519,12 @@ class Zip extends Archive
|
|||
* Reads the local file header
|
||||
*
|
||||
* This header precedes each individual file inside the zip file. Assumes the current file pointer is pointing at
|
||||
* the right position already. Enhances this given central header with the data found at the local header.
|
||||
* the right position already. Enhances the given central header with the data found at the local header.
|
||||
*
|
||||
* @param array $header the central file header read previously (see above)
|
||||
* @return array
|
||||
*/
|
||||
function readFileHeader($header)
|
||||
protected function readFileHeader($header)
|
||||
{
|
||||
$binary_data = fread($this->fh, 30);
|
||||
$data = unpack(
|
||||
|
@ -549,20 +550,7 @@ class Zip extends Archive
|
|||
}
|
||||
}
|
||||
$header['flag'] = $data['flag'];
|
||||
$header['mdate'] = $data['mdate'];
|
||||
$header['mtime'] = $data['mtime'];
|
||||
|
||||
if ($header['mdate'] && $header['mtime']) {
|
||||
$hour = ($header['mtime'] & 0xF800) >> 11;
|
||||
$minute = ($header['mtime'] & 0x07E0) >> 5;
|
||||
$seconde = ($header['mtime'] & 0x001F) * 2;
|
||||
$year = (($header['mdate'] & 0xFE00) >> 9) + 1980;
|
||||
$month = ($header['mdate'] & 0x01E0) >> 5;
|
||||
$day = $header['mdate'] & 0x001F;
|
||||
$header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
|
||||
} else {
|
||||
$header['mtime'] = time();
|
||||
}
|
||||
$header['mtime'] = $this->makeUnixTime($data['mdate'], $data['mtime']);
|
||||
|
||||
$header['stored_filename'] = $header['filename'];
|
||||
$header['status'] = "ok";
|
||||
|
@ -651,4 +639,111 @@ class Zip extends Archive
|
|||
($timearray['seconds'] >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UNIX timestamp from a DOS timestamp
|
||||
*
|
||||
* @param $mdate
|
||||
* @param $mtime
|
||||
* @return int
|
||||
*/
|
||||
protected function makeUnixTime($mdate = null, $mtime = null)
|
||||
{
|
||||
if ($mdate && $mtime) {
|
||||
$year = (($mdate & 0xFE00) >> 9) + 1980;
|
||||
$month = ($mdate & 0x01E0) >> 5;
|
||||
$day = $mdate & 0x001F;
|
||||
|
||||
$hour = ($mtime & 0xF800) >> 11;
|
||||
$minute = ($mtime & 0x07E0) >> 5;
|
||||
$seconde = ($mtime & 0x001F) << 1;
|
||||
|
||||
$mtime = mktime($hour, $minute, $seconde, $month, $day, $year);
|
||||
} else {
|
||||
$mtime = time();
|
||||
}
|
||||
|
||||
return $mtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a local file header for the given data
|
||||
*
|
||||
* @param int $offset location of the local header
|
||||
* @param int $ts unix timestamp
|
||||
* @param int $crc CRC32 checksum of the uncompressed data
|
||||
* @param int $len length of the uncompressed data
|
||||
* @param int $clen length of the compressed data
|
||||
* @param string $name file name
|
||||
* @param boolean|null $comp if compression is used, if null it's determined from $len != $clen
|
||||
* @return string
|
||||
*/
|
||||
protected function makeCentralFileRecord($offset, $ts, $crc, $len, $clen, $name, $comp = null)
|
||||
{
|
||||
if(is_null($comp)) $comp = $len != $clen;
|
||||
$comp = $comp ? 8 : 0;
|
||||
$dtime = dechex($this->makeDosTime($ts));
|
||||
|
||||
$header = "\x50\x4b\x01\x02"; // central file header signature
|
||||
$header .= pack('v', 14); // version made by - VFAT
|
||||
$header .= pack('v', 20); // version needed to extract - 2.0
|
||||
$header .= pack('v', 0); // general purpose flag - no flags set
|
||||
$header .= pack('v', $comp); // compression method - deflate|none
|
||||
$header .= pack(
|
||||
'H*',
|
||||
$dtime[6] . $dtime[7] .
|
||||
$dtime[4] . $dtime[5] .
|
||||
$dtime[2] . $dtime[3] .
|
||||
$dtime[0] . $dtime[1]
|
||||
); // last mod file time and date
|
||||
$header .= pack('V', $crc); // crc-32
|
||||
$header .= pack('V', $clen); // compressed size
|
||||
$header .= pack('V', $len); // uncompressed size
|
||||
$header .= pack('v', strlen($name)); // file name length
|
||||
$header .= pack('v', 0); // extra field length
|
||||
$header .= pack('v', 0); // file comment length
|
||||
$header .= pack('v', 0); // disk number start
|
||||
$header .= pack('v', 0); // internal file attributes
|
||||
$header .= pack('V', 0); // external file attributes @todo was 0x32!?
|
||||
$header .= pack('V', $offset); // relative offset of local header
|
||||
$header .= $name; // file name
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a local file header for the given data
|
||||
*
|
||||
* @param int $ts unix timestamp
|
||||
* @param int $crc CRC32 checksum of the uncompressed data
|
||||
* @param int $len length of the uncompressed data
|
||||
* @param int $clen length of the compressed data
|
||||
* @param string $name file name
|
||||
* @param boolean|null $comp if compression is used, if null it's determined from $len != $clen
|
||||
* @return string
|
||||
*/
|
||||
protected function makeLocalFileHeader($ts, $crc, $len, $clen, $name, $comp = null)
|
||||
{
|
||||
if(is_null($comp)) $comp = $len != $clen;
|
||||
$comp = $comp ? 8 : 0;
|
||||
$dtime = dechex($this->makeDosTime($ts));
|
||||
|
||||
$header = "\x50\x4b\x03\x04"; // local file header signature
|
||||
$header .= pack('v', 20); // version needed to extract - 2.0
|
||||
$header .= pack('v', 0); // general purpose flag - no flags set
|
||||
$header .= pack('v', $comp); // compression method - deflate|none
|
||||
$header .= pack(
|
||||
'H*',
|
||||
$dtime[6] . $dtime[7] .
|
||||
$dtime[4] . $dtime[5] .
|
||||
$dtime[2] . $dtime[3] .
|
||||
$dtime[0] . $dtime[1]
|
||||
); // last mod file time and date
|
||||
$header .= pack('V', $crc); // crc-32
|
||||
$header .= pack('V', $clen); // compressed size
|
||||
$header .= pack('V', $len); // uncompressed size
|
||||
$header .= pack('v', strlen($name)); // file name length
|
||||
$header .= pack('v', 0); // extra field length
|
||||
$header .= $name;
|
||||
return $header;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue