ContentLength.rst 2.3 KB

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