79 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			79 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| Adding Content-Length header
 | |
| =============
 | |
| 
 | |
| Adding a ``Content-Length`` header for ``ZipStream`` is not trivial since the
 | |
| size is not known beforehand.
 | |
| 
 | |
| The following workaround adds an approximated header:
 | |
| 
 | |
| .. code-block:: php
 | |
| 
 | |
|     class Zip
 | |
|     {
 | |
|         /** @var string */
 | |
|         private $name;
 | |
| 
 | |
|         private $files = [];
 | |
| 
 | |
|         public function __construct($name)
 | |
|         {
 | |
|             $this->name = $name;
 | |
|         }
 | |
| 
 | |
|         public function addFile($name, $data)
 | |
|         {
 | |
|             $this->files[] = ['type' => 'addFile', 'name' => $name, 'data' => $data];
 | |
|         }
 | |
| 
 | |
|         public function addFileFromPath($name, $path)
 | |
|         {
 | |
|             $this->files[] = ['type' => 'addFileFromPath', 'name' => $name, 'path' => $path];
 | |
|         }
 | |
| 
 | |
|         public function getEstimate()
 | |
|         {
 | |
|             $estimate = 22;
 | |
|             foreach ($this->files as $file) {
 | |
|             $estimate += 76 + 2 * strlen($file['name']);
 | |
|             if ($file['type'] === 'addFile') {
 | |
|                 $estimate += strlen($file['data']);
 | |
|             }
 | |
|             if ($file['type'] === 'addFileFromPath') {
 | |
|                 $estimate += filesize($file['path']);
 | |
|             }
 | |
|             }
 | |
|             return $estimate;
 | |
|         }
 | |
| 
 | |
|         public function finish()
 | |
|         {
 | |
|             header('Content-Length: ' . $this->getEstimate());
 | |
|             $options = new \ZipStream\Option\Archive();
 | |
|             $options->setSendHttpHeaders(true);
 | |
|             $options->setEnableZip64(false);
 | |
|             $options->setDeflateLevel(-1);
 | |
|             $zip = new \ZipStream\ZipStream($this->name, $options);
 | |
| 
 | |
|             $fileOptions = new \ZipStream\Option\File();
 | |
|             $fileOptions->setMethod(\ZipStream\Option\Method::STORE());
 | |
|             foreach ($this->files as $file) {
 | |
|             if ($file['type'] === 'addFile') {
 | |
|                 $zip->addFile($file['name'], $file['data'], $fileOptions);
 | |
|             }
 | |
|             if ($file['type'] === 'addFileFromPath') {
 | |
|                 $zip->addFileFromPath($file['name'], $file['path'], $fileOptions);
 | |
|             }
 | |
|             }
 | |
|             $zip->finish();
 | |
|             exit;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| It only works with the following constraints:
 | |
| 
 | |
| - All file content is known beforehand.
 | |
| - Content Deflation is disabled
 | |
| 
 | |
| Thanks to
 | |
| `partiellkorrekt <https://github.com/maennchen/ZipStream-PHP/issues/89#issuecomment-1047949274>`_
 | |
| for this workaround. | 
