You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
5.2 KiB

  1. <?php
  2. /*
  3. * The MIT License
  4. *
  5. * Copyright 2019 Blobt.
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. namespace iron\actions;
  26. use yii\base\Action;
  27. use Yii;
  28. use yii\base\Exception;
  29. use yii\web\Response;
  30. use yii\web\UploadedFile;
  31. /***
  32. * @author iron <weiriron@gmail.com>
  33. * @created Sep 11, 2019
  34. */
  35. class UploadAction extends Action
  36. {
  37. /**
  38. * 常量:表单数据类型
  39. */
  40. const DATA_TYPE_FORM = 1;
  41. /**
  42. * 常量: 二进制数据类型
  43. */
  44. const DATA_TYPE_BINARY = 2;
  45. /**
  46. * @var integer 限制的最大尺寸
  47. */
  48. public $maxSize;
  49. /**
  50. * @var array 允许的文件类型(扩展名)
  51. */
  52. public $allowType;
  53. /**
  54. * @var string 文件保存路径
  55. */
  56. public $path;
  57. /**
  58. * @var string 数据类型
  59. */
  60. public $dataType;
  61. /**
  62. * @var bool 是否随机文件名(默认为随机,推荐为随机避免中文文件名导致的问题)
  63. */
  64. public $randName = true;
  65. /**
  66. * @var integer 默认单次最大上传数量(1-20
  67. */
  68. public $maxCount;
  69. public function init()
  70. {
  71. if ($this->maxSize === null) {
  72. $this->maxSize = 2048;//默认最大尺寸为2M
  73. }
  74. if ($this->allowType === null) {
  75. $this->allowType = ['*'];//默认允许任何图片类型
  76. }
  77. if ($this->maxCount === null) {
  78. $this->maxCount = 5;//默认单次最大上传数量为5
  79. }
  80. if ($this->dataType === null) {
  81. $this->dataType = self::DATA_TYPE_FORM;//默认上传数据类型为表单数据
  82. }
  83. }
  84. public function run()
  85. {
  86. Yii::$app->response->format = Response::FORMAT_JSON;
  87. $data = [];
  88. d(Yii::$app->request->post());exit;
  89. if ($this->dataType == self::DATA_TYPE_FORM) {
  90. $files = UploadedFile::getInstancesByName('files');
  91. } else {
  92. //TODO 非表单类型的文件上传
  93. $files = [];
  94. }
  95. try {
  96. foreach ($files as $file) {
  97. $this->checkType($file->extension);
  98. $this->checkSize($file->size);
  99. $savePath = $this->getSavePath();
  100. $fileName = $this->getFileName($file->baseName);
  101. $filePath = "$savePath/$fileName.{$file->extension}";
  102. $file->saveAs($filePath);
  103. $data[] = ["uploads/$this->path/$fileName.{$file->extension}"];
  104. }
  105. return ['status' => true, 'paths' => $data];
  106. } catch (\Exception $e) {
  107. return ['status' => false, 'info' => $e->getMessage()];
  108. }
  109. }
  110. /**
  111. * 检查文件类型是否允许上传
  112. * @param $extension 文件扩展名
  113. * @return bool
  114. * @throws Exception
  115. */
  116. protected function checkType($extension)
  117. {
  118. if (in_array('*', $this->allowType)) {
  119. return true;
  120. }
  121. if (!in_array($extension, $this->allowType)) {
  122. throw new Exception("类型【{$extension}】不被允许,请在配置项中添加该类型");
  123. }
  124. }
  125. /**
  126. * 检查文件尺寸是否超过最大允许上传尺寸
  127. * @param $size 文件尺寸
  128. * @throws Exception
  129. */
  130. protected function checkSize($size)
  131. {
  132. if ($size/1024 > $this->maxSize) {
  133. throw new Exception("文件大于允许的最大尺寸【{$this->maxSize}】,请修改配置或压缩文件");
  134. }
  135. }
  136. /**
  137. * 获取文件保存路径并创建文件夹
  138. * @return string 文件保存的完成路径
  139. */
  140. protected function getSavePath()
  141. {
  142. $dirs = explode('/', $this->path);
  143. $savePath = Yii::getAlias('@app').'/web/uploads';
  144. if (!is_dir($savePath)) {
  145. mkdir($savePath, 755);
  146. }
  147. foreach ($dirs as $dir) {
  148. $savePath .= "/{$dir}";
  149. if (!is_dir($savePath)) {
  150. mkdir($savePath, 755);
  151. }
  152. }
  153. return $savePath;
  154. }
  155. /**
  156. * 利用时间戳加随机数构建新文件名
  157. * @param $originName 源文件名
  158. * @return string
  159. */
  160. //TODO 利用原文件名生成新文件名
  161. protected function getFileName($originName)
  162. {
  163. return time() . rand(0, 9999);
  164. }
  165. }