Файловый менеджер - Редактировать - /home/clickysoft/public_html/jmapi5.clickysoft.net/maennchen.tar
Назад
zipstream-php/guides/index.rst 0000644 00000007670 15021223105 0012471 0 ustar 00 ZipStream PHP ============= 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. .. toctree:: index Symfony Options StreamOutput FlySystem PSR7Streams Nginx Varnish ContentLength 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: .. code-block:: sh composer require maennchen/zipstream-php If you want to use``addFileFromPsr7Stream``` (``Psr\Http\Message\StreamInterface``) or use a stream instead of a ``resource`` as ``outputStream``, the following dependencies must be installed as well: .. code-block:: sh composer require psr/http-message guzzlehttp/psr7 If ``composer install`` yields the following error, your installation is missing the `mbstring extension <https://www.php.net/manual/en/book.mbstring.php>`_, either `install it <https://www.php.net/manual/en/mbstring.installation.php>`_ or run the follwoing command: .. code-block:: Your requirements could not be resolved to an installable set of packages. Problem 1 - Root composer.json requires PHP extension ext-mbstring * but it is missing from your system. Install or enable PHP's mbstrings extension. .. code-block:: sh composer require symfony/polyfill-mbstring Usage Intro --------------- Here's a simple example: .. code-block:: php // 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', ); // add a file named 'goodbye.txt' from an open stream resource $filePointer = tmpfile(); fwrite($filePointer, 'The quick brown fox jumped over the lazy dog.'); rewind($filePointer); $zip->addFileFromStream( fileName: 'goodbye.txt', stream: $filePointer, ); fclose($filePointer); // add a file named 'streamfile.txt' from the body of a `guzzle` response // Setup with `psr/http-message` & `guzzlehttp/psr7` dependencies required. $zip->addFileFromPsr7Stream( fileName: 'streamfile.txt', stream: $response->getBody(), ); // finish the zip stream $zip->finish(); You can also add comments, modify file timestamps, and customize (or disable) the HTTP headers. It is also possible to specify the storage method when adding files, the current default storage method is ``DEFLATE`` i.e files are stored with Compression mode 0x08. Known Issues --------------- 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 ``enableZip64: 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 <https://github.com/maennchen/ZipStream-PHP/issues/146>`_. 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>`_. 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>`_. zipstream-php/guides/FlySystem.rst 0000644 00000002070 15021223105 0013306 0 ustar 00 Usage with FlySystem =============== For saving or uploading the generated zip, you can use the `Flysystem <https://flysystem.thephpleague.com>`_ package, and its many adapters. For that you will need to provide another stream than the ``php://output`` default one, and pass it to Flysystem ``putStream`` method. .. code-block:: php // Open Stream only once for read and write since it's a memory stream and // the content is lost when closing the stream / opening another one $tempStream = fopen('php://memory', 'w+'); // Create Zip Archive $zipStream = new ZipStream( outputStream: $tempStream, outputName: 'test.zip', ); $zipStream->addFile('test.txt', 'text'); $zipStream->finish(); // Store File // (see Flysystem documentation, and all its framework integration) // Can be any adapter (AWS, Google, Ftp, etc.) $adapter = new Local(__DIR__.'/path/to/folder'); $filesystem = new Filesystem($adapter); $filesystem->writeStream('test.zip', $tempStream) // Close Stream fclose($tempStream); zipstream-php/guides/Options.rst 0000644 00000004260 15021223105 0013005 0 ustar 00 Available options =============== Here is the full list of options available to you. You can also have a look at ``src/ZipStream.php`` file. .. code-block:: php use ZipStream\ZipStream; require_once 'vendor/autoload.php'; $zip = new ZipStream( // Define output stream // (argument is eiter a resource or implementing // `Psr\Http\Message\StreamInterface`) // // Setup with `psr/http-message` & `guzzlehttp/psr7` dependencies // required when using `Psr\Http\Message\StreamInterface`. outputStream: $filePointer, // Set the deflate level (default is 6; use -1 to disable it) defaultDeflateLevel: 6, // Add a comment to the zip file comment: 'This is a comment.', // Send http headers (default is true) sendHttpHeaders: false, // HTTP Content-Disposition. // Defaults to 'attachment', where FILENAME is the specified filename. // Note that this does nothing if you are not sending HTTP headers. contentDisposition: 'attachment', // Output Name for HTTP Content-Disposition // Defaults to no name outputName: "example.zip", // HTTP Content-Type. // Defaults to 'application/x-zip'. // Note that this does nothing if you are not sending HTTP headers. contentType: 'application/x-zip', // Set the function called for setting headers. // Default is the `header()` of PHP httpHeaderCallback: header(...), // 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. // Set to true if your input stream is remote // (used with addFileFromStream()). // Default is false. defaultEnableZeroHeader: false, // Enable zip64 extension, allowing very large archives // (> 4Gb or file count > 64k) // Default is true enableZip64: true, // Flush output buffer after every write // Default is false flushOutput: true, ); zipstream-php/guides/Nginx.rst 0000644 00000001057 15021223105 0012436 0 ustar 00 Usage with nginx ============= If you are using nginx as a webserver, it will try to buffer the response. So you'll want to disable this with a custom header: .. code-block:: php header('X-Accel-Buffering: no'); # or with the Response class from Symfony $response->headers->set('X-Accel-Buffering', 'no'); Alternatively, you can tweak the `fastcgi cache parameters <https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffers>`_ within nginx config. See `original issue <https://github.com/maennchen/ZipStream-PHP/issues/77>`_. zipstream-php/guides/ContentLength.rst 0000644 00000002534 15021223105 0014130 0 ustar 00 Adding Content-Length header ============= Adding a ``Content-Length`` header for ``ZipStream`` can be achieved by using the options ``SIMULATION_STRICT`` or ``SIMULATION_LAX`` in the ``operationMode`` parameter. In the ``SIMULATION_STRICT`` mode, ``ZipStream`` will not allow to calculate the size based on reading the whole file. ``SIMULATION_LAX`` will read the whole file if neccessary. ``SIMULATION_STRICT`` is therefore useful to make sure that the size can be calculated efficiently. .. code-block:: php use ZipStream\OperationMode; use ZipStream\ZipStream; $zip = new ZipStream( operationMode: OperationMode::SIMULATE_STRICT, // or SIMULATE_LAX defaultEnableZeroHeader: false, sendHttpHeaders: true, outputStream: $stream, ); // Normally add files $zip->addFile('sample.txt', 'Sample String Data'); // Use addFileFromCallback and exactSize if you want to defer opening of // the file resource $zip->addFileFromCallback( 'sample.txt', exactSize: 18, callback: function () { return fopen('...'); } ); // Read resulting file size $size = $zip->finish(); // Tell it to the browser header('Content-Length: '. $size); // Execute the Simulation and stream the actual zip to the client $zip->executeSimulation(); zipstream-php/guides/StreamOutput.rst 0000644 00000001470 15021223105 0014026 0 ustar 00 Stream Output =============== Stream to S3 Bucket --------------- .. code-block:: php use Aws\S3\S3Client; use Aws\Credentials\CredentialProvider; use ZipStream\ZipStream; $bucket = 'your bucket name'; $client = new S3Client([ 'region' => 'your region', 'version' => 'latest', 'bucketName' => $bucket, 'credentials' => CredentialProvider::defaultProvider(), ]); $client->registerStreamWrapper(); $zipFile = fopen("s3://$bucket/example.zip", 'w'); $zip = new ZipStream( enableZip64: false, outputStream: $zipFile, ); $zip->addFile( fileName: 'file1.txt', data: 'File1 data', ); $zip->addFile( fileName: 'file2.txt', data: 'File2 data', ); $zip->finish(); fclose($zipFile); zipstream-php/guides/PSR7Streams.rst 0000644 00000001032 15021223105 0013436 0 ustar 00 Usage with PSR 7 Streams =============== PSR-7 streams are `standardized streams <https://www.php-fig.org/psr/psr-7/>`_. ZipStream-PHP supports working with these streams with the function ``addFileFromPsr7Stream``. For all parameters of the function see the API documentation. Example --------------- .. code-block:: php $stream = $response->getBody(); // add a file named 'streamfile.txt' from the content of the stream $zip->addFileFromPsr7Stream( fileName: 'streamfile.txt', stream: $stream, ); zipstream-php/guides/Symfony.rst 0000644 00000011067 15021223105 0013021 0 ustar 00 Usage with Symfony =============== Overview for using ZipStream in Symfony -------- Using ZipStream in Symfony requires use of Symfony's ``StreamedResponse`` when used in controller actions. Wrap your call to the relevant ``ZipStream`` stream method (i.e. ``addFile``, ``addFileFromPath``, ``addFileFromStream``) in Symfony's ``StreamedResponse`` function passing in any required arguments for your use case. Using Symfony's ``StreamedResponse`` will allow Symfony to stream output from ZipStream correctly to users' browsers and avoid a corrupted final zip landing on the users' end. Example for using ``ZipStream`` in a controller action to zip stream files stored in an AWS S3 bucket by key: .. code-block:: php use Symfony\Component\HttpFoundation\StreamedResponse; use Aws\S3\S3Client; use ZipStream; //... /** * @Route("/zipstream", name="zipstream") */ public function zipStreamAction() { // sample test file on s3 $s3keys = array( "ziptestfolder/file1.txt" ); $s3Client = $this->get('app.amazon.s3'); //s3client service $s3Client->registerStreamWrapper(); //required // using StreamedResponse to wrap ZipStream functionality // for files on AWS s3. $response = new StreamedResponse(function() use($s3keys, $s3Client) { // Define suitable options for ZipStream Archive. // this is needed to prevent issues with truncated zip files //initialise zipstream with output zip filename and options. $zip = new ZipStream\ZipStream( outputName: 'test.zip', defaultEnableZeroHeader: true, contentType: 'application/octet-stream', ); //loop keys - useful for multiple files foreach ($s3keys 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); // concatenate s3path. // replace with your bucket name or get from parameters file. $bucket = 'bucketname'; $s3path = "s3://" . $bucket . "/" . $key; //addFileFromStream if ($streamRead = fopen($s3path, 'r')) { $zip->addFileFromStream( fileName: $fileName, stream: $streamRead, ); } else { die('Could not open stream for reading'); } } $zip->finish(); }); return $response; } In the above example, files on AWS S3 are being streamed from S3 to the Symfon application via ``fopen`` call when the s3Client has ``registerStreamWrapper`` applied. This stream is then passed to ``ZipStream`` via the ``addFileFromStream`` function, which ZipStream then streams as a zip to the client browser via Symfony's ``StreamedResponse``. No Zip is created server side, which makes this approach a more efficient solution for streaming zips to the client browser especially for larger files. For the above use case you will need to have installed `aws/aws-sdk-php-symfony <https://github.com/aws/aws-sdk-php-symfony>`_ to support accessing S3 objects in your Symfony web application. This is not required for locally stored files on you server you intend to stream via ``ZipStream``. See official Symfony documentation for details on `Symfony's StreamedResponse <https://symfony.com/doc/current/components/http_foundation.html#streaming-a-response>`_ ``Symfony\Component\HttpFoundation\StreamedResponse``. Note from `S3 documentation <https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/s3-stream-wrapper.html>`_: Streams opened in "r" mode only allow data to be read from the stream, and are not seekable by default. This is so that data can be downloaded from Amazon S3 in a truly streaming manner, where previously read bytes do not need to be buffered into memory. If you need a stream to be seekable, you can pass seekable into the stream context options of a function. Make sure to configure your S3 context correctly! Uploading a file -------- You need to add correct permissions (see `#120 <https://github.com/maennchen/ZipStream-PHP/issues/120>`_) **example code** .. code-block:: php $path = "s3://{$adapter->getBucket()}/{$this->getArchivePath()}"; // the important bit $outputContext = stream_context_create([ 's3' => ['ACL' => 'public-read'], ]); fopen($path, 'w', null, $outputContext); zipstream-php/guides/Varnish.rst 0000644 00000001207 15021223105 0012762 0 ustar 00 Usage with Varnish ============= Serving a big zip with varnish in between can cause random stream close. This can be solved by adding attached code to the vcl file. To avoid the problem, add the following to your varnish config file: .. code-block:: sub vcl_recv { # Varnish can’t intercept the discussion anymore # helps for streaming big zips if (req.url ~ "\.(tar|gz|zip|7z|exe)$") { return (pipe); } } # Varnish can’t intercept the discussion anymore # helps for streaming big zips sub vcl_pipe { set bereq.http.connection = "close"; return (pipe); } zipstream-php/phpunit.xml.dist 0000644 00000000736 15021223105 0012517 0 ustar 00 <?xml version="1.0"?> <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" bootstrap="test/bootstrap.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd" cacheDirectory=".phpunit.cache"> <coverage/> <testsuites> <testsuite name="Application"> <directory>test</directory> </testsuite> </testsuites> <logging/> <source> <include> <directory suffix=".php">src</directory> </include> </source> </phpunit> zipstream-php/.phive/phars.xml 0000644 00000000306 15021223105 0012365 0 ustar 00 <?xml version="1.0" encoding="UTF-8"?> <phive xmlns="https://phar.io/phive"> <phar name="phpdocumentor" version="^3.3.1" installed="3.3.1" location="./tools/phpdocumentor" copy="false"/> </phive> zipstream-php/.phpdoc/template/base.html.twig 0000644 00000001262 15021223105 0015256 0 ustar 00 {% extends 'layout.html.twig' %} {% set topMenu = { "menu": [ { "name": "Guides", "url": "https://maennchen.dev/ZipStream-PHP/guide/index.html"}, { "name": "API", "url": "https://maennchen.dev/ZipStream-PHP/classes/ZipStream-ZipStream.html"}, { "name": "Issues", "url": "https://github.com/maennchen/ZipStream-PHP/issues"}, ], "social": [ { "iconClass": "fab fa-github", "url": "https://github.com/maennchen/ZipStream-PHP"}, { "iconClass": "fas fa-envelope-open-text", "url": "https://github.com/maennchen/ZipStream-PHP/discussions"}, { "iconClass": "fas fa-money-bill", "url": "https://opencollective.com/zipstream"}, ] } %} zipstream-php/composer.json 0000644 00000004452 15021223105 0012065 0 ustar 00 { "name": "maennchen/zipstream-php", "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.", "keywords": ["zip", "stream"], "type": "library", "license": "MIT", "authors": [{ "name": "Paul Duncan", "email": "pabs@pablotron.org" }, { "name": "Jonatan Männchen", "email": "jonatan@maennchen.ch" }, { "name": "Jesse Donat", "email": "donatj@gmail.com" }, { "name": "András Kolesár", "email": "kolesar@kolesar.hu" } ], "require": { "php-64bit": "^8.1", "ext-mbstring": "*", "ext-zlib": "*" }, "require-dev": { "phpunit/phpunit": "^10.0", "guzzlehttp/guzzle": "^7.5", "ext-zip": "*", "mikey179/vfsstream": "^1.6", "php-coveralls/php-coveralls": "^2.5", "friendsofphp/php-cs-fixer": "^3.16", "vimeo/psalm": "^5.0" }, "suggest": { "psr/http-message": "^2.0", "guzzlehttp/psr7": "^2.4" }, "scripts": { "format": "php-cs-fixer fix", "test": [ "@test:unit", "@test:formatted", "@test:lint" ], "test:unit": "phpunit --coverage-clover=coverage.clover.xml --coverage-html cov", "test:unit:slow": "@test:unit --group slow", "test:unit:fast": "@test:unit --exclude-group slow", "test:formatted": "@format --dry-run --stop-on-violation --using-cache=no", "test:lint": "psalm --stats --show-info=true --find-unused-psalm-suppress", "coverage:report": "php-coveralls --coverage_clover=coverage.clover.xml --json_path=coveralls-upload.json --insecure", "install:tools": "phive install --trust-gpg-keys 0x67F861C3D889C656", "docs:generate": "tools/phpdocumentor --sourcecode" }, "autoload": { "psr-4": { "ZipStream\\": "src/" } }, "autoload-dev": { "psr-4": { "ZipStream\\Test\\": "test/" } }, "archive": { "exclude": [ "/composer.lock", "/docs", "/.gitattributes", "/.github", "/.gitignore", "/guides", "/.phive", "/.php-cs-fixer.cache", "/.php-cs-fixer.dist.php", "/.phpdoc", "/phpdoc.dist.xml", "/.phpunit.result.cache", "/phpunit.xml.dist", "/psalm.xml", "/test", "/tools", "/.tool-versions", "/vendor" ] } } zipstream-php/.php-cs-fixer.dist.php 0000644 00000004267 15021223105 0013405 0 ustar 00 <?php declare(strict_types=1); /** * PHP-CS-Fixer config for ZipStream-PHP * @author Nicolas CARPi <nico-git@deltablot.email> * @copyright 2022 Nicolas CARPi * @see https://github.com/maennchen/ZipStream-PHP * @license MIT * @package maennchen/ZipStream-PHP */ use PhpCsFixer\Config; use PhpCsFixer\Finder; $finder = Finder::create() ->exclude('.github') ->exclude('.phpdoc') ->exclude('docs') ->exclude('tools') ->exclude('vendor') ->in(__DIR__); $config = new Config(); return $config->setRules([ '@PER' => true, '@PER:risky' => true, '@PHP82Migration' => true, '@PHPUnit84Migration:risky' => true, 'array_syntax' => ['syntax' => 'short'], 'class_attributes_separation' => true, 'declare_strict_types' => true, 'dir_constant' => true, 'is_null' => true, 'no_homoglyph_names' => true, 'no_null_property_initialization' => true, 'no_php4_constructor' => true, 'no_unused_imports' => true, 'no_useless_else' => true, 'non_printable_character' => true, 'ordered_imports' => true, 'ordered_class_elements' => true, 'php_unit_construct' => true, 'pow_to_exponentiation' => true, 'psr_autoloading' => true, 'random_api_migration' => true, 'return_assignment' => true, 'self_accessor' => true, 'semicolon_after_instruction' => true, 'short_scalar_cast' => true, 'simplified_null_return' => true, 'single_blank_line_before_namespace' => true, 'single_class_element_per_statement' => true, 'single_line_comment_style' => true, 'single_quote' => true, 'space_after_semicolon' => true, 'standardize_not_equals' => true, 'strict_param' => true, 'ternary_operator_spaces' => true, 'trailing_comma_in_multiline' => true, 'trim_array_spaces' => true, 'unary_operator_spaces' => true, 'global_namespace_import' => [ 'import_classes' => true, 'import_functions' => true, 'import_constants' => true, ], ]) ->setFinder($finder) ->setRiskyAllowed(true); zipstream-php/.editorconfig 0000644 00000000445 15021223105 0012016 0 ustar 00 root = true [*] end_of_line = lf insert_final_newline = true charset = utf-8 [*.{yml,md,xml}] indent_style = space indent_size = 2 [*.{rst,php}] indent_style = space indent_size = 4 [composer.json] indent_style = space indent_size = 2 [composer.lock] indent_style = space indent_size = 4 zipstream-php/phpdoc.dist.xml 0000644 00000002412 15021223105 0012276 0 ustar 00 <?xml version="1.0" encoding="UTF-8" ?> <phpdocumentor configVersion="3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://www.phpdoc.org" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/phpDocumentor/phpDocumentor/master/data/xsd/phpdoc.xsd" > <title>💾 ZipStream-PHP</title> <paths> <output>docs</output> </paths> <version number="3.0.0"> <folder>latest</folder> <api> <source dsn="."> <path>src</path> </source> <output>api</output> <ignore hidden="true" symlinks="true"> <path>tests/**/*</path> <path>vendor/**/*</path> </ignore> <extensions> <extension>php</extension> </extensions> <visibility>public</visibility> <default-package-name>ZipStream</default-package-name> <include-source>true</include-source> </api> <guide> <source dsn="."> <path>guides</path> </source> <output>guide</output> </guide> </version> <setting name="guides.enabled" value="true"/> <template name="default" /> </phpdocumentor>