UploadedFile.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. namespace Yurun\Util\YurunHttp\Http\Psr7;
  3. use Psr\Http\Message\StreamInterface;
  4. use Psr\Http\Message\UploadedFileInterface;
  5. use Yurun\Util\YurunHttp\Stream\FileStream;
  6. class UploadedFile implements UploadedFileInterface
  7. {
  8. /**
  9. * 文件在客户端时的文件名.
  10. *
  11. * @var string
  12. */
  13. protected $fileName;
  14. /**
  15. * 文件mime类型.
  16. *
  17. * @var string
  18. */
  19. protected $mediaType;
  20. /**
  21. * 临时文件名.
  22. *
  23. * @var string
  24. */
  25. protected $tmpFileName;
  26. /**
  27. * 文件大小,单位:字节
  28. *
  29. * @var int
  30. */
  31. protected $size;
  32. /**
  33. * 错误码
  34. *
  35. * @var int
  36. */
  37. protected $error;
  38. /**
  39. * 文件流
  40. *
  41. * @var \Yurun\Util\YurunHttp\Stream\FileStream
  42. */
  43. protected $stream;
  44. /**
  45. * 文件是否被移动过.
  46. *
  47. * @var bool
  48. */
  49. protected $isMoved = false;
  50. /**
  51. * @param string $fileName
  52. * @param string $mediaType
  53. * @param string $tmpFileName
  54. * @param int $size
  55. * @param int $error
  56. */
  57. public function __construct($fileName, $mediaType, $tmpFileName, $size = null, $error = 0)
  58. {
  59. $this->fileName = $fileName;
  60. $this->mediaType = $mediaType;
  61. $this->tmpFileName = $tmpFileName;
  62. if (null === $size)
  63. {
  64. $this->size = filesize($tmpFileName);
  65. }
  66. else
  67. {
  68. $this->size = $size;
  69. }
  70. $this->error = $error;
  71. }
  72. /**
  73. * Retrieve a stream representing the uploaded file.
  74. *
  75. * This method MUST return a StreamInterface instance, representing the
  76. * uploaded file. The purpose of this method is to allow utilizing native PHP
  77. * stream functionality to manipulate the file upload, such as
  78. * stream_copy_to_stream() (though the result will need to be decorated in a
  79. * native PHP stream wrapper to work with such functions).
  80. *
  81. * If the moveTo() method has been called previously, this method MUST raise
  82. * an exception.
  83. *
  84. * @return StreamInterface stream representation of the uploaded file
  85. *
  86. * @throws \RuntimeException in cases when no stream is available or can be
  87. * created
  88. */
  89. public function getStream()
  90. {
  91. if (null === $this->stream)
  92. {
  93. $this->stream = new FileStream($this->tmpFileName);
  94. }
  95. return $this->stream;
  96. }
  97. /**
  98. * Move the uploaded file to a new location.
  99. *
  100. * Use this method as an alternative to move_uploaded_file(). This method is
  101. * guaranteed to work in both SAPI and non-SAPI environments.
  102. * Implementations must determine which environment they are in, and use the
  103. * appropriate method (move_uploaded_file(), rename(), or a stream
  104. * operation) to perform the operation.
  105. *
  106. * $targetPath may be an absolute path, or a relative path. If it is a
  107. * relative path, resolution should be the same as used by PHP's rename()
  108. * function.
  109. *
  110. * The original file or stream MUST be removed on completion.
  111. *
  112. * If this method is called more than once, any subsequent calls MUST raise
  113. * an exception.
  114. *
  115. * When used in an SAPI environment where $_FILES is populated, when writing
  116. * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be
  117. * used to ensure permissions and upload status are verified correctly.
  118. *
  119. * If you wish to move to a stream, use getStream(), as SAPI operations
  120. * cannot guarantee writing to stream destinations.
  121. *
  122. * @see http://php.net/is_uploaded_file
  123. * @see http://php.net/move_uploaded_file
  124. *
  125. * @param string $targetPath path to which to move the uploaded file
  126. *
  127. * @return void
  128. *
  129. * @throws \InvalidArgumentException if the $path specified is invalid
  130. * @throws \RuntimeException on any error during the move operation, or on
  131. * the second or subsequent call to the method
  132. */
  133. public function moveTo($targetPath)
  134. {
  135. if (!\is_string($targetPath))
  136. {
  137. throw new \InvalidArgumentException('targetPath specified is invalid');
  138. }
  139. if ($this->isMoved)
  140. {
  141. throw new \RuntimeException('file can not be moved');
  142. }
  143. if (is_uploaded_file($this->tmpFileName))
  144. {
  145. $this->isMoved = move_uploaded_file($this->tmpFileName, $targetPath);
  146. }
  147. else
  148. {
  149. $this->isMoved = rename($this->tmpFileName, $targetPath);
  150. }
  151. if (!$this->isMoved)
  152. {
  153. throw new \RuntimeException(sprintf('file %s move to %s fail', $this->tmpFileName, $targetPath));
  154. }
  155. }
  156. /**
  157. * Retrieve the file size.
  158. *
  159. * Implementations SHOULD return the value stored in the "size" key of
  160. * the file in the $_FILES array if available, as PHP calculates this based
  161. * on the actual size transmitted.
  162. *
  163. * @return int|null the file size in bytes or null if unknown
  164. */
  165. public function getSize()
  166. {
  167. return $this->size;
  168. }
  169. /**
  170. * Retrieve the error associated with the uploaded file.
  171. *
  172. * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants.
  173. *
  174. * If the file was uploaded successfully, this method MUST return
  175. * UPLOAD_ERR_OK.
  176. *
  177. * Implementations SHOULD return the value stored in the "error" key of
  178. * the file in the $_FILES array.
  179. *
  180. * @see http://php.net/manual/en/features.file-upload.errors.php
  181. *
  182. * @return int one of PHP's UPLOAD_ERR_XXX constants
  183. */
  184. public function getError()
  185. {
  186. return $this->error;
  187. }
  188. /**
  189. * Retrieve the filename sent by the client.
  190. *
  191. * Do not trust the value returned by this method. A client could send
  192. * a malicious filename with the intention to corrupt or hack your
  193. * application.
  194. *
  195. * Implementations SHOULD return the value stored in the "name" key of
  196. * the file in the $_FILES array.
  197. *
  198. * @return string|null the filename sent by the client or null if none
  199. * was provided
  200. */
  201. public function getClientFilename()
  202. {
  203. return $this->fileName;
  204. }
  205. /**
  206. * Retrieve the media type sent by the client.
  207. *
  208. * Do not trust the value returned by this method. A client could send
  209. * a malicious media type with the intention to corrupt or hack your
  210. * application.
  211. *
  212. * Implementations SHOULD return the value stored in the "type" key of
  213. * the file in the $_FILES array.
  214. *
  215. * @return string|null the media type sent by the client or null if none
  216. * was provided
  217. */
  218. public function getClientMediaType()
  219. {
  220. return $this->mediaType;
  221. }
  222. /**
  223. * 获取上传文件的临时文件路径.
  224. *
  225. * @return string
  226. */
  227. public function getTempFileName()
  228. {
  229. return $this->tmpFileName;
  230. }
  231. }