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