Yii2实现UploadedFile上传文件示例

时间:2022-03-25 01:41:50

闲来无事,整理了一下自己写的文件上传类。

通过

?
1
2
3
4
5
6
7
UploadFile::getInstance($model, $attribute);
 
UploadFile::getInstances($model, $attribute);
 
UploadFile::getInstanceByName($name);
 
UploadFile::getInstancesByName($name);

把表单上传的文件赋值到  UploadedFile中的  private static $_files  中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/**
   * Returns an uploaded file for the given model attribute.
   * The file should be uploaded using [[\yii\widgets\ActiveField::fileInput()]].
   * @param \yii\base\Model $model the data model
   * @param string $attribute the attribute name. The attribute name may contain array indexes.
   * For example, '[1]file' for tabular file uploading; and 'file[1]' for an element in a file array.
   * @return UploadedFile the instance of the uploaded file.
   * Null is returned if no file is uploaded for the specified model attribute.
   * @see getInstanceByName()
   */
  public static function getInstance($model, $attribute)
  {
    $name = Html::getInputName($model, $attribute);
    return static::getInstanceByName($name);
  }
 
  /**
   * Returns all uploaded files for the given model attribute.
   * @param \yii\base\Model $model the data model
   * @param string $attribute the attribute name. The attribute name may contain array indexes
   * for tabular file uploading, e.g. '[1]file'.
   * @return UploadedFile[] array of UploadedFile objects.
   * Empty array is returned if no available file was found for the given attribute.
   */
  public static function getInstances($model, $attribute)
  {
    $name = Html::getInputName($model, $attribute);
    return static::getInstancesByName($name);
  }
 
  /**
   * Returns an uploaded file according to the given file input name.
   * The name can be a plain string or a string like an array element (e.g. 'Post[imageFile]', or 'Post[0][imageFile]').
   * @param string $name the name of the file input field.
   * @return UploadedFile the instance of the uploaded file.
   * Null is returned if no file is uploaded for the specified name.
   */
  public static function getInstanceByName($name)
  {
    $files = self::loadFiles();
    return isset($files[$name]) ? $files[$name] : null;
  }
 
  /**
   * Returns an array of uploaded files corresponding to the specified file input name.
   * This is mainly used when multiple files were uploaded and saved as 'files[0]', 'files[1]',
   * 'files[n]'..., and you can retrieve them all by passing 'files' as the name.
   * @param string $name the name of the array of files
   * @return UploadedFile[] the array of UploadedFile objects. Empty array is returned
   * if no adequate upload was found. Please note that this array will contain
   * all files from all sub-arrays regardless how deeply nested they are.
   */
  public static function getInstancesByName($name)
  {
    $files = self::loadFiles();
    if (isset($files[$name])) {
      return [$files[$name]];
    }
    $results = [];
    foreach ($files as $key => $file) {
      if (strpos($key, "{$name}[") === 0) {
        $results[] = $file;
      }
    }
    return $results;
  }

loadFiles()方法,把$_FILES中的键值作为参数传递到loadFilesRecursive($key, $names, $tempNames, $types, $sizes, $errors) 中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
   * Creates UploadedFile instances from $_FILE.
   * @return array the UploadedFile instances
   */
  private static function loadFiles()
  {
    if (self::$_files === null) {
      self::$_files = [];
      if (isset($_FILES) && is_array($_FILES)) {
        foreach ($_FILES as $class => $info) {
          self::loadFilesRecursive($class, $info['name'], $info['tmp_name'], $info['type'], $info['size'], $info['error']);
        }
      }
    }
    return self::$_files;
  }

loadFilesRecursive方法,通过递归把$_FILES中的内容保存到  self::$_files 中

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
   * Creates UploadedFile instances from $_FILE recursively.
   * @param string $key key for identifying uploaded file: class name and sub-array indexes
   * @param mixed $names file names provided by PHP
   * @param mixed $tempNames temporary file names provided by PHP
   * @param mixed $types file types provided by PHP
   * @param mixed $sizes file sizes provided by PHP
   * @param mixed $errors uploading issues provided by PHP
   */
  private static function loadFilesRecursive($key, $names, $tempNames, $types, $sizes, $errors)
  {
    if (is_array($names)) {
      foreach ($names as $i => $name) {
        self::loadFilesRecursive($key . '[' . $i . ']', $name, $tempNames[$i], $types[$i], $sizes[$i], $errors[$i]);
      }
    } elseif ($errors !== UPLOAD_ERR_NO_FILE) {
      self::$_files[$key] = new static([
        'name' => $names,
        'tempName' => $tempNames,
        'type' => $types,
        'size' => $sizes,
        'error' => $errors,
      ]);
    }
  }

实例:

html

?
1
2
3
4
5
<form class="form-horizontal form-margin50" action="<?= \yii\helpers\Url::toRoute('upload-face') ?>"
          method="post" enctype="multipart/form-data" id="form1">
         <input type="hidden" name="_csrf" value="<?= Yii::$app->request->getCsrfToken() ?>">
         <input type="file" name="head_pic" id="doc" style="display: none" onchange="setImagePreview()"/>
 </form>

php代码,打印的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static function uploadImage($userId = '', $tem = '')
  {
    $returnPath = '';
    $path = 'uploads/headpic/' . $userId;
    if (!file_exists($path)) {
      mkdir($path, 0777);
      chmod($path, 0777);
    }
 
    $patch = $path . '/' . date("YmdHis") . '_';
    $tmp = UploadedFile::getInstanceByName('head_pic');
    if ($tmp) {
      $patch = $path . '/' . date("YmdHis") . '_';
      $tmp->saveAs($patch . '1.jpg');
      $returnPath .= $patch;
    }
 
    return $returnPath;
  }

打印dump($tmp,$_FILES,$tmp->getExtension());

Yii2实现UploadedFile上传文件示例

对应的 UploadedFile

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
class UploadedFile extends Object
{
  /**
   * @var string the original name of the file being uploaded
   */
  // "Chrysanthemum.jpg"
  public $name;
  /**
   * @var string the path of the uploaded file on the server.
   * Note, this is a temporary file which will be automatically deleted by PHP
   * after the current request is processed.
   */
  // "C:\Windows\Temp\php8CEF.tmp"
  public $tempName;
  /**
   * @var string the MIME-type of the uploaded file (such as "image/gif").
   * Since this MIME type is not checked on the server-side, do not take this value for granted.
   * Instead, use [[\yii\helpers\FileHelper::getMimeType()]] to determine the exact MIME type.
   */
  // "image/jpeg"
  public $type;
  /**
   * @var integer the actual size of the uploaded file in bytes
   */
  // 879394
  public $size;
  /**
   * @var integer an error code describing the status of this file uploading.
   * @see http://www.php.net/manual/en/features.file-upload.errors.php
   */
  // 0
  public $error;
 
  private static $_files;
 
 
  /**
   * String output.
   * This is PHP magic method that returns string representation of an object.
   * The implementation here returns the uploaded file's name.
   * @return string the string representation of the object
   */
  public function __toString()
  {
    return $this->name;
  }
 
  /**
   * Returns an uploaded file for the given model attribute.
   * The file should be uploaded using [[\yii\widgets\ActiveField::fileInput()]].
   * @param \yii\base\Model $model the data model
   * @param string $attribute the attribute name. The attribute name may contain array indexes.
   * For example, '[1]file' for tabular file uploading; and 'file[1]' for an element in a file array.
   * @return UploadedFile the instance of the uploaded file.
   * Null is returned if no file is uploaded for the specified model attribute.
   * @see getInstanceByName()
   */
  public static function getInstance($model, $attribute)
  {
    $name = Html::getInputName($model, $attribute);
    return static::getInstanceByName($name);
  }
 
  /**
   * Returns all uploaded files for the given model attribute.
   * @param \yii\base\Model $model the data model
   * @param string $attribute the attribute name. The attribute name may contain array indexes
   * for tabular file uploading, e.g. '[1]file'.
   * @return UploadedFile[] array of UploadedFile objects.
   * Empty array is returned if no available file was found for the given attribute.
   */
  public static function getInstances($model, $attribute)
  {
    $name = Html::getInputName($model, $attribute);
    return static::getInstancesByName($name);
  }
 
  /**
   * Returns an uploaded file according to the given file input name.
   * The name can be a plain string or a string like an array element (e.g. 'Post[imageFile]', or 'Post[0][imageFile]').
   * @param string $name the name of the file input field.
   * @return null|UploadedFile the instance of the uploaded file.
   * Null is returned if no file is uploaded for the specified name.
   */
  public static function getInstanceByName($name)
  {
    $files = self::loadFiles();
    return isset($files[$name]) ? new static($files[$name]) : null;
  }
 
  /**
   * Returns an array of uploaded files corresponding to the specified file input name.
   * This is mainly used when multiple files were uploaded and saved as 'files[0]', 'files[1]',
   * 'files[n]'..., and you can retrieve them all by passing 'files' as the name.
   * @param string $name the name of the array of files
   * @return UploadedFile[] the array of UploadedFile objects. Empty array is returned
   * if no adequate upload was found. Please note that this array will contain
   * all files from all sub-arrays regardless how deeply nested they are.
   */
  public static function getInstancesByName($name)
  {
    $files = self::loadFiles();
    if (isset($files[$name])) {
      return [new static($files[$name])];
    }
    $results = [];
    foreach ($files as $key => $file) {
      if (strpos($key, "{$name}[") === 0) {
        $results[] = new static($file);
      }
    }
    return $results;
  }
 
  /**
   * Cleans up the loaded UploadedFile instances.
   * This method is mainly used by test scripts to set up a fixture.
   */
  //清空self::$_files
  public static function reset()
  {
    self::$_files = null;
  }
 
  /**
   * Saves the uploaded file.
   * Note that this method uses php's move_uploaded_file() method. If the target file `$file`
   * already exists, it will be overwritten.
   * @param string $file the file path used to save the uploaded file
   * @param boolean $deleteTempFile whether to delete the temporary file after saving.
   * If true, you will not be able to save the uploaded file again in the current request.
   * @return boolean true whether the file is saved successfully
   * @see error
   */
  //通过php的move_uploaded_file() 方法保存临时文件为目标文件
  public function saveAs($file, $deleteTempFile = true)
  {
    //$this->error == UPLOAD_ERR_OK UPLOAD_ERR_OK 其值为 0,没有错误发生,文件上传成功。
    if ($this->error == UPLOAD_ERR_OK) {
      if ($deleteTempFile) {
        //将上传的文件移动到新位置
        return move_uploaded_file($this->tempName, $file);
      } elseif (is_uploaded_file($this->tempName)) {//判断文件是否是通过 HTTP POST 上传的
        return copy($this->tempName, $file);//copy — 拷贝文件
      }
    }
    return false;
  }
 
  /**
   * @return string original file base name
   */
  //获取上传文件原始名称 "name" => "Chrysanthemum.jpg" "Chrysanthemum"
  public function getBaseName()
  {
    // https://github.com/yiisoft/yii2/issues/11012
    $pathInfo = pathinfo('_' . $this->name, PATHINFO_FILENAME);
    return mb_substr($pathInfo, 1, mb_strlen($pathInfo, '8bit'), '8bit');
  }
 
  /**
   * @return string file extension
   */
  //获取上传文件扩展名称 "name" => "Chrysanthemum.jpg" "jpg"
  public function getExtension()
  {
    return strtolower(pathinfo($this->name, PATHINFO_EXTENSION));
  }
 
  /**
   * @return boolean whether there is an error with the uploaded file.
   * Check [[error]] for detailed error code information.
   */
  //上传文件是否出现错误
  public function getHasError()
  {
    return $this->error != UPLOAD_ERR_OK;
  }
 
  /**
   * Creates UploadedFile instances from $_FILE.
   * @return array the UploadedFile instances
   */
  private static function loadFiles()
  {
    if (self::$_files === null) {
      self::$_files = [];
      if (isset($_FILES) && is_array($_FILES)) {
        foreach ($_FILES as $class => $info) {
          self::loadFilesRecursive($class, $info['name'], $info['tmp_name'], $info['type'], $info['size'], $info['error']);
        }
      }
    }
    return self::$_files;
  }
 
  /**
   * Creates UploadedFile instances from $_FILE recursively.
   * @param string $key key for identifying uploaded file: class name and sub-array indexes
   * @param mixed $names file names provided by PHP
   * @param mixed $tempNames temporary file names provided by PHP
   * @param mixed $types file types provided by PHP
   * @param mixed $sizes file sizes provided by PHP
   * @param mixed $errors uploading issues provided by PHP
   */
  private static function loadFilesRecursive($key, $names, $tempNames, $types, $sizes, $errors)
  {
    if (is_array($names)) {
      foreach ($names as $i => $name) {
        self::loadFilesRecursive($key . '[' . $i . ']', $name, $tempNames[$i], $types[$i], $sizes[$i], $errors[$i]);
      }
    } elseif ((int)$errors !== UPLOAD_ERR_NO_FILE) {
      self::$_files[$key] = [
        'name' => $names,
        'tempName' => $tempNames,
        'type' => $types,
        'size' => $sizes,
        'error' => $errors,
      ];
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。