文件上传
获取上传的文件
可以使用 IlluminateHttpRequest
实例提供的 file
方法或者动态属性来访问上传文件, file
方法返回 IlluminateHttpUploadedFile
类的一个实例,该类继承自 PHP 标准库中提供与文件交互方法的 SplFileInfo
类:
$file = $request->file('photo');
$file = $request->photo;
你可以使用 hasFile
方法判断文件在请求中是否存在:
if ($request->hasFile('photo')) {
//
}
验证文件是否上传成功
使用 isValid
方法判断文件在上传过程中是否出错:
if ($request->file('photo')->isValid()){
//
}
文件路径 & 扩展名
UploadedFile
类还提供了访问上传文件绝对路径和扩展名的方法。 extension
方法可以基于文件内容判断文件扩展名,该扩展名可能会和客户端提供的扩展名不一致:
$path = $request->photo->path();
$extension = $request->photo->extension();
其他文件方法
UploadedFile
实例上还有很多其他可用方法,查看该类的API文档了解更多信息。
保存上传的文件
要保存上传的文件,需要使用你所配置的某个文件系统,对应配置位于 config/filesystems.php
:

Laravel 默认使用 local
配置存放上传文件,即本地文件系统,默认根目录是 storage/app
,public
也是本地文件系统,只不过存放在这里的文件可以被公开访问,其对应的根目录是 storage/app/public
,要让 Web 用户访问到该目录下存放文件的前提是在应用入口 public
目录下建一个软链 storage
链接到 storage/app/public
。
UploadedFile
类有一个 store
方法,该方法会将上传文件移动到相应的磁盘路径上,该路径可以是本地文件系统的某个位置,也可以是云存储(如Amazon S3)上的路径。
store
方法接收一个文件保存的相对路径(相对于文件系统配置的根目录 ),该路径不需要包含文件名,因为系统会自动生成一个唯一ID作为文件名。
store
方法还接收一个可选的参数 —— 用于存储文件的磁盘名称作为第二个参数(对应文件系统配置 disks
的键名,默认值是 local
),该方法会返回相对于根目录的文件路径:
$path = $request->photo->store('images');
$path = $request->photo->store('images', 's3');
如果你不想自动生成文件名,可以使用 storeAs
方法,该方法接收保存路径、文件名和磁盘名作为参数:
$path = $request->photo->storeAs('images', 'filename.jpg');
$path = $request->photo->storeAs('images', 'filename.jpg', 's3');
下面我们来简单演示下文件上传功能,在 routes/api.php
中定义如下文件上传路由:
Route::post('file/upload', function(IlluminateHttpRequest $request) {
if ($request->hasFile('photo') && $request->file('photo')->isValid()) {
$photo = $request->file('photo');
$extension = $photo->extension();
//$store_result = $photo->store('photo');
$store_result = $photo->storeAs('photo', 'test.jpg');
$output = [
'extension' => $extension,
'store_result' => $store_result
];
print_r($output);exit();
}
exit('未获取到上传文件或上传过程出错');
});
我们还是使用 Advanced REST Client 工具来演示 POST 表单提交:

标记红圈的地方是需要重点关注的输入和输出。我分别测试了 store
方法和 storeAs
方法,上传文件成功后可以去 storage/app
目录下查看:

其他存储介质使用方式也差不多,无非是修改下 store
和 storeAs
对应的参数。在使用过程中遇到什么问题,欢迎在评论区反馈。