public function __construct($handle = null) { parent::__construct(); $this->header = parent::HEADER_EXTENDED_TIMESTAMP; if ($handle != null) { fread($handle, 2); $arr = unpack('vlength/cflags', fread($handle, 3)); $this->length = $arr['length']; $this->flags = $arr['flags'] & 0xff; $consumed = 1; $this->isModTimeSet = ZipUtils::testBit($this->flags, 0); $this->isAcTimeSet = ZipUtils::testBit($this->flags, 1); $this->isCrTimeSet = ZipUtils::testBit($this->flags, 2); if ($this->isModTimeSet && $consumed < $this->length) { $arr = unpack('V', fread($handle, 4)); $this->modTime = $arr[1]; $consumed += 4; } if ($this->isAcTimeSet && $consumed < $this->length) { $arr = unpack('V', fread($handle, 4)); $this->acTime = $arr[1]; $consumed += 4; } if ($this->isCrTimeSet && $consumed < $this->length) { $arr = unpack('V', fread($handle, 4)); $this->crTime = $arr[1]; } } }
public function parseHeader($handle) { $pk = fread($handle, 4); if ($pk == AbstractZipHeader::ZIP_LOCAL_FILE_HEADER) { /* * local file header signature 4 bytes (0x04034b50) * version needed to extract 2 bytes * general purpose bit flag 2 bytes * compression method 2 bytes * last mod file time + file date 4 bytes * crc-32 4 bytes * compressed size 4 bytes * uncompressed size 4 bytes * file name length 2 bytes * extra field length 2 bytes * --------------------------------------- * 30 bytes */ $this->offset = (int) ftell($handle) - 4; $this->versionNeeded = fread($handle, 2); $arr = unpack("v2wa", fread($handle, 4)); $this->gpFlags = $arr['wa1']; $this->gzType = $arr['wa2']; $this->dosTime = fread($handle, 4); $arr = unpack("V3dwa/v2wa", fread($handle, 16)); $this->fileCRC32 = $arr['dwa1']; $this->gzLength = $arr['dwa2']; $this->dataLength = $arr['dwa3']; $filePathLength = $arr['wa1']; $localExtraFieldLength = $arr['wa2']; $this->path = fread($handle, $filePathLength); $this->dataOffset = 30 + $filePathLength + $localExtraFieldLength; if ($localExtraFieldLength > 0) { $eoef = ftell($handle) + $localExtraFieldLength; while (ftell($handle) < $eoef) { $ef = AbstractExtraField::decodeField($handle); /* @var $ef AbstractExtraField */ $this->extraFieldsArray[$ef->header] = $ef; } } $hasDataDescriptor = $this->gpFlags & 4 == 4; if ($hasDataDescriptor) { $pkHeader = AbstractZipHeader::seekPKHeader($handle); if ($pkHeader !== self::ZIP_LOCAL_DATA_DESCRIPTOR) { fseek($handle, -12, SEEK_CUR); } $arr = unpack("Vdwa", fread($handle, 12)); $this->fileCRC32 = $arr['dwa1']; $this->gzLength = $arr['dwa2']; $this->dataLength = $arr['dwa3']; } else { fseek($handle, $this->gzLength, SEEK_CUR); } $this->isDirectory = !$hasDataDescriptor && $this->dataLength == 0 && $this->fileCRC32 == 0; } else { if ($pk == AbstractZipHeader::ZIP_CENTRAL_FILE_HEADER) { /* * * central file header signature 4 bytes (0x02014b50) * version made by 2 bytes * version needed to extract 2 bytes * general purpose bit flag 2 bytes * compression method 2 bytes * last mod file time 2 bytes * last mod file date 2 bytes * crc-32 4 bytes * compressed size 4 bytes * uncompressed size 4 bytes * file name length 2 bytes * extra field length 2 bytes * file comment length 2 bytes * disk number start 2 bytes * internal file attributes 2 bytes * external file attributes 4 bytes * relative offset of local header 4 bytes * ---------------------------------------- * 46 bytes * * file name (variable size) * extra field (variable size) * file comment (variable size) */ // $this->offset = (int)ftell($handle) - 4; $this->versionMadeBy = fread($handle, 2); $this->versionNeeded = fread($handle, 2); $arr = unpack("v2wa", fread($handle, 4)); $this->gpFlags = $arr['wa1']; $this->gzType = $arr['wa2']; $this->dosTime = fread($handle, 4); $arr = unpack("V3dwa/v3wa", fread($handle, 18)); // $this->fileCRC32 = $arr['dwa1']; // $this->gzLength = $arr['dwa2']; // $this->dataLength = $arr['dwa3']; $filePathLength = $arr['wa1']; $centralExtraFieldLength = $arr['wa2']; $fileCommentLength = $arr['wa3']; $this->discNumberStart = fread($handle, 2); $this->internalFileAttributes = fread($handle, 2); $this->externalFileAttributes = fread($handle, 4); // $arr = unpack("V", fread($handle, 4)); // $this->relativeOffsetOfLocalHeader = $arr[1]; // $this->path = fread($handle, $filePathLength); fseek($handle, 4 + $filePathLength, SEEK_CUR); if ($centralExtraFieldLength > 0) { $eoef = ftell($handle) + $centralExtraFieldLength; while (ftell($handle) < $eoef) { $ef = AbstractExtraField::decodeField($handle, false); /* @var $ef AbstractExtraField */ $ef2 = $this->extraFieldsArray[$ef->header]; if (isset($ef2)) { $ef2->centralData = $ef->centralData; } else { $this->extraFieldsArray[$ef->header] = $ef; } } } if ($fileCommentLength > 0) { $this->comment = fread($handle, $fileCommentLength); } } else { fseek($handle, -4, SEEK_CUR); } } }