You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 04:17:24