框架上传功能
上传文件
内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要自己扩展。
假设表单代码如下:
<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‘);
// 移动到框架应用根目录/uploads/ 目录下
$info = $file->move( ‘../uploads‘);
if($info){
// 成功上传后 获取上传信息
// 输出 jpg
echo $info->getExtension();
// 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
echo $info->getSaveName();
// 输出 42a79759f284b767dfcb2a0197904287.jpg
echo $info->getFilename();
}else{
// 上传失败获取错误信息
echo $file->getError();
}
}
move
方法成功的话返回的是一个\think\File
对象,你可以对上传后的文件进行后续操作。
多文件上传
如果你使用的是多文件上传表单,例如:
<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‘);
foreach($files as $file){
// 移动到框架应用根目录/uploads/ 目录下
$info = $file->move( ‘../uploads‘);
if($info){
// 成功上传后 获取上传信息
// 输出 jpg
echo $info->getExtension();
// 输出 42a79759f284b767dfcb2a0197904287.jpg
echo $info->getFilename();
}else{
// 上传失败获取错误信息
echo $file->getError();
}
}
}
上传验证
支持对上传文件的验证,包括文件大小、文件类型和后缀:
public function upload(){
// 获取表单上传文件 例如上传了001.jpg
$file = request()->file(‘image‘);
// 移动到框架应用根目录/uploads/ 目录下
$info = $file->validate([‘size‘=>15678,‘ext‘=>‘jpg,png,gif‘])->move( ‘../uploads‘);
if($info){
// 成功上传后 获取上传信息
// 输出 jpg
echo $info->getExtension();
// 输出 20160820/42a79759f284b767dfcb2a0197904287.jpg
echo $info->getSaveName();
// 输出 42a79759f284b767dfcb2a0197904287.jpg
echo $info->getFilename();
}else{
// 上传失败获取错误信息
echo $file->getError();
}
}
getSaveName
方法返回的是图片的服务器文件地址,并不能直接用于图片的URL地址,尤其在windows平台上必须做转换才能正常显示图片。
如果上传文件验证不通过,则move
方法返回false。
验证参数 | 说明 |
---|---|
size | 上传文件的最大字节 |
ext | 文件后缀,多个用逗号分割或者数组 |
type | 文件MIME类型,多个用逗号分割或者数组 |
还有一个额外的自动验证规则是,如果上传的文件后缀是图像文件后缀,则会检查该文件是否是一个合法的图像文件。
上传错误提示信息支持多语言,你可以修改语言包来修改错误提示。
上传规则
默认情况下,会在上传目录下面生成以当前日期为子目录,以微秒时间的md5
编码为文件名的文件,例如上面生成的文件名可能是:
/home/www/uploads/20160510/42a79759f284b767dfcb2a0197904287.jpg
我们可以指定上传文件的命名规则,使用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
的属性和方法,便于进行后续的文件处理。
webuploader 无刷新上传前端组件上传
官网:http://fex.baidu.com/webuploader/
简介
结合tp5.1的上传demo
例
文件上传并回显到页面
视图文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>文件上传</title>
<!--引入CSS-->
<link rel="stylesheet" type="text/css" href="/static/webuploader/css/webuploader.css">
<!--引入jquery-->
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
<!--引入JS-->
<script type="text/javascript" src="/static/webuploader/jekyll/js/webuploader.js"></script>
</head>
<body>
<img src="#" id="avatar" style="width:200px ;display:none" >
<div id="picker">选择文件</div>
<script>
var token = ‘{:token()}‘;
var uploader = WebUploader.create({
// 选完文件后,是否自动上传。
auto: true,
// swf文件路径
swf: ‘/static/webuploader/jekyll/js/Uploader.swf‘,
// 文件接收服务端。
server: ‘{:url("uploadSubmit")}‘,
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: ‘#picker‘,
//设置文件上传域的name
fileVal: ‘pic‘,
//传递请求的额外参数
formData: {
‘__token__‘: token,
},
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: false
});
//回调事件
uploader.on( ‘uploadSuccess‘, function( $file,response ){
console.log(arguments);
if(response.static == 0){
$(‘#avatar‘).attr(‘src‘, response.msg).show();
}
});
</script>
</body>
</html>
控制器
<?php
namespace app\admin\controller;
use think\Controller;
use think\Request;
class Upload extends Controller
{
//上传界面
public function index(){
return view(‘admin@/upload/index‘);
}
//上传处理
public function upload(Request $request){
//dump($request->file());
$file = $request->file(‘pic‘);
// 移动到框架应用根目录/uploads/ 目录下
$info = $file->move( ‘./uploads‘);
if($info){
$savename = ‘/uploads/‘.str_replace(‘\\‘,‘/‘, $info->getSaveName());
//$savename = ‘1111‘;
return json([‘static‘ => 0, ‘msg‘ => $savename]);
}
return json([‘static‘ => 1, ‘msg‘ => $file->getError()]);
}
}
路由
<?php
use \think\facade\Route;
Route::group(‘admin‘, function (){
//文件上传界面
Route::get(‘upload‘, ‘@admin/upload/index‘)->name(‘upload‘);
//服务器端文件接收
Route::post(‘uploadSubmit‘, ‘@admin/upload/upload‘)->name(‘uploadSubmit‘);
});
运行效果