Laravel s3 存储:未定义的方法“url”

Fis*_*kke 12 storage amazon-s3 laravel

我是使用 amazon s3 与 laravel 的初学者,并且在调用 url() 方法从 s3 文件中检索完整 url 时遇到问题。

我使用的是 Laravel 版本 5.8.29,并且为 s3 安装了适当的 Composer 包

我正在测试将文件上传到存储桶后检索 url。上传成功。

use Illuminate\Support\Facades\Storage;

$url = Storage::url('file.jpg');

$url = Storage::disk('s3')->url('image.png');
Run Code Online (Sandbox Code Playgroud)

使用 Storage::url('file.jpg') 可以,但是

使用 Storage::disk('s3')->url('image.png') ,我会得到一个错误,提示“未定义的方法 'url'”,即使它在 laravel 官方文档中,我也不知道为什么。

gio*_*pds 14

我也对这个“错误”感到恼火。VSCode 和 Intelephense 一直在说Undefined method 'url'任何,即使知道这是Laravel 文档文件存储Storage::disk('s3')->url('path.ext');上建议的方法。有关 5.8 的特定文档,请查看此处。

显然,有不止一种方法可以处理这个问题,我不确定在不改变 Laravel 本身的情况下选择哪一种才是正确的方法。我会告诉你我认为最好的是什么,至少对我来说是这样,因为我正在努力解决同样的问题。

这里建议的一些方法是:

  • 使用默认的云文件系统,如下所示:

    Storage::cloud()->url('filename.ext');
    
    Run Code Online (Sandbox Code Playgroud)

    但我承认我不喜欢它,因为我更喜欢指定磁盘名称。请记住,要使用它,您必须cloud在 处定义配置config/filesystems.php,如下所示:'cloud' => env('FILESYSTEM_CLOUD', 's3')。但是,如果我们可以通过该cloud方法了解一些内容,那就是它在读取代码时向 IDE 返回正确的类型(我们将使用它)。

  • 按照cloud上面的方法,返回\Illuminate\Filesystem\FilesystemManager。因此,我们可以使用它在变量注释中指定它,如下所示:

    /** @var \Illuminate\Filesystem\FilesystemManager $disk */
    $disk = Storage::disk('s3');
    $url = $disk->url('filename.ext');
    
    Run Code Online (Sandbox Code Playgroud)

    格雷格在这里提到了这一点。我真的很喜欢这个实现,并且我可能会使用它。请记住,您还可以始终创建一个方法来在任何地方返回该方法,以避免重复代码:

    /**
     * Return the s3 storage disk.
     *
     * @return \Illuminate\Filesystem\FilesystemAdapter 
     */
    private function getDisk()
    {
        return Storage::disk('s3');
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 另一种强大的方法是直接使用 Laravel 在表下使用的一些隐藏方法直接生成 url:
    $s3 = Storage::disk('s3')->getAdapter()->getClient();
    $url = $s3->getObjectUrl(env('AWS_BUCKET'), 'filename.ext');
    
    Run Code Online (Sandbox Code Playgroud) 即使不必url在配置中设置文件系统,这也可能会生成 url,但正如人们评论的那样,它可能不适用于非公共 s3 目录。据我测试,如果您url设置了配置,它就会忽略它。就我个人而言,考虑到所有这些原因,我不喜欢这样。
  • 还有另一种方法,例如扩展外观,但我也不喜欢,而且我宁愿不在这里发布它,首先是因为对于一些琐碎的事情来说代码太多,其次是不推荐它。但当然,如果您想以集中的方式处理这个问题,这也许是一条路。

正如您所看到的,现在更快、更简洁的方法是使用@var符号。

希望有人在不久的将来解决这个问题,或者出现其他更好的方法。如果有人知道更好的东西,请在评论中告诉我,我很乐意在这里更新。

相关信息:

如果这有帮助,请记住考虑接受答案或点赞。