碎碎念
这篇笔记记录使用PHP实现单/多文件上传,涉及文件操作,上传方面的知识哦。
开始
php.ini的配置项
file_uploads = On//文件上传允许的开关upload_tmp_dir ="c:/wamp64/tmp"//临时上传目录upload_max_filesize = 2M//最大允许上传大小post_max_size = 8M//post接受的最大大小max_file_uploads = 20//最大允许上传数量
超全局变量$_FILES返回的数组内容(注意临时文件存放的key是tmp_name),其中key指的是input表单的name属性值。
Array([up] => Array([name] => 2020-04-15 下午1.33.43.png[type] => image/png[tmp_name] => /Applications/MAMP/tmp/php/php9dYVY9[error] => 0[size] => 1350112)[up1] => Array([name] => 2020-04-17 下午8.09.34.png[type] => image/png[tmp_name] => /Applications/MAMP/tmp/php/phpQ5vWzq[error] => 0[size] => 494639))
error有这么几种取值情况:

限制上传文件大小:通过HTML标签来限制上传文件的大小,否则如果在后端PHP上判断大小时,文件其实已经在服务器上了。(注意,这个隐藏域必须放在提交文件的上面) ```html
使用了这个隐藏域之后,可以在用户提交之后,文件上传之前就进行限制判断,超过限制,马上做出$_FILES['error'] = 2的错误。这样就可以避免等一个大文件传上服务器以后才发现超过限制了。这样既浪费了用户的表情,也浪费了我们的带宽。```php<?php你上面那个是判断出现错误情况下的,判断有没超过你定义的大小是返回错误为0的情况下进行判断。if($_FILES['file']['error']>0){switch($_FILES['file']['error']){case 1:echo "上传的文件超过了 php.ini 中7a64e78988e69d8331333337373638 upload_max_filesize 选项限制的值。";break;case 2:echo "上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。";break;case 3:echo "文件只有部分被上传。";break;case 4:echo "没有文件被上传。";break;default:echo "未知错误!";}exit;}else{if($_FILES['file']['size'] > 1000000){echo "上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。";exit;}}echo "上传成功";
- 移动临时文件的安全检测,PHP为此提供了两个函数
- is_uploaded_file($临时文件地址);
 - move_uploaded_file($要移动的文件, 新地址);
 
 多文件上传的优化:前端表单name字段,如果是多表单上传每次都必须制定不同的name?!此时可以把name指定为imgae[],返回的将是一个image多维数组,返回了多表单的数据。
最终代码
PHP实现单/多文件上传
<?phpclass FileUploadHandler{protected $uploadDir;public function make(): array{$this->makeDir();$uploadedFiles = [];$formatted_files = $this->format();foreach($formatted_files as $file){if ($file['error'] == 0 and is_uploaded_file($file['tmp_name'])){$target = $this->uploadDir.'/'.md5($file['name']).'.'.pathinfo($file['name'])['extension'];if (move_uploaded_file($file['tmp_name'], $target)){$uploadedFiles[] = ['name'=>$file['name'],'path'=>$target,'size'=>$file['size'],];}}}return $uploadedFiles;}// 创建上传目录private function makeDir(): bool{$path = 'dest/'.date('Y/m/d');$this->uploadDir = $path;return is_dir($path) or mkdir($path, 0755, true);}// 统一格式化文件private function format(): array{$files = [];foreach($_FILES as $file){if(is_array($file['name'])) {foreach($file['name'] as $idx=>$value){$files[] = ['name'=>$file['name'][$idx],'type'=>$file['type'][$idx],'tmp_name'=>$file['tmp_name'][$idx],'error'=>$file['error'][$idx],'size'=>$file['size'][$idx]];}} else {$files[] = $file;}}return $files;}}
