Ne-Lexa / php-zip

PhpZip is a php-library for extended work with ZIP-archives.
MIT License
491 stars 60 forks source link

Write Zip to memory stream #37

Closed p4ddy1 closed 5 years ago

p4ddy1 commented 5 years ago

Description
With the current implementation of ZipFile::saveAsStream it is unfortunately impossible to write the archive to a php://memory or php://temp stream and use it afterwards, because the method closes the stream after writing to it. It would be really nice if there was a method which writes the archive to a stream, but does not close it afterwards. Making the method ZipFile::writeZipToStream public would be sufficient I think.

Example

$zipFile = new ZipFile();
$zipFile->addFromString('test.txt', 'This is a test');
$zipFile->writeZipToStream($outputStream);
Ne-Lexa commented 5 years ago

For your case, you can extend the class, for example:

<?php
use PhpZip\Exception\ZipException;

require __DIR__ . '/vendor/autoload.php';

class MemoryZipFile extends PhpZip\ZipFile
{
    /**
     * Save as memory.
     *
     * @return resource
     * @throws ZipException
     */
    public function saveAsMemory()
    {
        if (!($handle = fopen('php://memory', 'r+b'))) {
            throw new ZipException("Can't open memory stream.");
        }
        $this->writeZipToStream($handle);
        return $handle;
    }
}

$zipFile = new MemoryZipFile();
$zipFile->addFromString('test.txt', 'This is a test');
$memoryResource = $zipFile->saveAsMemory();

rewind($memoryResource);
echo stream_get_contents($memoryResource) . PHP_EOL;

fclose($memoryResource);

or

<?php
use PhpZip\Exception\ZipException;

require __DIR__ . '/vendor/autoload.php';

$zipFile = new class extends \PhpZip\ZipFile
{
    /**
     * Save as memory.
     *
     * @return resource
     * @throws ZipException
     */
    public function saveAsMemory()
    {
        if (!($handle = fopen('php://memory', 'r+b'))) {
            throw new ZipException("Can't open memory stream.");
        }
        $this->writeZipToStream($handle);
        return $handle;
    }
};
$zipFile->addFromString('test.txt', 'This is a test');
$memoryResource = $zipFile->saveAsMemory();

rewind($memoryResource);
echo stream_get_contents($memoryResource) . PHP_EOL;

fclose($memoryResource);
p4ddy1 commented 5 years ago

Thanks for the reply. I went with the second solution.