上传文件
内置的上传只是上传到本地服务器,上传到远程或者第三方平台的话需要安装额外的扩展。
假设表单代码如下:
<form action="/index/upload" enctype="multipart/form-data" method="post"> <input type="file" name="image" /> <input type="submit" value="上传" /> </form>
注意,要使用上传功能 你的表单需要设置 enctype=”multipart/form-data”
然后在控制器中添加如下的代码:
<?php namespace app\controller; use app\BaseController; use think\facade\View; use think\facade\Db; // 请求门面类 use think\facade\Request; // 文件上传门面类 use think\facade\Filesystem; class Code extends BaseController { // 上传页面 public function index() { return View::fetch(); } // 上传文件方法 public function upload(){ // 获取表单上传文件 例如上传了001.jpg $file = request()->file('image'); // 上传到本地服务器 $savename = Filesystem::putFile( 'topic', $file); if($savename){ echo "文件上传成功"; }else{ echo '文件上传失败'; } } }?>
$file
变量是一个\think\File
对象,你可以获取相关的文件信息,支持使用SplFileObject
类的属性和方法。
默认情况下是上传到本地服务器,会在runtime/storage
目录下面生成以当前日期为子目录,以微秒时间的md5编码为文件名的文件
要使用请求对象必须使用门面方式(
think\facade\Request类负责
)调用可以通过Request对象完成全局输入变量的检测、获取和安全过滤
支持$_GET、$_POST、$_REQUEST、$_SERVER、$_SESSION、$_COOKIE、$_ENV等系统变量,以及文件上传信息
Request请求对象大全
系统级助手函数
获取当前系统参数
// 获取当前域名echo '获取当前域名:'.$request->domain();// 获取当前入口文件echo '获取当前入口文件:'.$request->baseFile();// 获取当前URL地址,不含域名echo '获取当前URL地址,不含域名:'.$request->url();// 获取包含域名的完整url地址echo '获取包含域名的完整url地址:'.$request->url(true);// 获取URL地址 不含QUERY_STRINGecho '获取URL地址 不含QUERY_STRING:'.$request->baseurl();// 获取URL访问的ROOT地址echo '获取URL访问的ROOT地址:'.$request->root();// 获取URL访问的ROOT地址echo '获取URL访问的ROOT地址 :'.$request->root(true);// 获取URL地址中的 PATH_INFO 信息echo '获取URL地址中的 PATH_INFO 信息:'.$request->pathinfo();// 获取URL地址中的 PATH_INFO 信息,不含后缀echo '获取URL地址中的 PATH_INFO 信息,不含后缀:'.$request->path();// 获取URL地址中的后缀信息echo '获取URL地址中的后缀信息:'.$request->ext();
获取请求的参数
echo '请求方法:'.$request->method();echo '资源类型:'.$request->type();echo '访问ip:'.$request->ip();echo '是否为ajax请求:'.var_export($request->isAjax(), true);echo '请求参数:';dump($request->param());echo '请求参数:仅包含name';dump($request->only(['name']));echo '请求参数:排除name';dump($request->except(['name']));
获取get post参数
echo 'GET参数:';dump($request->get());echo 'GET参数:name';dump($request->get('name'));echo 'POST参数:name';dump($request->post('name'));echo 'cookie参数:name';dump($request->cookie('name'));echo '上传文件信息:image';dump($request->file('image'));echo '获取参数name,无论get还是post';echo $request->param('name');
获取当前的控制器方法
echo '模块:'.$request->module();echo '控制器:'.$request->controller();echo '操作:'.$request->action();
门面类facade
use think\facade\Request; 这一部分是请求伪装// 是否为 GET 请求if (Request::instance()->isGet()) echo “当前为 GET 请求”;// 是否为 POST 请求if (Request::instance()->isPost()) echo “当前为 POST 请求”;// 是否为 PUT 请求if (Request::instance()->isPut()) echo “当前为 PUT 请求”;// 是否为 DELETE 请求if (Request::instance()->isDelete()) echo “当前为 DELETE 请求”;// 是否为 Ajax 请求if (Request::instance()->isAjax()) echo “当前为 Ajax 请求”;// 是否为 Pjax 请求if (Request::instance()->isPjax()) echo “当前为 Pjax 请求”;// 是否为手机访问if (Request::instance()->isMobile()) echo “当前为手机访问”;// 是否为 HEAD 请求if (Request::instance()->isHead()) echo “当前为 HEAD 请求”;// 是否为 Patch 请求if (Request::instance()->isPatch()) echo “当前为 PATCH 请求”;// 是否为 OPTIONS 请求if (Request::instance()->isOptions()) echo “当前为 OPTIONS 请求”;// 是否为 cliif (Request::instance()->isCli()) echo “当前为 cli”;// 是否为 cgiif (Request::instance()->isCgi()) echo “当前为 cgi”;这一部分是获取当前的信息$request = Request::instance();// 获取当前域名echo ‘domain: ‘ . $request->domain() . ‘<br/>’;// 获取当前入口文件echo ‘file: ‘ . $request->baseFile() . ‘<br/>’;// 获取当前URL地址 不含域名echo ‘url: ‘ . $request->url() . ‘<br/>’;// 获取包含域名的完整URL地址echo ‘url with domain: ‘ . $request->url(true) . ‘<br/>’;// 获取当前URL地址 不含QUERY_STRINGecho ‘url without query: ‘ . $request->baseUrl() . ‘<br/>’;// 获取URL访问的ROOT地址echo ‘root:’ . $request->root() . ‘<br/>’;// 获取URL访问的ROOT地址echo ‘root with domain: ‘ . $request->root(true) . ‘<br/>’;// 获取URL地址中的PATH_INFO信息echo ‘pathinfo: ‘ . $request->pathinfo() . ‘<br/>’;// 获取URL地址中的PATH_INFO信息 不含后缀echo ‘pathinfo: ‘ . $request->path() . ‘<br/>’;// 获取URL地址中的后缀信息echo ‘ext: ‘ . $request->ext() . ‘<br/>’;这样做是获取你当前 模块控制器 等信息$request = Request::instance();echo “当前模块名称是” . $request->module();echo “当前控制器名称是” . $request->controller();echo “当前操作名称是” . $request->action();获取请求参数$request = Request::instance();echo ‘请求方法:’ . $request->method() . ‘<br/>’;echo ‘资源类型:’ . $request->type() . ‘<br/>’;echo ‘访问ip地址:’ . $request->ip() . ‘<br/>’;echo ‘是否AJax请求:’ . var_export($request->isAjax(), true) . ‘<br/>’;echo ‘请求参数:’;dump($request->param());echo ‘请求参数:仅包含name’;dump($request->only([‘name’]));echo ‘请求参数:排除name’;dump($request->except([‘name’]));
上传规则
默认情况下是上传到本地服务器,会在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', ], // 更多的磁盘配置信息 ],];
我们可以指定上传文件的命名规则,例如:
$savename = \think\facade\Filesystem::putFile( 'topic', $file, 'md5');
最终生成的文件名类似于:
runtime/storage/topic/72/ef580909368d824e899f77c7c98388.jpg
系统默认提供了几种上传命名规则,包括:
规则 | 描述 |
---|---|
date | 根据日期和微秒数生成 |
md5 | 对文件使用md5_file散列生成 |
sha1 | 对文件使用sha1_file散列生成 |
其中md5和sha1规则会自动以散列值的前两个字符作为子目录,后面的散列值作为文件名。
如果需要使用自定义命名规则,可以在rule
方法中传入函数或者使用闭包方法,例如:
$savename = \think\facade\Filesystem::putFile( 'topic', $file,'uniqid');
如果希望以指定的文件名保存,可调用putFileAs
方法,例如:
$savename = \think\facade\Filesystem::putFileAs( 'topic', $file,'abc.jpg');
多文件上传
如果你使用的是多文件上传表单,例如:
<form action="/index/index/upload" enctype="multipart/form-data" method="post"> <input type="file" name="image[]" multiple /> <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(); }}
验证参数 | 说明 |
---|---|
fileSize | 上传文件的最大字节 |
fileExt | 文件后缀,多个用逗号分割或者数组 |
fileMime | 文件MIME类型,多个用逗号分割或者数组 |
image | 验证图像文件的尺寸和类型 |
https://www.kancloud.cn/manual/thinkphp6_0/1037625
获取文件hash散列值
可以获取上传文件的哈希散列值,例如:
// 获取表单上传文件$file = request()->file('image');// 获取上传文件的hash散列值echo $file->md5();echo $file->sha1();
可以统一使用hash方法获取文件散列值
// 获取表单上传文件$file = request()->file('image');// 获取上传文件的hash散列值echo $file->hash('sha1');echo $file->hash('md5');