2declare(strict_types=1);
83 const ZIP_VERSION_MADE_BY = 0x603;
90 const FILE_HEADER_SIGNATURE = 0x04034b50;
91 const CDR_FILE_SIGNATURE = 0x02014b50;
92 const CDR_EOF_SIGNATURE = 0x06054b50;
93 const DATA_DESCRIPTOR_SIGNATURE = 0x08074b50;
94 const ZIP64_CDR_EOF_SIGNATURE = 0x06064b50;
95 const ZIP64_CDR_LOCATOR_SIGNATURE = 0x07064b50;
173 $this->opt = $opt ?:
new ArchiveOptions();
175 $this->output_name =
$name;
176 $this->need_headers =
$name && $this->opt->isSendHttpHeaders();
178 $this->cdr_ofs =
new Bigint();
179 $this->ofs =
new Bigint();
216 $file->processData(
$data);
262 $file->processPath(
$path);
357 foreach ($this->files as $cdrFile) {
358 $this->send($cdrFile);
359 $this->cdr_ofs = $this->cdr_ofs->add(
Bigint::init(strlen($cdrFile)));
363 if (count($this->files) >= 0xFFFF ||
364 $this->cdr_ofs->isOver32() ||
365 $this->ofs->isOver32()) {
366 if (!$this->opt->isEnableZip64()) {
370 $this->addCdr64Eof();
371 $this->addCdr64Locator();
388 $num_files = count($this->files);
389 $cdr_length = $this->cdr_ofs;
390 $cdr_offset = $this->ofs;
393 [
'V', static::ZIP64_CDR_EOF_SIGNATURE],
395 [
'v', static::ZIP_VERSION_MADE_BY],
396 [
'v', Version::ZIP64],
405 $ret = static::packFields($fields);
422 foreach ($fields as [
$format, $value]) {
425 if ($value instanceof
Bigint) {
426 $args[] = $value->getLow32();
427 $args[] = $value->getHigh32();
433 if ($value instanceof
Bigint) {
434 $value = $value->getLow32();
442 array_unshift($args, $fmt);
445 return pack(...$args);
455 public function send(
string $str): void
457 if ($this->need_headers) {
458 $this->sendHttpHeaders();
460 $this->need_headers =
false;
462 fwrite($this->opt->getOutputStream(), $str);
464 if ($this->opt->isFlushOutput()) {
466 $status = ob_get_status();
467 if (isset($status[
'flags']) && ($status[
'flags'] & PHP_OUTPUT_HANDLER_FLUSHABLE)) {
484 $disposition = $this->opt->getContentDisposition();
486 if ($this->output_name) {
488 $safe_output = trim(str_replace([
'"',
"'",
'\\',
';',
"\n",
"\r"],
'', $this->output_name));
491 $urlencoded = rawurlencode($safe_output);
492 $disposition .=
"; filename*=UTF-8''{$urlencoded}";
496 'Content-Type' => $this->opt->getContentType(),
497 'Content-Disposition' => $disposition,
498 'Pragma' =>
'public',
499 'Cache-Control' =>
'public, must-revalidate',
500 'Content-Transfer-Encoding' =>
'binary'
503 $call = $this->opt->getHttpHeaderCallback();
504 foreach ($headers as
$key => $val) {
516 $cdr_offset = $this->ofs->add($this->cdr_ofs);
519 [
'V', static::ZIP64_CDR_LOCATOR_SIGNATURE],
525 $ret = static::packFields($fields);
536 $num_files = count($this->files);
537 $cdr_length = $this->cdr_ofs;
538 $cdr_offset = $this->ofs;
541 $comment = $this->opt->getComment();
544 [
'V', static::CDR_EOF_SIGNATURE],
547 [
'v', min($num_files, 0xFFFF)],
548 [
'v', min($num_files, 0xFFFF)],
549 [
'V', $cdr_length->getLowFF()],
550 [
'V', $cdr_offset->getLowFF()],
567 $this->ofs =
new Bigint();
568 $this->cdr_ofs =
new Bigint();
569 $this->opt =
new ArchiveOptions();
580 if (!$this->opt->isStatFiles()) {
584 return $stat[
'size'] > $this->opt->getLargeFileSize();
595 $file->ofs = $this->ofs;
while(count($oldTaskList) > 0) foreach(array_keys( $newTaskList) as $task) init()
An exception for terminatinating execution or to throw for unit testing.
This Exception gets invoked if a counter value exceeds storage size.
getCdrFile()
Send CDR record for specified file.
addToCdr(File $file)
Save file attributes for trailing CDR record.
__construct(?string $name=null, ?ArchiveOptions $opt=null)
Create a new ZipStream object.
clear()
Clear all internal variables.
addFileFromStream(string $name, $stream, ?FileOptions $options=null)
addFileFromStream
send(string $str)
Send string, sending HTTP headers if necessary.
isLargeFile(string $path)
Is this file larger than large_file_size?
addCdr64Locator()
Send ZIP64 CDR Locator (Central Directory Record Locator) record.
addCdr64Eof()
Send ZIP64 CDR EOF (Central Directory Record End-of-File) record.
addFileFromPsr7Stream(string $name, StreamInterface $stream, ?FileOptions $options=null)
addFileFromPsr7Stream
addFileFromPath(string $name, string $path, ?FileOptions $options=null)
addFileFromPath
sendHttpHeaders()
Send HTTP headers for this stream.
addCdrEof()
Send CDR EOF (Central Directory Record End-of-File) record.
addFile(string $name, string $data, ?FileOptions $options=null)
addFile
static packFields(array $fields)
Create a format string and argument list for pack(), then call pack() and return the result.
$stream
PHP stream implementation.