Skip to content

Commit 2e00fb5

Browse files
authored
Migrate Wiki into Guides (#228)
1 parent 51e0182 commit 2e00fb5

13 files changed

Lines changed: 484 additions & 22 deletions

.github/CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,5 @@ To generate the documentation for the library, run:
135135
```bash
136136
$ composer run docs:generate
137137
```
138+
139+
The guide documentation pages can be found in the `/guides/` directory.

README.md

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Simply add a dependency on maennchen/zipstream-php to your project's composer.js
2626
composer require maennchen/zipstream-php
2727
```
2828

29-
## Usage and options
29+
## Usage
3030

3131
For detailed instructions, please check the
3232
[Documentation](https://maennchen.dev/ZipStream-PHP/).
@@ -50,31 +50,10 @@ $zip->addFile('hello.txt', 'This is the contents of hello.txt');
5050
// add a file named 'some_image.jpg' from a local file 'path/to/image.jpg'
5151
$zip->addFileFromPath('some_image.jpg', 'path/to/image.jpg');
5252

53-
// add a file named 'goodbye.txt' from an open stream resource
54-
$fp = tmpfile();
55-
fwrite($fp, 'The quick brown fox jumped over the lazy dog.');
56-
rewind($fp);
57-
$zip->addFileFromStream('goodbye.txt', $fp);
58-
fclose($fp);
59-
6053
// finish the zip stream
6154
$zip->finish();
6255
```
6356

64-
You can also add comments, modify file timestamps, and customize (or
65-
disable) the HTTP headers. It is also possible to specify the storage method when adding files,
66-
the current default storage method is 'deflate' i.e files are stored with Compression mode 0x08.
67-
68-
See the [Wiki](https://github.com/maennchen/ZipStream-PHP/wiki) for details.
69-
70-
## Known issues
71-
72-
The native Mac OS archive extraction tool prior to macOS 10.15 might not open archives in some conditions. A workaround is to disable the Zip64 feature with the option `$opt->setEnableZip64(false)`. This limits the archive to 4 Gb and 64k files but will allow users on macOS 10.14 and below to open them without issue. See #116.
73-
74-
The linux `unzip` utility might not handle properly unicode characters. It is recommended to extract with another tool like [7-zip](https://www.7-zip.org/). See [#146](https://github.com/maennchen/ZipStream-PHP/issues/146).
75-
76-
It is the responsability of the client code to make sure that files are not saved with the same path, as it is not possible for the library to figure it out while streaming a zip. See [#154](https://github.com/maennchen/ZipStream-PHP/issues/154).
77-
7857
## Upgrade to version 2.0.0
7958

8059
- Only the self opened streams will be closed (#139)

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"/.gitattributes",
5959
"/.github",
6060
"/.gitignore",
61+
"/guides",
6162
"/.phive",
6263
"/.php-cs-fixer.cache",
6364
"/.php-cs-fixer.dist.php",

guides/ContentLength.rst

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
Adding Content-Length header
2+
=============
3+
4+
Adding a ``Content-Length`` header for ``ZipStream`` is not trivial since the
5+
size is not known beforehand.
6+
7+
The following workaround adds an approximated header:
8+
9+
.. code-block:: php
10+
11+
class Zip
12+
{
13+
/** @var string */
14+
private $name;
15+
16+
private $files = [];
17+
18+
public function __construct($name)
19+
{
20+
$this->name = $name;
21+
}
22+
23+
public function addFile($name, $data)
24+
{
25+
$this->files[] = ['type' => 'addFile', 'name' => $name, 'data' => $data];
26+
}
27+
28+
public function addFileFromPath($name, $path)
29+
{
30+
$this->files[] = ['type' => 'addFileFromPath', 'name' => $name, 'path' => $path];
31+
}
32+
33+
public function getEstimate()
34+
{
35+
$estimate = 22;
36+
foreach ($this->files as $file) {
37+
$estimate += 76 + 2 * strlen($file['name']);
38+
if ($file['type'] === 'addFile') {
39+
$estimate += strlen($file['data']);
40+
}
41+
if ($file['type'] === 'addFileFromPath') {
42+
$estimate += filesize($file['path']);
43+
}
44+
}
45+
return $estimate;
46+
}
47+
48+
public function finish()
49+
{
50+
header('Content-Length: ' . $this->getEstimate());
51+
$options = new \ZipStream\Option\Archive();
52+
$options->setSendHttpHeaders(true);
53+
$options->setEnableZip64(false);
54+
$options->setDeflateLevel(-1);
55+
$zip = new \ZipStream\ZipStream($this->name, $options);
56+
57+
$fileOptions = new \ZipStream\Option\File();
58+
$fileOptions->setMethod(\ZipStream\Option\Method::STORE());
59+
foreach ($this->files as $file) {
60+
if ($file['type'] === 'addFile') {
61+
$zip->addFile($file['name'], $file['data'], $fileOptions);
62+
}
63+
if ($file['type'] === 'addFileFromPath') {
64+
$zip->addFileFromPath($file['name'], $file['path'], $fileOptions);
65+
}
66+
}
67+
$zip->finish();
68+
exit;
69+
}
70+
}
71+
72+
It only works with the following constraints:
73+
74+
- All file content is known beforehand.
75+
- Content Deflation is disabled
76+
77+
Thanks to
78+
`partiellkorrekt <https://github.com/maennchen/ZipStream-PHP/issues/89#issuecomment-1047949274>`_
79+
for this workaround.

guides/FlySystem.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Usage with FlySystem
2+
===============
3+
4+
For saving or uploading the generated zip, you can use the
5+
`Flysystem <https://flysystem.thephpleague.com>`_ package, and its many
6+
adapters.
7+
8+
For that you will need to provide another stream than the ``php://output``
9+
default one, and pass it to Flysystem ``putStream`` method.
10+
11+
.. code-block:: php
12+
13+
// Open Stream only once for read and write since it's a memory stream and
14+
// the content is lost when closing the stream / opening another one
15+
$tempStream = fopen('php://memory', 'w+');
16+
17+
// Init Options
18+
$zipStreamOptions = new Archive();
19+
$zipStreamOptions->setOutputStream($tempStream);
20+
21+
// Create Zip Archive
22+
$zipStream = new ZipStream('test.zip', $zipStreamOptions);
23+
$zipStream->addFile('test.txt', 'text');
24+
$zipStream->finish();
25+
26+
// Store File (see Flysystem documentation, and all its framework integration)
27+
$adapter = new Local(__DIR__.'/path/to/folder'); // Can be any adapter (AWS, Google, Ftp, etc.)
28+
$filesystem = new Filesystem($adapter);
29+
30+
$filesystem->putStream('test.zip', $tempStream)
31+
32+
// Close Stream
33+
fclose($tempStream);

guides/Nginx.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Usage with nginx
2+
=============
3+
4+
If you are using nginx as a webserver, it will try to buffer the response.
5+
So you'll want to disable this with a custom header:
6+
7+
.. code-block:: php
8+
header('X-Accel-Buffering: no');
9+
# or with the Response class from Symfony
10+
$response->headers->set('X-Accel-Buffering', 'no');
11+
12+
Alternatively, you can tweak the
13+
`fastcgi cache parameters <https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffers>`_
14+
within nginx config.
15+
16+
See `original issue <https://github.com/maennchen/ZipStream-PHP/issues/77>`_.

guides/Options.rst

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
Available options
2+
===============
3+
4+
Here is the full list of options available to you. You can also have a look at
5+
``src/Option/Archive.php`` file.
6+
7+
First, an instance of ``ZipStream\Option\Archive`` needs to be created, and
8+
after that you use setters methods to modify the values.
9+
10+
.. code-block:: php
11+
use ZipStream\ZipStream;
12+
use ZipStream\Option\Archive as ArchiveOptions;
13+
14+
require_once 'vendor/autoload.php';
15+
16+
$opt = new ArchiveOptions();
17+
18+
// Define output stream (argument is of type resource)
19+
$opt->setOutputStream($fd);
20+
21+
// Set the deflate level (default is 6; use -1 to disable it)
22+
$opt->setDeflateLevel(6);
23+
24+
// Add a comment to the zip file
25+
$opt->setComment('This is a comment.');
26+
27+
// Size, in bytes, of the largest file to try and load into memory (used by addFileFromPath()). Large files may also be compressed differently; see the 'largeFileMethod' option.
28+
$opt->setLargeFileSize(30000000);
29+
30+
// How to handle large files. Legal values are STORE (the default), or DEFLATE. Store sends the file raw and is significantly faster, while DEFLATE compresses the file and is much, much slower. Note that deflate must compress the file twice and is extremely slow.
31+
$opt->setLargeFileMethod(ZipStream\Option\Method::STORE());
32+
$opt->setLargeFileMethod(ZipStream\Option\Method::DEFLATE());
33+
34+
// Send http headers (default is false)
35+
$opt->setSendHttpHeaders(false);
36+
37+
// HTTP Content-Disposition. Defaults to 'attachment', where FILENAME is the specified filename. Note that this does nothing if you are not sending HTTP headers.
38+
$opt->setContentDisposition('attachment');
39+
40+
// Set the content type (does nothing if you are not sending HTTP headers)
41+
$opt->setContentType('application/x-zip');
42+
43+
// Set the function called for setting headers. Default is the `header()` of PHP
44+
$opt->setHttpHeaderCallback('header');
45+
46+
// Enable streaming files with single read where general purpose bit 3 indicates local file header contain zero values in crc and size fields, these appear only after file contents in data descriptor block. Default is false. Set to true if your input stream is remote (used with addFileFromStream()).
47+
$opt->setZeroHeader(false);
48+
49+
// Enable reading file stat for determining file size. When a 32-bit system reads file size that is over 2 GB, invalid value appears in file size due to integer overflow. Should be disabled on 32-bit systems with method addFileFromPath if any file may exceed 2 GB. In this case file will be read in blocks and correct size will be determined from content. Default is true.
50+
$opt->setStatFiles(true);
51+
52+
// Enable zip64 extension, allowing very large archives (> 4Gb or file count > 64k)
53+
// default is true
54+
$opt->setEnableZip64(true);
55+
56+
// Flush output buffer after every write
57+
// default is false
58+
$opt->setFlushOutput(true);
59+
60+
// Now that everything is set you can pass the options to the ZipStream instance
61+
$zip = new ZipStream('example.zip', $opt);

guides/PSR7Streams.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
Usage with PSR 7 Streams
2+
===============
3+
4+
PSR-7 streams are `standardized streams <https://www.php-fig.org/psr/psr-7/>`_.
5+
6+
ZipStream-PHP supports working with these streams with the function
7+
``addFileFromPsr7Stream``.
8+
9+
For all parameters of the function see the API documentation.
10+
11+
Example
12+
---------------
13+
14+
.. code-block:: php
15+
16+
$stream = $response->getBody();
17+
// add a file named 'streamfile.txt' from the content of the stream
18+
$zip->addFileFromPsr7Stream('streamfile.txt', $stream);

guides/StreamOutput.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
Stream Output
2+
===============
3+
4+
Stream to S3 Bucket
5+
---------------
6+
7+
.. code-block:: php
8+
use Aws\S3\S3Client;
9+
use Aws\Credentials\CredentialProvider;
10+
use ZipStream\Option\Archive;
11+
use ZipStream\ZipStream;
12+
13+
$bucket = 'your bucket name';
14+
$client = new S3Client([
15+
'region' => 'your region',
16+
'version' => 'latest',
17+
'bucketName' => $bucket,
18+
'credentials' => CredentialProvider::defaultProvider(),
19+
]);
20+
$client->registerStreamWrapper();
21+
22+
$zipFile = fopen("s3://$bucket/example.zip", 'w');
23+
24+
$options = new Archive();
25+
$options->setEnableZip64(false);
26+
$options->setOutputStream($zipFile);
27+
28+
$zip = new ZipStream(null, $options);
29+
$zip->addFile('file1.txt', 'File1 data');
30+
$zip->addFile('file2.txt', 'File2 data');
31+
$zip->finish();
32+
33+
fclose($zipFile);

0 commit comments

Comments
 (0)