
Laravel 接收上传文件时默认先存入系统临时目录(如 /tmp),这是 PHP 的底层机制;开发者需显式调用 move() 方法将文件从临时位置移至目标路径,否则仅保存临时路径或导致文件丢失。
laravel 接收上传文件时默认先存入系统临时目录(如 `/tmp`),这是 php 的底层机制;开发者需显式调用 `move()` 方法将文件从临时位置移至目标路径,否则仅保存临时路径或导致文件丢失。
在 Laravel 中,所有 HTTP 上传的文件(包括图片)都会首先由 PHP 自动写入服务器的临时目录(例如 Linux 下的 /tmp),这是 PHP $_FILES 机制的固有行为,并非 Laravel 特有。你代码中看似“直接处理 $request->file('photo')”,实则操作的是该临时文件的封装对象——它尚未脱离临时区。只有调用 $photo->move($destinationPath, $filename) 后,文件才真正被复制/移动到你指定的持久化位置。
你原代码的问题在于:
$destinationPath = 'uploads/books'; $photo->move($destinationPath, $profileImage);
这里 $destinationPath = 'uploads/books' 是相对路径,而 move() 方法要求传入绝对磁盘路径(即完整物理路径)。Laravel 的 move() 底层调用的是 PHP 的 move_uploaded_file(),它不支持相对路径,若路径不存在或权限不足,可能静默失败(部分环境会回退到临时目录或报错),导致你以为“文件已保存”,实则仍滞留在临时区。
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
✅ 正确做法是使用 public_path() 生成绝对路径:
if ($request->hasFile('photo')) {
$photo = $request->file('photo');
$extension = $photo->getClientOriginalExtension();
$filename = date('YmdHis') . '.' . $extension;
$destination = public_path('uploads/books'); // ✅ 绝对路径:/var/www/your-app/public/uploads/books
// 确保目录存在且可写
if (!file_exists($destination)) {
mkdir($destination, 0755, true);
}
$photo->move($destination, $filename);
$input['photo'] = $filename; // 仅保存文件名,前端通过 public URL 访问
}同时注意以下关键点:
-
前端访问路径需匹配:你的 Blade 模板中
<img src="uploads/books/%7B%7B%20%24book->photo%20%7D%7D" alt="Laravel 文件上传为何临时保存?解析图片存储路径配置原理" >是正确的,因为public/uploads/books/是 Web 可直接访问的静态资源路径(Laravel 的public/目录即 Web 根目录); -
验证规则优化:你重复定义了
'photo' => 'required',且max:2048单位为 KB,建议明确写为max:2048(即 2MB),并推荐使用mimetypes或更严格的 MIME 验证; -
模型
$fillable安全提示:created_at不应放入$fillable—— 它由 Laravel 自动管理,手动赋值可能导致时间戳异常; -
错误防护增强:生产环境务必检查
move()返回值或捕获Illuminate\Http\Exceptions\PostTooLargeException等异常。
总结:Laravel 不会“自动发送图片到 temp 文件”——而是 PHP 必然先存临时区;你的职责是用 public_path() 构造绝对路径 + move() 主动搬运 + 前端用 public/ 下相对 URL 渲染,三者缺一不可。

















