ZipStreamWrapper.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. class PHPExcel_Shared_ZipStreamWrapper
  8. {
  9. /**
  10. * Internal ZipAcrhive
  11. *
  12. * @var ZipArchive
  13. */
  14. private $archive;
  15. /**
  16. * Filename in ZipAcrhive
  17. *
  18. * @var string
  19. */
  20. private $fileNameInArchive = '';
  21. /**
  22. * Position in file
  23. *
  24. * @var int
  25. */
  26. private $position = 0;
  27. /**
  28. * Data
  29. *
  30. * @var mixed
  31. */
  32. private $data = '';
  33. /**
  34. * Register wrapper
  35. */
  36. public static function register()
  37. {
  38. @stream_wrapper_unregister('zip');
  39. @stream_wrapper_register('zip', __CLASS__);
  40. }
  41. /**
  42. * Implements support for fopen().
  43. *
  44. * @param string $path resource name including scheme, e.g.
  45. * @param string $mode only "r" is supported
  46. * @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH
  47. * @param string &$openedPath absolute path of the opened stream (out parameter)
  48. * @return bool true on success
  49. */
  50. public function stream_open($path, $mode, $options, &$opened_path)
  51. {
  52. // Check for mode
  53. if ($mode{0} != 'r') {
  54. throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.');
  55. }
  56. $pos = strrpos($path, '#');
  57. $url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://')
  58. $url['fragment'] = substr($path, $pos + 1);
  59. // Open archive
  60. $this->archive = new ZipArchive();
  61. $this->archive->open($url['host']);
  62. $this->fileNameInArchive = $url['fragment'];
  63. $this->position = 0;
  64. $this->data = $this->archive->getFromName($this->fileNameInArchive);
  65. return true;
  66. }
  67. /**
  68. * Implements support for fstat().
  69. *
  70. * @return boolean
  71. */
  72. public function statName()
  73. {
  74. return $this->fileNameInArchive;
  75. }
  76. /**
  77. * Implements support for fstat().
  78. *
  79. * @return boolean
  80. */
  81. public function url_stat()
  82. {
  83. return $this->statName($this->fileNameInArchive);
  84. }
  85. /**
  86. * Implements support for fstat().
  87. *
  88. * @return boolean
  89. */
  90. public function stream_stat()
  91. {
  92. return $this->archive->statName($this->fileNameInArchive);
  93. }
  94. /**
  95. * Implements support for fread(), fgets() etc.
  96. *
  97. * @param int $count maximum number of bytes to read
  98. * @return string
  99. */
  100. public function stream_read($count)
  101. {
  102. $ret = substr($this->data, $this->position, $count);
  103. $this->position += strlen($ret);
  104. return $ret;
  105. }
  106. /**
  107. * Returns the position of the file pointer, i.e. its offset into the file
  108. * stream. Implements support for ftell().
  109. *
  110. * @return int
  111. */
  112. public function stream_tell()
  113. {
  114. return $this->position;
  115. }
  116. /**
  117. * EOF stream
  118. *
  119. * @return bool
  120. */
  121. public function stream_eof()
  122. {
  123. return $this->position >= strlen($this->data);
  124. }
  125. /**
  126. * Seek stream
  127. *
  128. * @param int $offset byte offset
  129. * @param int $whence SEEK_SET, SEEK_CUR or SEEK_END
  130. * @return bool
  131. */
  132. public function stream_seek($offset, $whence)
  133. {
  134. switch ($whence) {
  135. case SEEK_SET:
  136. if ($offset < strlen($this->data) && $offset >= 0) {
  137. $this->position = $offset;
  138. return true;
  139. } else {
  140. return false;
  141. }
  142. break;
  143. case SEEK_CUR:
  144. if ($offset >= 0) {
  145. $this->position += $offset;
  146. return true;
  147. } else {
  148. return false;
  149. }
  150. break;
  151. case SEEK_END:
  152. if (strlen($this->data) + $offset >= 0) {
  153. $this->position = strlen($this->data) + $offset;
  154. return true;
  155. } else {
  156. return false;
  157. }
  158. break;
  159. default:
  160. return false;
  161. }
  162. }
  163. }