
本教程详细介绍了如何在 Laravel 应用中实现多文件上传功能。内容涵盖前端 Blade 模板中文件输入字段的正确命名方式(`name="field[]"`),以及后端控制器中如何接收、验证和遍历处理多个上传文件,并将其存储到指定磁盘,最终将每个文件路径与数据库记录关联,确保上传流程的完整性和正确性。
在现代 Web 应用中,用户上传文件是常见需求,而多文件上传更是提升用户体验的关键功能。然而,对于初学者来说,正确处理 Laravel 中的多文件上传可能会遇到一些挑战,尤其是在前端表单设置和后端控制器逻辑方面。本教程将深入探讨如何在 Laravel 中实现这一功能,从前端 Blade 模板的正确配置到后端控制器中文件的接收、验证和存储,提供一个全面且专业的解决方案。
实现多文件上传的第一步是在前端表单中正确配置文件输入字段。关键在于 input 标签的 name 属性和表单的 enctype 属性。
所有包含文件上传的 HTML 表单都必须设置 enctype="multipart/form-data" 属性。这是浏览器告知服务器表单数据将以多部分形式编码的必需步骤,以便正确处理文件内容。
立即学习“前端免费学习笔记(深入)”;
<form method="POST" action="{{ route('storeLesson') }}" enctype="multipart/form-data">
<!-- 表单内容 -->
</form>为了让 Laravel 识别并接收多个文件,input 标签的 name 属性必须以数组的形式命名,即在字段名后加上 []。例如,如果我们要上传多个“课程”文件,应使用 name="lessons[]"。这样,当表单提交时,request()-youjiankuohaophpcnlessons 将会是一个包含所有上传文件对象的数组。
此外,为了实现每个文件对应一个课程,并且与特定的课程文件夹关联,我们可以调整 Blade 模板的结构。
修正后的 Blade 模板示例:
<form method="POST" action="{{ route('storeLesson') }}" enctype="multipart/form-data">
@csrf {{-- Laravel CSRF 保护 --}}
<div class="mb-3">
@foreach($course->lessonFolders as $folder)
<div class="card mb-2">
<div class="card-header">{{ $folder->name }}</div>
<div class="card-body">
{{-- 隐藏字段传递 lesson_folder_id --}}
<input type="hidden" name="lesson_folder_id" value="{{ $folder->id }}">
<label for="lessonFiles-{{ $folder->id }}" class="form-label">上传课程文件 (支持多选)</label>
{{-- 关键:使用 lessons[] 并添加 multiple 属性 --}}
<input name="lessons[]" type="file" class="form-control" id="lessonFiles-{{ $folder->id }}" multiple>
<div class="mt-2">
@foreach($folder->lessons as $lesson)
@if($lesson->lesson)
<span class="badge bg-success me-1">{{ basename($lesson->lesson) }}</span>
@endif
@endforeach
</div>
</div>
</div>
@endforeach
</div>
<button class="btn btn-danger" type="submit">上传</button>
</form>注意事项:
前端表单配置完成后,接下来需要在 Laravel 控制器中接收、验证和处理这些上传的文件。
ERMEB云盘发卡系统官方正版系统发卡系统操作简单、方便、易懂,系统微信小程序前端采用nuiapp、后端采用think PHP6,PC前端采用vue开发,使用场景:文件上传储存。适合个人/个体/中小企业使用,本系统配合微信小程序端进行使用,文件下载以及发卡商品卡密领取都需要进入小程序内获取下载码以及卡密领取,小程序内可设置积分充值以及任务获取积分,支持微信激励广告领取文件下载码以及卡密商品,可实现
0
在处理文件之前,进行严格的验证至关重要,以确保文件符合预期类型、大小等要求,并防范潜在的安全风险。
use Illuminate\Http\Request;
use App\Models\Lesson; // 确保引入 Lesson 模型
class LessonController extends Controller
{
public function storeLesson(Request $request)
{
// 1. 验证请求数据
$validatedData = $request->validate([
'lesson_folder_id' => 'required|exists:lesson_folders,id', // 确保文件夹ID存在
'lessons' => 'required|array|min:1', // 必须上传至少一个文件
'lessons.*' => 'file|mimes:pdf,doc,docx,mp4,mov|max:20480', // 每个文件必须是指定类型且最大20MB
], [
'lesson_folder_id.required' => '请选择一个课程文件夹。',
'lesson_folder_id.exists' => '指定的课程文件夹不存在。',
'lessons.required' => '请上传至少一个课程文件。',
'lessons.array' => '上传的课程文件格式不正确。',
'lessons.min' => '请上传至少一个课程文件。',
'lessons.*.file' => '上传的不是有效文件。',
'lessons.*.mimes' => '文件类型不支持。支持PDF, DOC, DOCX, MP4, MOV。',
'lessons.*.max' => '单个文件大小不能超过20MB。',
]);
$lessonFolderId = $validatedData['lesson_folder_id'];
$uploadedFiles = $validatedData['lessons']; // 这是一个包含 UploadedFile 对象的数组
// 2. 遍历并存储每个文件
foreach ($uploadedFiles as $file) {
// 将文件存储到 'my_files' 磁盘下的 'lessons' 目录
// store() 方法会自动生成唯一文件名并返回相对路径
$path = $file->store('lessons', ['disk' => 'my_files']);
// 3. 为每个上传的文件创建新的 Lesson 记录
Lesson::create([
'lesson_folder_id' => $lessonFolderId,
'lesson' => $path, // 存储文件路径
'name' => $file->getClientOriginalName(), // 存储原始文件名,方便显示
// 根据实际需求添加其他字段
]);
}
return redirect('/courses')->with('success', '所有课程文件已成功上传。');
}
}在验证通过后,$validatedData['lessons'] 将是一个 UploadedFile 对象的数组。我们可以通过 foreach 循环遍历这个数组,对每个文件执行存储操作。
$file->store('lessons', ['disk' => 'my_files']):
对于每个成功存储的文件,我们都会创建一个新的 Lesson 模型记录,将文件路径 ($path) 和对应的 lesson_folder_id 以及原始文件名存储到数据库中。这样,每个上传的文件都对应一个独立的课程记录。
Laravel 的文件系统配置位于 config/filesystem.php。这里定义了各种存储磁盘,如本地存储、公共存储、S3 云存储等。本教程中使用了名为 my_files 的自定义磁盘。
config/filesystem.php 示例:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
'endpoint' => env('AWS_ENDPOINT'),
'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false),
],
'my_files' => [
'driver' => 'local',
'root' => public_path() . '/uploads' // 将文件存储到 public/uploads 目录下
]
],注意: 在上述示例中,为了将文件公开可访问,我将 my_files 的 root 路径修改为 public_path() . '/uploads'。这意味着上传的文件将直接存储在项目的 public/uploads 目录下,可以通过 URL 直接访问。如果希望文件不直接公开访问,应将其存储在 storage_path() 目录下,并通过控制器方法进行访问控制。
通过本文的详细讲解,您应该已经掌握了在 Laravel 中实现多文件上传的核心技术。关键在于前端 input 标签的 name="field[]" 命名方式以及后端控制器中对文件数组的正确接收、验证和循环处理。结合 Laravel 强大的文件系统和验证功能,您可以构建出健壮且用户友好的文件上传系统。在实际开发中,请务必关注文件安全性和用户体验,并根据项目需求选择合适的数据库设计和文件存储策略。
以上就是Laravel 多文件上传:前端与后端实现详解的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号