Code Monkey home page Code Monkey logo

zipstream-php's Introduction

ZipStream-PHP

Main Branch Coverage Status Latest Stable Version Total Downloads Financial Contributors on Open Collective License

Unstable Branch

The main branch is not stable. Please see the releases for a stable version.

Overview

A fast and simple streaming zip file downloader for PHP. Using this library will save you from having to write the Zip to disk. You can directly send it to the user, which is much faster. It can work with S3 buckets or any PSR7 Stream.

Please see the LICENSE file for licensing and warranty information.

Installation

Simply add a dependency on maennchen/zipstream-php to your project's composer.json file if you use Composer to manage the dependencies of your project. Use following command to add the package to your project's dependencies:

composer require maennchen/zipstream-php

Usage

For detailed instructions, please check the Documentation.

// Autoload the dependencies
require 'vendor/autoload.php';

// create a new zipstream object
$zip = new ZipStream\ZipStream(
    outputName: 'example.zip',

    // enable output of HTTP headers
    sendHttpHeaders: true,
);

// create a file named 'hello.txt'
$zip->addFile(
    fileName: 'hello.txt',
    data: 'This is the contents of hello.txt',
);

// add a file named 'some_image.jpg' from a local file 'path/to/image.jpg'
$zip->addFileFromPath(
    fileName: 'some_image.jpg',
    path: 'path/to/image.jpg',
);

// finish the zip stream
$zip->finish();

Upgrade to version 3.0.0

General

  • Minimum PHP Version: 8.1
  • Only 64bit Architecture is supported.
  • The class ZipStream\Option\Method has been replaced with the enum ZipStream\CompressionMethod.
  • Most clases have been flagged as @internal and should not be used from the outside. If you're using internal resources to extend this library, please open an issue so that a clean interface can be added & published. The externally available classes & enums are:
    • ZipStream\CompressionMethod
    • ZipStream\Exception*
    • ZipStream\ZipStream

Archive Options

  • The class ZipStream\Option\Archive has been replaced in favor of named arguments in the ZipStream\ZipStream constuctor.
  • The archive options largeFileSize & largeFileMethod has been removed. If you want different compressionMethods based on the file size, you'll have to implement this yourself.
  • The archive option httpHeaderCallback changed the type from callable to Closure.
  • The archive option zeroHeader has been replaced with the option defaultEnableZeroHeader and can be overridden for every file. Its default value changed from false to true.
  • The archive option statFiles was removed since the library no longer checks filesizes this way.
  • The archive option deflateLevel has been replaced with the option defaultDeflateLevel and can be overridden for every file.
  • The first argument (name) of the ZipStream\ZipStream constuctor has been replaced with the named argument outputName.
  • Headers are now also sent if the outputName is empty. If you do not want to automatically send http headers, set sendHttpHeaders to false.

File Options

  • The class ZipStream\Option\File has been replaced in favor of named arguments in the ZipStream\ZipStream->addFile* functions.
  • The file option method has been renamed to compressionMethod.
  • The file option time has been renamed to lastModificationDateTime.
  • The file option size has been renamed to maxSize.

Upgrade to version 2.0.0

https://github.com/maennchen/ZipStream-PHP/tree/2.0.0#upgrade-to-version-200

Upgrade to version 1.0.0

https://github.com/maennchen/ZipStream-PHP/tree/2.0.0#upgrade-to-version-100

Contributing

ZipStream-PHP is a collaborative project. Please take a look at the .github/CONTRIBUTING.md file.

Version Support

Versions are supported according to the table below.

Please do not open any pull requests contradicting the current version support status.

Careful: Always check the README on main for up-to-date information.

Version New Features Bugfixes Security
3
2
1
0

This library aligns itself with the PHP core support. New features and bugfixes will only target PHP versions according to their current status.

See: https://www.php.net/supported-versions.php

About the Authors

zipstream-php's People

Contributors

andrejpavlovic avatar brokencube avatar dabinat avatar dependabot[bot] avatar donatj avatar evertharmeling avatar felixjacobi avatar firtzberg avatar flindvall avatar jorrit avatar joshlewis avatar kolesar-andras avatar leftdevel avatar maennchen avatar monkeywithacupcake avatar mtak3 avatar nicolascarpi avatar ogyr avatar paolaruby avatar pfofi avatar ph0tonic avatar rlatkn avatar sagara- avatar scrutinizer-auto-fixer avatar snapshotpl avatar stil avatar teliov avatar tomschlick avatar xiao-chong avatar zepich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zipstream-php's Issues

compression option support

hi everyone,

maybe im blind (yes, thats a possibility...)

are the compression options, that usually come with zip, available with zipstream-php?

i.e. zip -r -9 somefile.zip somefile.sql

getCrc32() must be of the type integer, float returned

Description of the problem

I get the following TypeError in the getCrc32 method.
Return value of JDWil\ZipStream\Stream\WriteStream::getCrc32() must be of the type integer, float returned

Example code

$zipStream = \JDWil\ZipStream\ZipStream::forFile('php://output');
$zipStream->addFileFromDisk($saveAs, $file);
$zipStream->close();

$saveAs is just a string with the file name for the zip file (eg. file.pdf) and $file is the absolute path to the file. The PDF file is about 100 kb in size.

Informations

  • ZipStream-PHP version: composer.json says ^0.1.2
  • PHP version: tried with 7.0, 7.1, 7.2

Please include any supplemental information you deem relevant to this issue.

I tested it first with windows (xampp) I thought it was a windows issue, then I moved the code to production (Linux), same error.

I fixed the problem for myself by editing WriteStream.php and removed the :int part in line 126. So it looks now like this:

    public function getCrc32()
    {
        return $this->crc32Params->crc32;
    }

Can you please fix it or tell it what I can / should do?

UTF8 file names and comment

Hi,

Good work to continue this great little zip stream library :).

I started to move Ampache from ARCHIVES CLASSES to this and noticed an issue with utf8 filenames and comments. This is simply not supported.
I'm really not familiar with zip standard, anyway you can add utf8 support if filename/comment are utf8 strings?
Thanks!

How alive is this library?

Hello,

I want to include your library for downloading zip files in my project (elabftw).

I tried the latest stable version. It works. Tried the alpha1 version, it works too. But the alpha has been released in april and we are in august now.

I also see that you do not have that much time to dedicate to this project (see comment).

My questions are: is this project actively maintained? Will you release a stable version 1.0 soon?

Anyway, thanks for this great library, it helps me a lot for tackling timeout issues I have when generating big zip files :)

Cheers,
~Nico

Compressed files have no permissions set

Description of the problem

When compressing files (using addFileFromPath()) with ZipStream-PHP, the files inside the zip archive will lose all UNIX permissions. And after unzipping, directories work fine but files have no permissions set:

Output of unzip -Zv archive.zip with ZipStream:
Unix file attributes (000000 octal): ?---------

Output of unzip -Zv archive.zip with ZipArchive from PHP:
Unix file attributes (100666 octal): -rw-rw-rw-

After unziping, the files have no permissions set:
ls -l:
---------- 1 user wheel 799 Aug 1 12:37 file1.txt

There is no mention of permission in the source code of ZipStream and I'm not sure how one could go about adding this in the library. @maennchen any idea?

Workaround is of course to chmod the files after unzipping, but that is not a conceivable solution for normal users.

Example code

mkdir permbug
cd permbug
composer require maennchen/zipstream-php dev-master
echo "file1 content" > file1.txt

Content of index.php:

<?php

require_once 'vendor/autoload.php';

use ZipStream\ZipStream;
use ZipStream\Option\Archive as ArchiveOption;

$zipPath = 'file.zip';

$opt = new ArchiveOption();
$opt->setContentDisposition = 'attachment';
$opt->setContentType = 'application/x-zip';
$opt->setSendHttpHeaders(true);
$opt->setHttpHeaderCallback('header');
$zip = new ZipStream($zipPath, $opt);
$zip->addFileFromPath('zippedfile', 'file1.txt');
$zip->finish();
php -S locahost:7000
# from another shell
curl http://localhost:7000 -o file.zip
unzip -Zv file.zip|grep octal

It will show ?-------- instead of correct permissions.

Informations

  • ZipStream-PHP version: 1.0.0-alpha
  • PHP version: 7.1.17

edit: adding file.zip

file.zip

$zip->addFile immediatly returns a response

Calling the addFile method immediatly retuns an HTTP response resulting in in invalid ZIP file.

I've executed the code that was provided in the readme:

$zip->addFile('hello.txt', 'This is the contents of hello.txt');

Version used : 0.4.1 and 0.3.1
Apache/2.4.17 (Win32) OpenSSL/1.0.2d
PHP/5.6.21

Resulting Zip can't be extracted in Mac OSX Archive Utility and Windows WinRAR

I'm using Zipstream to create a streamed zip download to browser in a Symfony 2.8 + PHP 7 on Ubuntu web application. Files are streamed from AWS s3 bucket via aws-sdk-php which I used to create an S3Client with valid credentials against which I register the stream wrapper (s3Client->registerStreamWrapper();).

In web interface, user clicks "Download" button which initiates the above and a zip downloads via browser to user's local machine. However, the zip cannot be opened by:

  • Archive Utility (native app) on Mac OSX (El Capitan) with error "Unable to extract 'test.zip'. Error 2 No such file or directory.)
  • WinRAR on Windows with error "Archive is corrupted".

I can open the file via 7-zip on Windows and TheUnarchiver on Mac, but this is not a suitable solution as users can't be expected to guess or know to download a specific third party archive application to make a downloaded zip file usable.

I have seen a previous issue related to this from a few years ago requiring other third party bundles be updated and a related SO post (https://stackoverflow.com/questions/5573211/dynamically-created-zip-files-by-zipstream-in-php-wont-open-in-osx) dealing with the same issue back in 2011. I have updated my bundles and attempted the suggestions in that SO post to fix the issue without success.

Sample Code:

    //$s3Client instantiated with valid credentials and passed to function 
    $this->s3Client = $s3Client;  
    $this->s3Client->registerStreamWrapper();

$opt = array(
            'comment' => 'test zip file.',
            'content_type' => 'application/octet-stream'
          );
    $zip = new ZipStream\ZipStream($filename, $opt);

/*
    simple case with simple test file.
 */

    $keys = array(
          "zipsimpletestfolder/file1.txt"
      );

    foreach ($keys as $key) {
        // Get the file name in S3 key so we can save it to the zip file 
        // using the same name.
        $fileName = basename($key);

        $bucket = 'mg-test';

        $s3path = "s3://" . $bucket . "/" . $key;

        if ($streamRead = fopen($s3path, 'r')) {
          $zip->addFileFromStream($fileName, $streamRead);        
        } else {
          die('Could not open stream for reading');
        }
    }

In ZipStream class I see the following version settings for making and extract:

   ...

   // build file header
		$fields = array( // (from V.A of APPNOTE.TXT)
			array(
				'V',
				0x04034b50
			), // local file header signature
			array(
				'v',				
				0x000A //(6 << 8) + 3)
			), // version needed to extract
			//FIXED as mentioned in http://linlog.skepticats.com/entries/2012/02/Streaming_ZIP_files_in_PHP.php
			//and http://stackoverflow.com/questions/5573211/dynamically-created-zip-files-by-zipstream-in-php-wont-open-in-osx

  ...

Can you please assist with solving this issue?

Allow Setting Storage Method when adding files

When adding files to the zip stream, the user should be able to specify the compression method (0 for NOCOMPRESS or 8 for DEFLATE)

Currently it defaults to DEFLATE but in the internal methods used in the addFile, method there is an option to set the compression method.

I ran into a case where it was necessary to store some small files in an uncompressed state.

Would be happy to send in a pull request

Release V1

I've just released the version v1.0.0-alpha.1.

Please test the library and report any bugs you find.

The Native OSX-Unzipper can not handle the Archives.

I'm struggling to get correct archives that can be unzipped by the native OSX-Unzipper.

I'm reading and testing for some time now, but now I'm wondering if it is even possible for version >1. (I read several of these type of issues.)

  • Can you confirm ->addFileFromStream() does not work for the OSX-Unzipper?
  • If so, would it be wise to use version 0.5?

For a clear reference I'll post the code that I used, and a test.zip file.

test.zip

$options = new ZipStream\Option\Archive();
$options->setZeroHeader(true); 
$options->setContentType( 'application/octet-stream' ); 
$options->setSendHttpHeaders(true);
$options->setHttpHeaderCallback('header');

$zip = new ZipStream\ZipStream( $filename . '.zip', $options );

foreach ( $files as $file ) {

	if ( ! file_exists( $file ) ) {
		continue;
	}

	if ( ! $stream = fopen( $file, 'r' ) ) {
		$zip->addFileFromStream( basename( $file ), $stream );        
	} else {
		die( __( 'Could not open stream for reading', 'photosessions' ) );
	}

}

$zip->finish();

Scrutinizer?

Hey, I don't know if you're familiar with Scrutinizer, but I use it quite a bit - https://scrutinizer-ci.com

It will analyze your code and make recommendations.

Its free for open source projects and I highly recommend it. We use it at work as well.
I use it on some of my projects

Anyway, I can't set it up, you would have to but it'd be very useful finding potential issues with this thing.

download many urls with curl and zipstream

hi,thanks for your help.What I want to do is to download many urls with curl and zipstream,I want to get the zip from the brower and download and zip the files at the same time,but the below code(I found in https://hotexamples.com/examples/zipstream/ZipStream/addFileFromStream/php-zipstream-addfilefromstream-method-examples.html) doesn't work well. after I unzip the zip file,the jpgs are both empty and can't open. I'm new in php and look forward for your help.

function curlDownload(){

$zip = new \ZipStream\ZipStream("hi.zip");

$fileurls = array('http://img31.mtime.cn/pi/2014/10/22/092931.12614666_1000X1000.jpg', 'http://img31.mtime.cn/pi/2014/10/22/092931.79193700_1000X1000.jpg', 'http://img31.mtime.cn/pi/2014/10/22/092931.82617640_1000X1000.jpg', 'http://img31.mtime.cn/pi/2014/10/22/092931.63431992_1000X1000.jpg');

$fileurlslen = count($fileurls);

for ($x = 0; $x < $fileurlslen; $x++) {
    $fp = tmpfile();

    $ch = curl_init('localhost:63342/PhpFirstProject/hi.zip');
   
    curl_setopt($ch, CURLOPT_FILE, $fp);
    
    curl_exec ($ch);
    
    curl_close ($ch);

    $zip->addFileFromStream($fileurls[$x], $fp);
    fclose($fp);
}

$zip->finish();
}

Pause / Resume

Hello,

First of all, sorry if it's the wrong place to ask.
I would like to know if you think the ability of pause and resume a zipstream download could be a possible enhancement or if it is, by definition, impossible.

Thank you in advance for your answers.

Eckerdecker

Is it possible to create archive within an archive?

Hi @maennchen, I was wondering if it's possible to nest archives using your library. Everything is working great for me when streaming just one big archive, but I have a requirement of exporting data for multiple entries that need to be individually zipped in their own archives. I can easily create folders, but ideally a structure would be something like this:

MainArchive.zip
 |--SubArchive1.zip
   |--Text1.txt
   |--Image1.jpg
 |--SubArchive2.zip
   |--Text2.txt
   |--Image2.jpg
 |--SubArchive3.zip
   |--Text3.txt
   |--Image3.jpg

Document Nginx memory issue

This has taken me a ton of time to track down, but if you are using Nginx it can try to buffer the response. It took me many retries of just opening the request and seeing if the nginx process started steadily increasing memory usage without any stop. I do not know why this issue only happened sometimes and not others.

I am running this on Heroku and it looks like the default buildpack includes a custom buffer size of fastcgi_buffers 256 4k (https://github.com/heroku/heroku-buildpack-php/blob/master/conf/nginx/heroku.conf.php). If I am reading this correctly that means that it can buffer up to 1GB when the default web dynos max out at 500MB. While this seems like a bad config on Heroku's end, looking through Stackoverflow I saw plenty of people suggesting doing something similar so I doubt this configuration is unique to them.

My solution was to add header('X-Accel-Buffering: no'); to the streaming file and it appears to have fixed it. It could probably also be fixed by tweaking https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffers or anything else that would stop NGinx from using such large buffers for the response, but I feel like this was the easiest and the hardest to screw up the rest of the site's configuration with. Someone with more knowledge of how this stuff works can probably come up with a better solution, but I wasted hours just trying to figure out what was causing the problem in the first place.

tl;dr: I found a problem from a bad (and default on Heroku) configuration and want to possibly save others time trying to figure out WTF is going on.

Exception Handling

All Shut-up Operators (@) should be removed and the errors handled correctly.

Create new Exceptions for missing files etc.

Recursion

Is it possible to add folders and files recursively?

Thanks in advance.
v.

bad CRC error while trying to decompress zip created with ZipStream

I use the addFileFromStream to create archive. Archive is created but when I tried to extract it (using console linux unzip or GUI Archive Manager and GUI program for Windows) it fails with wrong crc error while extracting file.
It seems that pull request #61 fix this problem as I tried it locally by patching lib and it worked - I could extract files.

Wrong default option for httpHeaderCallback?

Description of the problem

Default value of httpHeaderCallback seems wrong in Option\Archive.

Shouldn't the value for this field be 'header' instead of 'method'?

This way you don't have to specifiy 'header' in the options when sending the headers. Otherwise it raises a TypeError (should be callable, string returned).

Tag v0.3.0

Could we tag v0.3.0 perhaps and push further changes to a v0.4.0?

I have a project I need this before and don't want to build against the old code base, and don't want to require an unstable release.

Besides the couple open issues that could be handled later, is there anything standing in the way of tagging it? @maennchen

Zip file from a remote URL

Hello !

I would like to put file from an URL to a zip archive and to be able to download it from the browser.
I heard of the function addFileFromStream but I don't know how to use it properly.

here it is the code I made by now but not working:

require 'vendor/autoload.php';

// create a new zipstream object
$zip = new ZipStream\ZipStream('example.zip');

// create a file named 'hello.txt' 
$zip->addFile('hello.txt', 'This is the contents of hello.txt');

// add a file named 'README.md' from a local file 'README.md'
$zip->addFileFromPath('README.md', 'README.md');

//My remote file
$file ="https://host/file.txt";

$fp = tmpfile();
$ch = curl_init($file);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_exec($ch);
curl_close($ch);
//rewind($fp);
$stream = readfile($file);
rewind($fp);
$zip->addFileFromStream("file.txt", $stream);
fclose($fp);
// finish the zip stream
$zip->finish();

How to use this lib with folder path

i am sorry for this question but i found it is very useful lib for my school project but i really don`t know how to use this lib.

can anyone give me step by step instruction with folder zip to download in stream without store to local storage.

it will be very helpful if i get working zip file using this lib.

v2 vs v1 - incompatibility with Microsoft Office

Greetings - @donatj recommended I submit an issue. I'm trying to generate .xlsx files in Google App Engine using ZipStream-PHP - it works great but Microsoft Excel refuses to open them - calling them corrupt (how rude!) I've attached two files - simple.xlsx works, my_simple.xlsx doesn't, even though the unzipped contents are identical. Any help you can provide would be enormously valuable!
simple.xlsx
my_simple.xlsx

Password protection

Description of the problem

Can you add password protection to this library?

  • ZipStream-PHP version: newest
  • PHP version: 7.x

How to stream ZIP to aws s3

Hello,

I would like to create large zips on my instances and send it back to S3 to store them. However zipStream does not heritate from file so i don't know how to send it back.

Is there anyway?

Thanks

Fix release "v.0.4.0". It should be "v0.4.0"

Hi there. Seems composer can't parse "v.0.4.0". (notice the "." after the "v").
I noticed you have a newer release "v0.4.1", but I can't use it because we still are on PHP 5.5; and that release enforces php 5.6 >=

Can you please create a "v0.4.0" release? It should point to
b1fad77

Thanks!

.docx files are recognized as corrupted by Microsoft Word

I tried to simply repackage existing .docx file with ZipStream, but resulting document cannot be opened by Microsoft Word.

.docx files are valid ZIP archives, they just have different file extension.

I'm going to add PR fixing this bug shortly.

addFileFromStream is not working for stream read from s3

Hi

I am reading a stream from S3 & trying to add that stream to zip but it does not work. It create empty zip file. Below is sample code.

require_once './vendor/autoload.php';
use Aws\S3\S3Client;
use ZipStream\ZipStream;

$client = S3Client::factory(array(
     'region' => 'us-east-1',
    'version' => 'latest',
    'credentials' => array(
    'key' => 'key',
    'secret'  => 'skey',
   )
));

$client->registerStreamWrapper();
$bucket = 'test-files';
$key = 'ab76d9d.mpg';
$context = stream_context_create(array(
    's3' => array(
        'seekable' => true
    )
));

if (!($stream = fopen("s3://{$bucket}/{$key}", 'r',false,$context))) {
    die('Could not open stream for reading');
}

$zip = new ZipStream('example.zip');
$zip->addFileFromStream('goodbye.mpg', $stream);
fclose($fp);
$zip->finish();

Separating documentation from code

Hello,

IMHO the doc directory should be removed and its content should be added to the wiki. It's much better to separate documentation from the project.

Basic usage should still be in the README.

.zip to .zip.cpgz infinite loop on mac

On a mac, the downloaded zip enters into a .zip to .zip.cpgz infinite loop (apparently OSX creates the .cpgz to read what's inside the .zip, but it fails and it creates a .zip and so on...).

I believe it's got something to do with the headers.

Can someone please look into this?

Write Tests

The test coverage is really small. We need to write some tests.

Release announcement URL could be wrong

The readme mentions a release announcement at the url: http://pablotron.org/?cid=1535

The page now displays "I'm in the process of migrating to a new server."

Maybe I'm just unlucky and visiting the page at the wrong time. But if already completed the migration process, it's probably best to update the url in the readme.

Thanks!

File size unknown when downloading.

Description of the problem

I was under the impression that when you set SendHttpHeaders and StatFiles to true that the headers would report the content length to the browser so it knows how large the file it is downloading is. Is this the case?

When the browser downloads the created ZIP it doesn't show the size of the file it's downloading. Now that I think about it I suppose that can't be known ahead of time since it is compressing on the fly, but for my use I'm just using STORE instead of deflate so I should be able to send that information myself? Any idea how I might go about doing that? If this is determined by the content-length header is there any overhead that comes from making the ZIP that I could calculate beforehand?

EDIT: I see now that if I add up the size of all the files beforehand I can send a content-length header and it is reflected in the browser. Is there any way to reliably determine how much overhead will be created by the ZIP wrapper beforehand to get an accurate file size? Or even an estimate? As long as it's slightly longer than the actual size it seems to work fine.

Informations

  • ZipStream-PHP version: 1.0.0-alpha.1
  • PHP version: 7.2.8

Please include any supplemental information you deem relevant to this issue.

Create Directories

I know how we can add files in folders and sub-folders in a zip. But is it possible to add blank folders?

I want to allow users to download their data in zip and want to match exactly same structure as they have on web, so creating lank folders is important.

How tu use addFileFromStream() with 'fopen' on a remote url?

Hi there.

I'm trying to use fopen to read an image from a remote url, and read the content in chunks. I need it to be in chunks since the file can be very large, and the memory limitation wouldn't let me load the full image in one go.

I've tried to use 'addFileFromStream()' method. But this part of the code doesn't work:

    // calculate header attributes
    fseek($stream, 0, SEEK_END);

fseek doesn't work with fopen on a remote url:

Warning: fseek(): stream does not support seeking in ZipStream.php on line 337

Long story short, this is how I'd need the code to work:

$zip = new ZipStream('mybundle.zip');
$fh = fopen('https://pixabay.com/static/uploads/photo/2016/07/10/21/47/cat-1508613_960_720.jpg');

$chunkSize  = 1048576; // 1MB.
while(!feof($fh)) {
    $data = fread($fh, $chunkSize);
    $zip->send($data);
}
$zip->finish();
exit(0);

Is there anyway I can achieve this with ZipStream? Thank you.

how to know when the file has finished downloading ?

i thought i have to call $zip->finish() to download the file and close the stream, but apparently its not needed and the package will stream as you add the files to $zip->addFileFromStream()

i tried something like

$done = $zip->finish();
if ($done) {
    // do something
}

but the do something part never fires.

so what exactly $zip->finish() does & how do i know when the stream has finished and file has downloaded ?

Corrupt Archive with Images

I am able to successfully create, stream, and open a zip containing text files, however, the moment I add a non-text file, I'm no longer able to open the zip. I get the following error from Windows:

Windows cannot open the folder.
The Compressed (zipped) Folder 'path\to\archive.zip' is invalid.

I was able to get everything to be successful with a tiny image (8kb), but the error continued to occur for a slightly larger file (27kb) and all other files I've tried. I'm not sure if this is a file size issue, a local setting issue, or something else, but I have run into the same issues with v0.5.2, 0.5.0, and 0.4.1. Below is my code with v0.5.2, the last version I tested.

$zip = new ZipStream('files.zip');
$zip->addFile('test-file2.jpg', file_get_contents('files/test2.jpg'));
$zip->finish();

I have tried to use addFile and addFileFromPath - both with the same result. The above code works if I use 'files/test.txt' instead of the jpg.

Update version string

In ZipStream.php the VERSION is still set at 0.3.0 even though the latest release is 0.5.1.

Allowed memory size of 553648128 bytes exhausted (tried to allocate 1048577 bytes)

@maennchen I am using your ZipStream. However while using addFileFromStream to add more than 400+ files to the zip I am getting following error

Fatal Error : Allowed memory size of 553648128 bytes exhausted (tried to allocate 1048577 bytes) at src/ZipStream.php 351

Following is the code we are using.

$outputFileName = 'example.zip';
$zip = new ZipStream\ZipStream($outputFileName);
$s3 = Drupal\amazons3\S3Client::factory();

$phpForceDownload = array(); // It contains 400+ S3 Urls

foreach ($phpForceDownload as $fileUrl) {
        $command = $s3->getCommand('GetObject', array(
          'Bucket' => 'my-bucket-storage-100',
          'Key' => $fileUrl
        ));

        $signedUrl = $command->createPresignedUrl('+20 minutes');

        // Get the file name on S3 so we can save it to the zip file
        //  using the same name.
        $fileName = basename($fileUrl);

        // We want to fetch the file to a file pointer so we create it here
        //  and create a curl request and store the response into the file
        //  pointer.
        // After we've fetched the file we add the file to the zip file using
        //  the file pointer and then we close the curl request and the file
        //  pointer.
        // Closing the file pointer removes the file.
        $fp = tmpfile();
        $ch = curl_init($signedUrl);
        curl_setopt($ch, CURLOPT_TIMEOUT, 120);
        curl_setopt($ch, CURLOPT_FILE, $fp);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_exec($ch);
        curl_close($ch);
        $zip->addFileFromStream($fileName, $fp);
        fclose($fp);
      }
      $zip->finish();

Large file support

There are other similar libraries with support for Zip64, to allow files larger than 2GB to be zipped. It would be great if you could add that to this library as well. Great work, btw!

help me,sir

I am facing memory-limit error in wp plugin code.
My code is below
function zipData($source, $destination) {
if (extension_loaded('zip')) {
if (file_exists($source)) {
$zip = new ZipArchive();
if ($zip -> open($destination, ZipArchive::CREATE) === TRUE) {
$source = realpath($source);
if (is_dir($source)) {
$iterator = new RecursiveDirectoryIterator($source);

                        $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);
                        $files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);
                        foreach ($files as $file) {
                            $file = realpath($file);
                            if (is_dir($file)) {
                                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
                            } else if (is_file($file)) {
                                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
                            }
                        }
                    } else if (is_file($source)) {
                        $zip->addFromString(basename($source), file_get_contents($source));
                    }
                }
                return $zip->close();
            }
        }
        return false;
    }

    ini_set('max_execution_time', 600);
    ini_set('memory_limit','1024M');
    ini_set('upload_max_filesize','5000M');
    zipData($upload_dir['basedir'], $upload_dir['basedir'].'/Jincowboy/JinBackupMedia'. time() .'.zip');

but i am facing memory limit. so i checked google. i saw stream zipfile generation is needed for avoding memory limit.
But i couldn't confirm about this.
I want my code allow memory limit and creation zip file of big file directory with big files

Corrupt File

I've copied the sample code from #31 and get a corrupt zip archive on macOS using PHP 7.1.

I've also tested the code here from aws/aws-sdk-php#809 and get matching bytes length.

Content length whilst S3 streaming

Hi all!

I was banging my head trying to work out how to stream a zip using Amazon Web Service's S3, was getting a full but corrupted zip file. Was looking at some other problems people were having but have come out with a different problem/solution.

In short, if you use header("Content-length: ".$length); before finishing the zip, you get a corrupt file.

It works to not have this line for now, but it would be good to give this to the user so that they get a download time/percentage complete figure in their web browser. Any ideas? Hopefully I'm not missing something obvious...

Here is my code in full (also as an example of a working S3 use case)

$zip = new ZipStream\ZipStream($SentFileName . '.zip');

// Send length header (WHICH WILL CORRUPT BELOW FILE)
// header("Content-length: ".$length); 

 // Create a new zipstream object
        foreach($this -> ZipList as $path => $files){
            foreach($files as $file){
                        // Copy object
                        // We need to use a command to get a request for the S3 object
                        //  and then we can get the presigned URL.
                        $command = $s3Client->getCommand('GetObject', [
                            'Bucket' => AWS_S3_BUCKET_NAME,
                            'Key' => $file-> Key
                        ]);

                        $signedUrl = $s3Client->createPresignedRequest($command, "+10 minutes")->getUri();

                        // We want to fetch the file to a file pointer so we create it here
                        //  and create a curl request and store the response into the file
                        //  pointer.
                        // After we've fetched the file we add the file to the zip file using
                        //  the file pointer and then we close the curl request and the file
                        //  pointer.
                        // Closing the file pointer removes the file.
                        $fp = tmpfile();
                        $ch = curl_init($signedUrl);
                        curl_setopt($ch, CURLOPT_TIMEOUT, 120);
                        curl_setopt($ch, CURLOPT_FILE, $fp);
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                        curl_exec($ch);
                        curl_close($ch);
                        rewind($fp);

                        try {
                            $zip->addFileFromStream($path.$file -> FileName, $fp);
                        } catch (StreamNotReadableException $e){
                            // Error
                        }

                        fclose($fp);
            }
        }

        $zip->finish();

Permission denied leads to empty file rather than error or no file

If you use add_file_from_path to try to add a file for which you do not have read access (i.e. permission denied), rather than raising an error or not adding the file, ZipStream-PHP will add an empty file with the name specified.

This should probably be changed to throw an exception, or just not add the file. No?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.