编程

在 Laravel 中上传文件

553 2023-05-30 14:01:00

如果你想了解怎么在 Laravel 中处理文件上传,那么请往下读。本文涵盖了在 Laravel 中处理文件上传所需的最低要求,并涉及了一些更高级的东西如添加验证和表单请求等。

请注意本教程是基于 Laravel 9,以我目前的了解,也适用于后续的版本。

准备文件上传控制器

创建新控制器,用来添加文件处理逻辑。

$ php artisan make:controller FileUploadController

FileUploadController 中,添加以下代码:

use Illuminate\Http\Request;

...

public function upload(Request $request)
{
    // Create a variable referencing the uploaded file from the request
    $file = $request->file('upload');

    // Store the file in storage/app/uploads
    $file->store('uploads');

    // Redirect to the success page
    return redirect()->route('fileUpload.success');
}

然后,添加为 success 路由添加另一个方法。可根据自己需要自定义内容: 

public function success()
{
    return 'Success!';
}

然后再在 routes/web.php 中添加下面的路由,关联文件上传控制器:

Route::get('/', fn () => view('upload'));
Route::get('/success', [FileUploadController::class, 'success'])->name('fileUpload.success');
Route::post('/', [FileUploadController::class, 'upload'])->name('fileUpload.upload');

在浏览器中打开上传表单对应的页面,点击浏览,选中文件然后点击上传!

 

然后我们就能看见文件存储在 storage/uploads 文件夹下了。

你能看到文件被重命名为一个随机名。如果要保留原文件名,你可以将 $file->store('uploads') 替换成 $file->storeAs('uploads', $file->getClientOriginalName())

文件上传验证

接下来,让我们看看如何在文件上传处理中添加一些验证。将我们想接受的文件类型放到 rules 中是一种很好的实际 。如果我们只对图片感兴趣,或者更具体地说对 .jpg 感兴趣,那么我们可以通过设置一些验证规则来做到这一点。

重新访问 FileUploadController.php,在上传逻辑的最顶端,在从请求访问文件之前。我们可以通过请求变量定义一些验证规则,如下所示:

// Specify the validation rules that we want to apply
$request->validate([
    'upload' => 'required|image|max:1000',
]);

// Create a variable referencing the uploaded file from the request
$file = $request->file('upload');

...

添加完后,可尝试上传一个非图片文件看看会发生什么。

你会注意到不再调整到 success 消息页面,并且表单被重置。我们继续完善。

upload.blade.php 文件(即表单文件所在)中,我在 input 字段下面添加了一个新的代码段。具体位置可根据需要自行决定。

@if ($errors->get('upload'))
    <p>
        {{ $errors->get('upload')[0] }}
    </p>
@endif

再次尝试上传非图片文件,你就能看到提示信息,说明没有返回成功信息的原因。

回到此前的验证规则代码,让我们稍微分析一下。

$request->validate([
    'upload' => 'required|image|max:1000',
]);

我在 upload 参数中添加了三个规则,使用管道符 | 分开。

  • required: 字段为必需
  • image: 接收图片,比如 .jpg, .png, .svg.
  • max:1000:  拒绝大小超过 1000kbs (1 MB) 的文件

可以查看 Laravel 文档了解更多验证规则信息

将这些验证规则提取到各自的 Form Request 

为了让控制器更加整洁,我们添加的验证逻辑可以提取到它们自己的 Form Request 类中

用下面命令创建:

php artisan make:request FileUploadRequest

删除 authorize 方法,因为我们步使用它。我们只关注 rules 方法,复制控制器中的验证规则。

class FileUploadRequest extends FormRequest
{
    public function rules()
    {
        return [
            'upload' => 'required|image|max:1000',
        ];
    }
}

最好,回到 FileUploadController 并修改 upload() 方法中 $request 的参数类型:

public function upload(FileUploadRequest $request)

如果 IDE 没有自动帮你引入,别忘了引入命名空间。

use App\Http\Requests\FileUploadRequest;

请尝试再次上传图像,一切都应该像以前一样正常。让我们把这个分解一下。
我们添加的验证规则已提取到表单请求中。然后,通过添加 $request 的类名(作为类型),Laravel 将通过依赖注入注入必要的类,并在我们开始处理文件之前执行验证检查。