Laravel中Storage::exists返回false但file_exists返回true的原因
问题:Laravel Storage::disk('local')->exists() 返回false,但file_exists()返回true
我在Laravel任务中执行以下流程:
- 如果项目使用S3磁盘,将文件从S3下载到本地磁盘的
storage/app/videos-to-convert/{video-name}路径; - 使用
ffmpeg复制视频并添加必要的元数据; - 检查视频的元数据信息并保存到数据库;
- 如果使用S3,将本地文件移动到S3。
遇到的问题是:Storage::disk('local')->exists($videoPath)返回false,但file_exists($videoPath)返回true。
相关代码如下:
// 我们需要将S3文件移至本地磁盘以运行FFMPEG if ($this->isUsingS3Bucket()) { $s3File = Storage::disk('s3')->get("videos-to-convert/{$this->session->id}.{$this->session->video_extension}"); Storage::disk('local')->put("videos-to-convert/{$this->session->id}.{$this->session->video_extension}", $s3File); } // 此处路径已确认无误,经过多次检查 $inputPath = storage_path("app/videos-to-convert/{$this->session->id}.{$this->session->video_extension}"); $outputPath = storage_path("app/videos/{$this->session->id}.{$this->session->video_extension}"); // 视频的无头信息由浏览器中的MediaRecorder发送 // 我们需要用ffmpeg复制视频,以获取视频时长等元数据信息 shell_exec("ffmpeg -y -i $inputPath -vcodec copy -acodec copy $outputPath"); $ffprobe = FFProbe::create(); $durationInSeconds = $ffprobe->format($outputPath)->get('duration'); echo "-------\n"; $o = shell_exec("ls -la /var/www/html/storage/app/videos"); // 此`ls -la`命令显示视频存在于Storage::disk('local')->exists($outputPath)检测的路径中 echo $o; if ($this->isUsingS3Bucket()) { $exists = file_exists($outputPath); $existLaravel = Storage::disk('local')->exists($outputPath); if ($exists) { echo "FILE EXISTS 'file_exists'------\n"; } if ($existLaravel) { echo "FILE EXISTS WITH Storage::disk('local') LARAVEL-----\n"; } // 剩余代码 }
原因与解决方案
核心原因
Laravel的Storage::disk('local')默认根目录指向storage/app/,调用exists()方法时,需要传入相对于该根目录的路径,而非完整的系统绝对路径。
你代码中$outputPath是用storage_path()生成的绝对路径(比如/var/www/html/storage/app/videos/xxx.mp4),当把这个绝对路径传给Storage::disk('local')->exists()时,它会在storage/app/目录下查找这个完整路径(相当于查找storage/app//var/www/html/storage/app/videos/xxx.mp4),显然不存在,所以返回false。而file_exists()是直接用系统绝对路径检查,因此能正确识别文件存在,返回true。
解决办法
将传给Storage::disk('local')->exists()的路径替换为相对路径即可:
// 替换原来的检查代码 $relativeOutputPath = "videos/{$this->session->id}.{$this->session->video_extension}"; $existLaravel = Storage::disk('local')->exists($relativeOutputPath);
验证方式
你可以通过Storage::disk('local')->path()方法验证相对路径的正确性,它会生成与$outputPath完全一致的绝对路径:
echo Storage::disk('local')->path($relativeOutputPath); // 输出:/var/www/html/storage/app/videos/xxx.mp4
内容的提问来源于stack exchange,提问作者Bruno Francisco
相关产品推荐
相关产品推荐

