文件上传原轻松实现
文件上传原轻松实现
与原生麻烦的上传过程相比, 框架做了最大限度的简化,让上传操作更加的简单方便
上传文件
内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要安装额外的扩展。
假设表单代码如下:
<form action="/index/index/upload" enctype="multipart/form-data" method="post"> <input type="file" name="image" /> <br> <input type="submit" value="上传" /> </form>
然后在控制器中添加如下的代码:
public function upload(){ // 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 上传到本地服务器 $savename = \think\facade\Filesystem::putFile( 'topic', $file); }
$file变量是一个\think\File对象,你可以获取相关的文件信息,支持使用SplFileObject类的属性和方法。
多文件上传
如果你使用的是多文件上传表单,例如:
<form action="/index/index/upload" enctype="multipart/form-data" method="post"> <input type="file" name="image[]" /> <br> <input type="file" name="image[]" /> <br> <input type="file" name="image[]" /> <br> <input type="submit" value="上传" /> </form>
控制器代码可以改成:
public function upload(){ // 获取表单上传文件 $files = request()->file('image'); $savename = []; foreach($files as $file){ $savename[] = \think\facade\Filesystem::putFile( 'topic', $file); } }
上传验证
支持对上传文件的验证,包括文件大小、文件类型和后缀:
public function upload(){ // 获取表单上传文件 $files = request()->file(); try { validate(['image'=>'filesize:10240|fileExt:jpg|image:200,200,jpg']) ->check($files); $savename = []; foreach($files as $file) { $savename[] = \think\facade\Filesystem::putFile( 'topic', $file); } } catch (think\exception\ValidateException $e) { echo $e->getMessage(); } }
如果上传文件验证不通过,则move方法返回false。
验证参数 | 说明 |
---|---|
filesize | 上传文件的最大字节 |
fileExt | 文件后缀,多个用逗号分割或者数组 |
fileMime | 文件MIME类型,多个用逗号分隔或者数组 |
image | 验证图像文件的尺寸和类型 |
type | 文件MIME类型,多个用逗号分割或者数组 |
具体用法可以参考验证章节的内置规则-> 上传验证。
还有一个额外的自动验证规则是,如果上传的文件后缀是图像文件后缀,则会检查该文件是否是一个合法的图像文件。
上传错误提示信息支持多语言,你可以修改语言包来修改错误提示。
上传规则
默认情况下是上传到本地服务器,会在runtime/storage目录下面生成以当前日期为子目录,以微秒时间的md5编码为文件名的文件,例如上面生成的文件名可能是:
runtime/storage/topic//20160510/42a79759f284b767dfcb2a0197904287.jpg
如果是多应用的话,上传根目录默认是runtime/index/storage,如果你希望上传的文件是可以直接访问或者下载的话,可以使用public存储方式。
$savename = \think\facade\Filesystem::disk('public')->putFile( 'topic', $file);
你可以在config/filesystem.php配置文件中配置上传根目录及上传规则,例如:
return [ 'default' => 'local', 'disks' => [ 'local' => [ 'type' => 'local', 'root' => app()->getRuntimePath() . 'storage', ], 'public' => [ 'type' => 'local', 'root' => app()->getRootPath() . 'public/storage', 'url' => '/storage', 'visibility' => 'public', ], // 更多的磁盘配置信息 ], ];
我们可以指定上传文件的命名规则,使用rule方法即可,例如:
// 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 移动到服务器的上传目录 并且使用md5规则 $file->rule('md5')->move('../uploads/');
最终生成的文件名类似于:
application/uploads/72/ef580909368d824e899f77c7c98388.jpg
系统默认提供了几种上传命名规则,包括:
规则 | 描述 |
---|---|
date | 根据日期和微秒数生成 |
md5 | 对文件使用md5_file散列生成 |
sha1 | 对文件使用sha1_file散列生成 |
其中md5和sha1规则会自动以散列值的前两个字符作为子目录,后面的散列值作为文件名。
如果需要使用自定义命名规则,可以在rule方法中传入函数或者方法,例如:
// 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 移动到服务器的上传目录 并且使用uniqid规则 $file->rule('uniqid')->move('../uploads/');
生成的文件名类似于:
application/uploads/573d3b6d7abe2.jpg
如果你希望保留原文件名称,可以使用:
// 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 移动到服务器的上传目录 并且使用原文件名 $file->move('../uploads/','');
默认情况下,会覆盖服务器上传目录下的同名文件,如果不希望覆盖,可以使用:
// 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 移动到服务器的上传目录 并且设置不覆盖 $file->move('../uploads/',true,false);
获取文件hash散列值
可以获取上传文件的哈希散列值,例如:
// 获取表单上传文件 $file = request()->file('image'); // 移动到服务器的上传目录 并且使用原文件名 $upload = $file->move('/home/www/upload/'); // 获取上传文件的hash散列值 echo $upload->md5(); echo $upload->sha1();
可以统一使用hash方法获取文件散列值
// 获取表单上传文件 $file = request()->file('image'); // 移动到服务器的上传目录 并且使用原文件名 $upload = $file->move('/home/www/upload/'); // 获取上传文件的hash散列值 echo $upload->hash('sha1'); echo $upload->hash('md5');
返回对象
上传成功后返回的仍然是一个File对象,除了File对象自身的方法外,并且可以使用SplFileObject的属性和方法,便于进行后续的文件处理。