如何实现对文件的操作,实现上传,下载,展示等等功能,我们通过编写一个简单的实例来了解其中具体的内容。

文件列表的展示/文件上传/文件下载

首先我们需要创建两个文件,一个视图文件,一个控制器,来实现前后端的互通,然后我们在 storage\app\ 创建一个 uploadfiles 的文件夹,用于存储文件。

创建一个名为 filesmanagement.blade.php 的视图文件,包括基本的样式和布局,如下图:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- CSRF Token --><meta name="csrf-token" content="{{ csrf_token() }}"><title>Files Management</title><!-- Scripts --><script src="{{ asset('js/app.js') }}" defer></script><!-- Fonts --><link rel="dns-prefetch" href="//fonts.gstatic.com"><link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet"><!-- Styles --><link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body><div id="app"><nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"><div> This is a demo for file show, upload, download </div></nav><main class="py-4"><div class="container"><div class="row justify-content-center"><div class="col-md-10"><div class="card"><div class="card-header">Files Management</div><div class="card-body"><form><!-- 具体的内容稍后填充 --></form></div></div></div></div></div></main></div>
</body>
</html>

创建一个名为 FilesManagementController.php 的控制器,里面包含三个方法,如下:

<?phpnamespace App\Http\Controllers\TryDemo;use App\Http\Controllers\Controller;class FilesManagementController extends Controller
{public function showFiles(){// 页面展示文件列表}public function uploadFile(){// 上传文件时调用}public function downloadFile(){// 下载文件时调用}}

然后我们需要在路由配置文件里添加对控制器里具体方法的调用,如下图:


进入页面,展示所有文件列表
Route::get('/files', [App\Http\Controllers\TryDemo\FilesManagementController::class, 'showFiles']);通过 form 表单提交上传的文件
设置此路由名为 UploadFile,之后会在视图文件里使用
Route::post('/files', [App\Http\Controllers\TryDemo\FilesManagementController::class, 'uploadFile'])->name('UploadFile');通过点击文件列表的超链接,在浏览器下载指定的文件,{filename} 为文件名,作为参数传入控制器
设置此路由名为 DownloadFile,之后会在视图文件里使用
Route::get('/files/{filename}', [App\Http\Controllers\TryDemo\FilesManagementController::class, 'downloadFile'])->name('DownloadFile');

路由配置已搭建好,在继续完善实例之前,我们需要先了解一下关于文件存储的一些概念,首先在项目的根目录下有两个文件夹目录,storage和 public ,storage 和 public 目录的主要区别在于 storage 目录是用于存放应用程序生成的文件,例如日志文件、缓存文件、上传的文件等等。而 public 目录是用于存放公开访问的文件,例如图片、CSS、JavaScript 文件等等。由于后面我们要将文件存放于这里,所以我们需要了解这两个位置的路径是如何通过函数获取的,如下图:


函数返回值为项目根目录路径
base_path();
返回值为:/var/www/mydemo (mydemo为项目目录名)base_path('storage/app/uploadfiles/AAA.txt');
返回值为:/var/www/mydemo/storage/app/uploadfiles/AAA.txt函数返回值为 storage 文件夹的根目录路径
storage_path();
返回值为:/var/www/mydemo/storagestorage_path('app/uploadfiles/AAA.txt');
返回值:/var/www/mydemo/storage/app/uploadfiles/AAA.txt函数返回值为 public 文件夹的根目录路径
public_path();
返回值为:/var/www/mydemo/public如果建立软连接,public_path() 里可以传入定义的软连接的名字,来获取真正的路径
public_path('myuploadfiles');
返回值为:/var/www/mydemo/public/myuploadfiles
注:我们这里的 myuploadfiles 为设定的软连接名,其实真实指向的是 /var/www/mydemo/storage/app/uploadfiles
稍后会解释什么是软连接需要引入 use Illuminate\Support\Facades\Storage
函数返回值为 storage/app/ 的根目录路径
Storage::path('uploadfiles/AAA.txt');
返回值为:/var/www/mydemo/storage/app/uploadfiles/AAA.txt

对于文件的操控,常用的函数如下:

需要引入 File 类
use Illuminate\Support\Facades\File;获取 app/uploadfiles 文件夹下的所有文件对象
$fileObjArray = File::files(storage_path('app/uploadfiles'));通过循环获得 file 对象,并可以调用其文件操作的函数
foreach ($fileObjArray  as $fileObj) {$fileObj->getPathname(); // 获取文件的路径和文件名$fileObj->getPath(); // 获取文件所在目录的路径$fileObj->getFilename(); // 获取文件名(不包含路径)$fileObj->getExtension(); // 获取文件扩展名(不包含点)$fileObj->getSize(); // 获取文件大小(字节数)$fileObj->getMTime(); // 获取文件的修改时间(Unix 时间戳)$fileObj->isFile(); // 判断文件是否是普通文件$fileObj->isDir(); // 判断文件是否是目录$fileObj->isLink(); // 判断文件是否是符号链接$fileObj->isReadable(); // 判断文件是否可读$fileObj->isWritable(); // 判断文件是否可写
}如果想获取单个文件对象,需要引入
use SplFileInfo;创建这个文件的 file 对象
$fileObj = new SplFileInfo($fileFullPath);
注:$fileFullPath 为文件的完整路径

了解完文件操作的基本内容后,我们来完善控制器里面的方法,如下图:

use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;public function showFiles()
{获取 uploadfiles 文件夹下所有的文件对象数组$fileObjArray = File::files(Storage::path('uploadfiles'));将文件对象数组传到视图文件中return view('files.filesmanagement', ['fileObjArray' => $fileObjArray]);
}public function uploadFile(Request $request)
{接收通过视图文件传来的上传的文件对象$file = $request->file('uploadfile');组成完整的文件路径,storeAs 默认是从 storage/app 目录开始$path = $file->storeAs('uploadfiles', $file->getClientOriginalName());上传成功后返回原页面return redirect()->back()->with('success', 'File uploaded successfully.');
}public function downloadFile($filename)
{获取要下载的文件的完整路径$path = Storage::path('uploadfiles/'.$filename);通过浏览器下载文件return response()->download($path, $filename);
}

然后我们开始填充视图文件的具体内容,通过控件调用路由来实现控制器里的逻辑,如下图:

<form method="POST" enctype="multipart/form-data" action="{{ route('UploadFile') }}">@csrf<div class="row mb-3"><label for="name" class="col-md-2 col-form-label text-md-end">Show Files</label><div class="col-md-8"><ul class="list-group">@if (count($fileObjArray) > 0)@foreach ($fileObjArray as $fileObj)<li class="list-group-item"><p>{{ $fileObj->getPathname() }}</p><div class="d-flex justify-content-end"><a href="{{ route('DownloadFile', ['filename' => $fileObj->getFilename()]) }}"> Download </a></div></li>@endforeach@endif</ul></div></div><div class="row mb-3"><label for="email" class="col-md-4 col-form-label text-md-end">Upload File</label><div class="col-md-6"><input id="uploadfile" type="file" class="form-control" name="uploadfile" value=""></div></div><div class="row mb-3"><div class="col-md-6 offset-md-4"><button type="submit" class="btn btn-primary">Upload File</button></div></div>
</form>

所有功能都已补充完整,通过浏览器可以进行尝试,如下图:

如何设置软链接

此时对于文件列表的展示,文件的上传和下载功能已完成,我们再尝试一个在页面展示一张已上传的图片,这里就需要了解一个概念,叫软链接。因为 storage 文件夹虽然用于存储文件,但是这个文件夹是不对外公开的,所以如果你想要通过文件的地址来指向具体文件来展示在页面,会提示 404 找不到文件。这里我们需要通过软链接将这个不对外公开的文件夹跟一个公开的文件夹链接,通过指向公开文件夹的路径来找到其指定的文件,这个公开的文件夹就是 public 文件夹,下面我们来讲解一下如何进行软链接操作,首先打开文件配置文件 config\filesystems.php,在最下方找到软链接的配置,如下图:

通过上图可以看到,我们已经配置两个软链接,名为 storage 的软链接指向的是 storage/app/public 文件夹,名为 myuploadfiles 的软链接指向的是 storage/app/uploadfiles 文件夹。当你在配置文件里什么都不配置的时候,直接运行如下命令,系统会自动生成名为 storage 的软链接。

php artisan storage:link

命令运行成功后会提示软链接的具体内容,如下图:

当然你也可以像我一样自定义一个软链接,如 myuploadfiles 来指定你自己存放文件的路径,要记得在填写完配置文件后,要再次运行 php artisan storage:link 命令才能生效,不过如果之前已经生成软链接的路径,在命令运行结束后会提示你软链接的路径已存在,需要注意,如下图:

如何在浏览器展示图片文件

当软链接创建成功后,我们就可以直接在视图文件通过 URL 来展示图片了,如下图:

<form>...
</form><div class="row mb-0"><img src="{{ asset('myuploadfiles/t1.png') }}" alt="show pic">
</div>asset() 方法会默认指向 public 文件夹,
在里面传入参数(软连接名和文件名拼接的路径),即可获得完整的图片路径

此时运行浏览器,可以看到图片展示成功了,如下:

如何在浏览器展示 PDF 文件

添加一个 showPDF() 的方法,如下:

use SplFileInfo;public function showPDF()
{获取文件的对象$fileObj = new SplFileInfo(storage_path('app/uploadfiles/TestPDF.pdf'));获取文件的完整路径$path = $fileObj->getPathname();获取文件类型的后缀名$fileType = $fileObj->getExtension();switch ($fileType) {case 'docx':$contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';break;case 'xlsx':$contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';break;case 'txt':$contentType = 'text/plain';break;case 'pdf':$contentType = 'application/pdf';break;default:$contentType = 'application/pdf';break;}$headers = ['Content-Type' => $contentType,'Content-Disposition' => 'inline; filename = '.$fileObj->getFilename(),];return response()->file($path, $headers);
}注:'Content-Disposition' => 'inline' 代表在浏览器页面展示'Content-Disposition' => 'attachment' 代表在浏览器页面下载

上面显示 PDF 的方式是整个浏览器显示 PDF 内容,如果你想在页面中局部嵌入 PDF 显示,可以直接在视图文件里添加,如下代码:

显示 PDF ,如浏览器不支持嵌入显示,会显示下载信息<object data="{{ asset('myuploadfiles/TestPDF.pdf') }}" type="application/pdf" width="100%" height="800px"><p>您的浏览器不支持嵌入式 PDF 文件,请<a href="{{ asset('myuploadfiles/TestPDF.pdf') }}">下载</a>该文件以查看它。</p></object>如想显示 txt 文件,可以按照如下方式来处理<iframe src="{{ asset('myuploadfiles/AAA.txt') }}" width="100%" height="800px"><p>您的浏览器不支持嵌入式 PDF 文件,请<a href="{{ asset('myuploadfiles/AAA.txt') }}">下载</a>该文件以查看它。</p>
</iframe>注:
这里的 asset() 方法都是依赖软链接指定到真实的文件目录
myuploadfiles 为我定义的软链接,指向的是 storage/app/uploadfiles/ 目录
AAA.txt 为指定的 PDF 文件

如今我们已经学会如何展示文件了,那现在我们继续完善一下上面的例子,在页面的文件列表后面 添加一个 Check Online 的功能,点击后会在浏览器开启一个新的 tab 页来展示文件的内容,我们先创建一个新的视图文件,名为 showfile.blade.php,此文件用于在跳转后展示文件的内容,如下图:

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- CSRF Token --><meta name="csrf-token" content="{{ csrf_token() }}"><title>Files Management</title><!-- Scripts --><script src="{{ asset('js/app.js') }}" defer></script><!-- Fonts --><link rel="dns-prefetch" href="//fonts.gstatic.com"><link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet"><!-- Styles --><link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body><div id="app"><nav class="navbar navbar-expand-md navbar-light bg-white shadow-sm"><div style="padding-left: 10px;"> {{ $filename }} </div></nav><main class="py-4"><div class="container"><div class="row justify-content-center"><div class="col-md-10"><div class="card"><div class="card-header" style="text-align: center;">Show File</div><div class="card-body">@if ($filetype == 'txt')<div class="row mb-3"><iframe src="{{ asset('myuploadfiles/'.$filename) }}" width="100%" height="800px"><p>您的浏览器不支持嵌入式 TXT 文件</p></iframe></div>@else<div class="row mb-3"><object data="{{ asset('myuploadfiles/'.$filename) }}" type="{{ $contenttype }}" width="100%" height="800px"><p>您的浏览器不支持嵌入式 {{ $filetype }} 文件</p></object></div>@endif</div></div></div></div></div></main></div>
</body>
</html>

我们在控制器里创建一个名为 showFile() 的方法,用于给这个页面传递所需要的参数,如下图:

use SplFileInfo;public function getContentType($fileType)
{$contentType = "";switch ($fileType) {case 'docx':$contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';break;case 'xlsx':$contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';break;case 'txt':$contentType = 'text/plain';break;case 'pdf':$contentType = 'application/pdf';break;default:$contentType = 'application/pdf';break;}return $contentType;
}public function showFile($fileName)
{$fileObj = new SplFileInfo(storage_path('app/uploadfiles/'.$fileName));$fileName = $fileObj->getFilename();$fileType = $fileObj->getExtension();$contentType = $this->getContentType($fileType); // 自定义的一个获取 content type 的方法return view('files.showfile', ['filename' => $fileName, 'filetype' => $fileType,'contenttype' => $contentType]);
}

然后我们配置一个路由来搭建视图文件和控制器的沟通桥梁,如下图:

Route::get('/showfile/{filename}', [App\Http\Controllers\TryDemo\FilesManagementController::class, 'showFile'])->name('ShowFile');

最后我们在 filemanagement.blade.php 的视图文件添加一个超链接来调用这个名为 ShowFile 的路由,如下图:

<div class="d-flex justify-content-end"><a href="{{ route('DownloadFile', ['filename' => $fileObj->getFilename()]) }}"> Download </a><!-- 添加在此 ↓↓↓ --><a href="{{ route('ShowFile', ['filename' => $fileObj->getFilename()]) }}" target="_blank" class="mx-3"> Check Online </a><!-- 添加结束 -->
</div>

至此所有功能已完善,打开浏览器看效果,如下:

Laravel 8 文件的上传/下载/显示的实例相关推荐

  1. Asp.net实现MVC处理文件的上传下载删除功能实例教程

    上传于下载功能是程序设计中非常常见的一个功能,在ASP.NET程序开发中有着非常广泛的应用.本文就以实例形式来实现这一功能. 一.概述 如果你仅仅只有Asp.net Web Forms背景转而学习As ...

  2. ACTIVEX实现大文件FTP上传下载---上

    ACTIVEX实现大文件FTP上传 在Windows 操作系统下,有一个重要的机制,就是OLE ,就是可以让某个应用程序(OLE Controller)访问其它应用程序(OLE Server)所提供的 ...

  3. 使用JSP+Servlet实现文件的上传下载上传

    <!DOCTYPE html > <html> <head> <meta charset="UTF-8"> <title> ...

  4. Java使用SFTP和FTP两种连接服务器的方式实现对文件的上传下载

    一.Java实现对SFTP服务器的文件的上传下载: 1.添加maven依赖: <dependency><groupId>com.jcraft</groupId>&l ...

  5. 文件的上传下载功能的实现(包括进度条)[telerik控件]

    文件的上传下载功能的实现(包括进度条) 1.准备工作 首先我们需要Telerik控件,数据库,上传文件文件夹. Telerik控件: RadUpload.RadProgressManager.RadP ...

  6. ssm框架验证码图片加载不出_基于SSM框架的文件图片上传/下载功能实现

    前一段时间很多做毕业设计的同学问:如何写图片和文件的上传下载功能,今天正好有时间,所以就做了一个案例,详细的讲解这个功能. 框架结构: 对于很多做过开发的而言,上传功能肯定都用过,而且用到的场景很多, ...

  7. 基于layui.upload.js 拖拽文件/文件夹上传下载

    layui.upload.js 拖拽文件/文件夹上传下载 前言 js代码 页面使用(我这里用的是uploader.jsp) CSS文件 上传效果 总结 前言 项目需求完成文件上传,可以拖拽上传文件/文 ...

  8. FTP客户端--实现FTP文件的上传下载功能

    现在是2017.6.16的1点多,这几天刚好做了个FTP客户端的计网实验,就把思路过程和源码发上来吧! 一.设计思路:首先,登陆指定的FTP服务器(指定服务器的IP和用户名,密码,端口号若无就默认为2 ...

  9. 通过okHttpUtils实现文件的上传下载

    封装了okhttp的网络框架,支持大文件上传下载,上传进度回调,下载进度回调,表单上传(多文件和多参数一起上传),链式调用,可以自定义返回对象,支持Https和自签名证书,支持cookie的持久化和自 ...

最新文章

  1. 帝国cms 标签php,帝国cms常用标签总结
  2. redis bitmap
  3. centos 7 中安装 docker和创建 tomcat容器并部署web应用
  4. 编码注释coding: utf-8
  5. 你对ES6究竟了解多少?—— 有这一篇就够用了
  6. 不小心运行了一个***程序~word 2003 打开2007格式文件的转换器.rar 里的
  7. 通信协议规格_小米和阿里巴巴定义智能家居通信协议“蓝牙Mesh”
  8. Zend Studio使用Xdebug调试
  9. Maven发布工程到公共库
  10. html消除样式,清除css样式
  11. 「 数学模型 」“使用SPSS软件主成分分析”实例
  12. 商业软件、共享软件和自由软件
  13. 中控考勤机重置考勤机密码方法
  14. 页面http 405错误排查
  15. latex中标题的使用
  16. 定时任务实现方式对比
  17. 商汤科技——机器视觉面试
  18. 【千锋Python2205班10.8笔记-day11-函数基础(一阶段)】
  19. VS2013 如何创建应用程序图标
  20. 有关深度学习人工智能的感悟

热门文章

  1. 男人成熟的十七种表现(zt)
  2. 【前端图片转化】 base64格式 转为 File文件类型
  3. 【中亦安图】SQL优化之基于SQL特征的改写(9)
  4. 【网络流24题补全计划】
  5. 基于遗传算法的电动汽车有序充电优化调度 利用遗传算法对电动汽车有序充电进行优化;优化目标包括充电费用最低,电动汽车充到足够的电,负荷峰谷差最小
  6. php 导出大数据量excel 解决方法 秒出 并不会出现PHPExcel内存溢出问题
  7. 【推荐】优秀笔记软件——幕布,注册可免费体验一个月高级会员
  8. 云南大学计算机学科评估排名,全国第四轮学科评估结果公布 云南大学2个学科获评A类...
  9. idea出现Error:Abnormal build process termination:
  10. 将图片快速批量转化成PDF格式文件