大侠请留步,且看我这个怪异的文件上传:The file "/tmp/phpQYktzX" does not exist ???

问题描述

事情是这样的,我通过表单上传图片,得到了标题里的那个错误,但其实文件已经上传成功了,而且奇怪的地方在于我如果使用 dd() 方法查看的话是没问题的,不会报错。然后我把打印函数去掉,正常做路由跳转就会报错,下面给出比较详细的代码截图。

处理表单上传图片的代码

file

上图中打印的结果

file

高潮到了:如果我把第一张图里的打印函数都去掉,正常做路由跳转,则报错如下图

file

一直报错 The file "/tmp/XXXXXX" does not exist

ImageUploadHandler.php

<?php

namespace App\Handlers;

class ImageUploadHandler
{
    // 只允许以下后缀名的图片文件上传
    protected $allowed_ext = ["png", "jpg", "gif", 'jpeg'];

    public function save($file)
    {
        // 构建存储的文件夹规则
        // 文件夹切割能让查找效率更高。
        $folder_name = "uploads/images/" . date("Ym/d", time());

        // 文件具体存储的物理路径,`public_path()` 获取的是 `public` 文件夹的物理路径。
        $upload_path = public_path() . '/' . $folder_name;

        // 获取文件的后缀名,因图片从剪贴板里黏贴时后缀名为空,所以此处确保后缀一直存在
        $extension = strtolower($file->getClientOriginalExtension()) ?: 'png';

        // 值如:14935210507BVc9v9ujP.png
        $filename = time() . str_random(20) . '.' . $extension;

        // 如果上传的不是图片将终止操作
        if (!in_array($extension, $this->allowed_ext)) {
            return false;
        }

        // 将图片移动到我们的目标存储路径中
        $file->move($upload_path, $filename);

        $imageSize = getimagesize($upload_path . '/' . $filename);

        return [
            'name' => $filename,
            'path' => "/{$folder_name}/{$filename}",
            'extension' => $extension,
            'original_name' => $file->getClientOriginalName(),
            'width' => $imageSize[0],
            'height' => $imageSize[1],
        ];
    }
}

补充描述

  1. 我在本地是完全没有问题的,本地开发环境是 Homestead。
  2. 服务器是 CentOS 7.4 版本。
  3. PHP Version:7.2.6
  4. Laravel Version:5.7.13

搞了好几个小时,没什么思路了,有大侠愿意帮忙分析一下吗?

如果缺少什么信息请留言,我会补充,谢谢!

勤学如春起之苗,不见其增,日有所长。

Soldoros
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

看这个堆栈,似乎是因为 dd 之后抛出一个异常,在 Laravel 的异常处理器的 App\Exceptions\Handler:report 方法内进入到了 Monolog 再次引发异常,导致的问题。一种猜测:进到控制器方法后 move 图片,dd 后的某条代码引发异常或错误,而后进到异常处理器,进到日志,日志检查到文件上传,所以希望再次读取上传的临时文件,然而已经被 move 了,所以抛出异常。可以继续追踪一下看看。重点关注一下 Freshbitsweb\LaravelLogEnhancer\RequestDataProcessor,卸载掉此扩展包尝试一下。

7个月前 评论
讨论数量: 14

看下堆栈,追到控制器那一层,看看是从哪里进到抛异常的代码的。建议使用 XDebug 调试一下。另外检查下 /tmp 的读写权限,虽然看起来不像权限问题。

7个月前 评论
Soldoros

@Wi1dcard 翻过堆栈信息,压根没有控制器的,我把堆栈信息在这里贴一下;另外权限的问题也看过了没问题,要是权限有问题的话图片也不会正常能被 move 了,非常感谢你的答案!

Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException thrown with message "The file "/tmp/phpt437P6" does not exist"

Stacktrace:
#21 Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException in /home/wwwroot/api.bdgstore.com.cn/vendor/symfony/http-foundation/File/File.php:37
#20 Symfony\Component\HttpFoundation\File\File:__construct in /home/wwwroot/api.bdgstore.com.cn/vendor/symfony/http-foundation/File/UploadedFile.php:77
#19 Symfony\Component\HttpFoundation\File\UploadedFile:__construct in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Http/UploadedFile.php:120
#18 Illuminate\Http\UploadedFile:createFromBase in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php:332
#17 Illuminate\Http\Request:Illuminate\Http\Concerns\{closure} in [internal]:0
#16 array_map in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php:333
#15 Illuminate\Http\Request:convertUploadedFiles in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php:314
#14 Illuminate\Http\Request:allFiles in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php:184
#13 Illuminate\Http\Request:all in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php:248
#12 Illuminate\Http\Request:except in /home/wwwroot/api.bdgstore.com.cn/vendor/freshbitsweb/laravel-log-enhancer/src/RequestDataProcessor.php:13
#11 Freshbitsweb\LaravelLogEnhancer\RequestDataProcessor:__invoke in /home/wwwroot/api.bdgstore.com.cn/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php:60
#10 call_user_func in /home/wwwroot/api.bdgstore.com.cn/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php:60
#9 Monolog\Handler\AbstractProcessingHandler:processRecord in /home/wwwroot/api.bdgstore.com.cn/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php:33
#8 Monolog\Handler\AbstractProcessingHandler:handle in /home/wwwroot/api.bdgstore.com.cn/vendor/monolog/monolog/src/Monolog/Logger.php:337
#7 Monolog\Logger:addRecord in /home/wwwroot/api.bdgstore.com.cn/vendor/monolog/monolog/src/Monolog/Logger.php:616
#6 Monolog\Logger:error in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Log/Logger.php:176
#5 Illuminate\Log\Logger:writeLog in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Log/Logger.php:87
#4 Illuminate\Log\Logger:error in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Log/LogManager.php:490
#3 Illuminate\Log\LogManager:error in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:114
#2 Illuminate\Foundation\Exceptions\Handler:report in /home/wwwroot/api.bdgstore.com.cn/app/Exceptions/Handler.php:37
#1 App\Exceptions\Handler:report in /home/wwwroot/api.bdgstore.com.cn/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php:81
#0 Illuminate\Foundation\Bootstrap\HandleExceptions:handleException in [internal]:0
7个月前 评论

在路由跳转之前没有报错,那这个错误可能是由于跳转之后那个 apis.edit 对应的方法里出现了问题。

7个月前 评论

看这个堆栈,似乎是因为 dd 之后抛出一个异常,在 Laravel 的异常处理器的 App\Exceptions\Handler:report 方法内进入到了 Monolog 再次引发异常,导致的问题。一种猜测:进到控制器方法后 move 图片,dd 后的某条代码引发异常或错误,而后进到异常处理器,进到日志,日志检查到文件上传,所以希望再次读取上传的临时文件,然而已经被 move 了,所以抛出异常。可以继续追踪一下看看。重点关注一下 Freshbitsweb\LaravelLogEnhancer\RequestDataProcessor,卸载掉此扩展包尝试一下。

7个月前 评论
Soldoros

@huazi 我之前也怀疑是这样,所有我去方法里截了一下,结果没截到,说明问题还是出在了 return 那里。

而且案情有了新的进展,且看补充。

file

7个月前 评论

试过删扩展包了吗。

7个月前 评论
leo

目测是你们的 Laravel 日志配置了把用户的请求都写到日志里,然而没有排除掉上传文件的情况

7个月前 评论
Soldoros

@Wi1dcard 我顺着你的思路,composer.json 和 composer.lock 都给删除了,重新拉取了下,问题解决了,但问题最终是哪里造成的目前尚不清楚,十分感谢你的答案,非常有帮助,谢谢!

7个月前 评论
Soldoros

@leo 有道理啊!但是为什么我重新安装了一下扩展包就没有这个问题了呢?如果是日志那里造成的问题,应该还存在这个问题才对呢

7个月前 评论
leo

@Soldoros 可能有人在线上调试 Bug,直接改了 vendor 里面的代码,调完之后忘记改回来了

7个月前 评论
Soldoros

@leo 哈哈,这个肯定不会,因为只有我自己开发维护这个项目。

7个月前 评论

我靠,老哥,我也遇到了这个问题,请问你是怎么解决的?重新拉取是重新 composer install的意思吗?

4个月前 评论

我刚才解决了这个问题,move_uploaded_file ,执行的操作是剪切文件,执行完这个请求之后临时文件就不存在了,所以日志或是扩展包再去读取这个临时文件时会报错,所以只要把move_uploaded_file改成copy就行!

4个月前 评论
Soldoros

@zjxkk 奇怪的是我并没有修改任何代码,只重新 Composer 拉取了一下就好,我感觉应该某些包产生冲突了,比如我把文件移走了以后,接下来的逻辑里触发了某些包自动记录日志之类的,也获取这个信息,然后就出现了。

感觉还是你这个方法靠谱,以后就用 copy

4个月前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

社区文档:

将托管在 packagist.org 和 github.com 的扩展包使用国内 CDN 加速
GitHub Laravel 扩展包 TOP 250
速查表方便快速查询框架功能,支持手机访问,支持中英文版本
Laravel 中文文档,由社区用户翻译和维护,将会保持一直更新
此文档的目的,就是为了提高技术团队的凝聚力、一致性和生产效率。
开发环境的部署,开发者工具的选择,适用于 Mac 和 Windows。
浓缩过后的精华
Laravel Nova 后台管理面板文档的中文翻译
Lumen 中文文档,由社区用户翻译和维护,将会保持一直更新
Laravel 下知名扩展包 Dingo API 的中文文档,Laravel API 开发必知必会