【问题标题】:How to get file URL using Storage facade in laravel 5?如何在 laravel 5 中使用 Storage 门面获取文件 URL?
【发布时间】:2015-05-11 22:21:49
【问题描述】:

我一直在尝试使用新的 Flysystem 与 Laravel 5 的集成。我正在将“本地化”路径存储到数据库,并让 Storage 门面完成路径。例如我存储screenshots/1.jpg 并使用

Storage::disk('local')->get('screenshots/1.jpg')

Storage::disk('s3')->get('screenshots/1.jpg') 

我可以在不同的磁盘上检索相同的文件。

get 检索文件内容,但我希望在我的视图中使用它,如下所示:

<img src="{{ Storage::path('screenshots/1.jpg') }}" />

但路径或任何能够检索完整路径的东西都不可用(据我所知)。那么如何返回完整路径?或者,我想知道这是否是设计使然?如果是这样,为什么我不应该能够获得完整的路径?或者,我是不是完全走错了路?

【问题讨论】:

  • 您要的是 url 而不是路径。

标签: php laravel flysystem


【解决方案1】:

存储磁盘的路径是:

$storagePath  = Storage::disk('local')->getDriver()->getAdapter()->getPathPrefix()

我不知道任何更短的解决方案......

您可以将 $storagePath 分享给您的视图,然后调用

$storagePath."/myImg.jpg";

【讨论】:

  • 这是获取公共存储文件夹路径的完美解决方案。谢谢!
  • 另一种方法是像这样使用applyPathPrefixStorage::disk('local')-&gt;getDriver()-&gt;getAdapter()-&gt;applyPathPrefix('myImg.jpg');
  • @maximLanin:不知何故,如果你复制你的例子,最后一个(applyPathPrefix)在 h 和 P(path*Prefix)之间有一个奇怪的字符。如果你复制粘贴,你会得到一个错误。第一个applyPathPrefix可以复制。很奇怪。 (您可以通过双击示例中的最后一个方法名称来测试它。
  • getDriver() 不是必需的。只需 Storage::disk('local')-&gt;getAdapter()-&gt;getPathPrefix() 也可以。
  • 也许很高兴知道从 Laravel 5.4 开始有一个新的、简单的方法 Storage::path,请参阅 Bilal's answer
【解决方案2】:

此方法从 Laravel 5.4 开始存在,您可以通过以下方式获取:

$path = Storage::disk('public')->path($filename);

【讨论】:

    【解决方案3】:

    编辑:L5.2+ 的解决方案

    有一个更好更直接的解决方案。

    使用Storage::url($filename) 获取给定文件的完整路径/URL。请注意,您需要将S3 设置为config/filesystems.php 中的存储文件系统:'default' =&gt; 's3'

    当然,Storage::disk('s3')-&gt;url($filename)也可以用同样的方法。

    正如您在config/filesystems.php 中看到的,还定义了一个参数'cloud' =&gt; 's3',它指的是云文件系统。如果您想在本地服务器中维护存储文件夹但在云中检索/存储一些文件,请使用Storage::cloud(),它也具有相同的文件系统方法,即Storage::cloud()-&gt;url($filename)

    Laravel 文档没有提到这个方法,但是如果你想了解更多可以查看它的源代码here

    【讨论】:

    • 不错!这是new method,但我很高兴它现在就在这里! Storage 类是否默认在视图中工作?如果是,将其标记为正确答案。
    • 是的!默认情况下它会在您的视图中运行,因此您完全不必担心。
    • 这是 L5.2+
    【解决方案4】:

    这就是我让它工作的方式 - 使用环境变量在 s3 和本地目录路径之间切换,将路径传递给所有视图。

    在 .env 中:

    APP_FILESYSTEM=local or s3
    S3_BUCKET=BucketID
    

    在 config/filesystems.php 中:

    'default' => env('APP_FILESYSTEM'),
    

    app/Providers/AppServiceProvider:

    public function boot()
    {
        view()->share('dynamic_storage', $this->storagePath());
    }
    
    protected function storagePath()
    {
        if (Storage::getDefaultDriver() == 's3') {
            return Storage::getDriver()
                    ->getAdapter()
                    ->getClient()
                    ->getObjectUrl(env('S3_BUCKET'), '');
        }
    
        return URL::to('/');
    }
    

    【讨论】:

    • 按照描述使用 s3 存储对我产生了错误。所以我将示例修改为return Storage::disk('s3')-&gt;getDriver()-&gt;getAdapter()-&gt;getClient()-&gt;getObjectUrl(env('S3_BUCKET'), '').'/';
    【解决方案5】:

    如果您只想显示存储(磁盘)路径,请使用:

    Storage::disk('local')->url('screenshots/1.jpg'); // storage/screenshots/1.jpg
    Storage::disk('local')->url(''): // storage
    

    另外,如果您有兴趣,我为 Laravel 创建了一个包 (https://github.com/fsasvari/laravel-uploadify),以便您可以在 Eloquent 模型字段中使用所有这些字段:

    $car = Car::first();
    
    $car->upload_cover_image->url();
    $car->upload_cover_image->name();
    $car->upload_cover_image->basename();
    $car->upload_cover_image->extension();
    $car->upload_cover_image->filesize();
    

    【讨论】:

      【解决方案6】:

      如果您需要文件的绝对 URL,请使用以下代码:

      $file_path = \Storage::url($filename);
      $url = asset($file_path);
      // Output: http://example.com/storage/filename.jpg
      

      【讨论】:

        【解决方案7】:

        先获取文件url/link,再获取路径,如下:

        $url = Storage::disk('public')->url($filename);
        $path = public_path($url);
        

        【讨论】:

          【解决方案8】:

          好吧,几周前我提出了一个非常相似的问题 (Get CDN url from uploaded file via Storage):我希望 CDN url 在我的视图中显示图像(如您所要求的那样)。

          但是,在查看包 API 后,我确认无法执行此任务。所以,我的解决方案是避免使用flysystem。就我而言,我需要使用 RackSpace。所以,最后决定创建自己的使用包,使用The PHP SDK for OpenStack制作自己的存储包。

          通过这种方式,您可以完全访问所需的功能,例如 getPublicUrl(),以便从 cdn 容器中获取公共 URL:

          /** @var DataObject $file */
          $file = \OpenCloud::container('cdn')->getObject('screenshots/1.jpg');
          
          // $url:  https://d224d291-8316ade.ssl.cf1.rackcdn.com/screenshots/1.jpg
          $url = (string) $file->getPublicUrl(UrlType::SSL);
          

          总之,如果需要将存储服务提升到另一个层次,那么flysystem 是不够的。对于local的目的,你可以试试@nXu的解决方案

          【讨论】:

            【解决方案9】:

            存储方法:

            public function upload($img){
               $filename = Carbon::now() . '-' .  $img->getClientOriginalName();
               return Storage::put($filename, File::get($img)) ? $filename : '';
            }
            

            路线:

             Route::get('image/{filename}', [
                    'as'   => 'product.image',
                    'uses' => 'ProductController@getImage',
                ]);
            

            控制器:

             public function getImage($filename)
                {
                    $file = Storage::get($filename);
            
                    return new Response($file, 200);
                }
            

            查看:

             <img src="{{ route('product.image', ['filename' => $yourImageName]) }}" alt="your image"/>
            

            【讨论】:

            • 为什么有人会这样做,为什么使用 s3 然后在网络服务器中 broxy !!
            【解决方案10】:

            我找到的另一个解决方案是:

            Storage::disk('documents')->getDriver()->getConfig()->get('url')
            

            将返回带有文档存储基本路径的 url

            【讨论】:

              【解决方案11】:

              这项工作于 2020 年在 laravel 7 上为我工作

                      $image_resize = Image::make($image->getRealPath());
                      $image_resize->resize(800,600);
                      $image_resize->save(Storage::disk('episodes')->path('') . $imgname);
              

              所以你可以这样使用它

              echo Storage::disk('public')->path('');
              

              【讨论】:

              • 也可以使用 Laravel 5.6。 $url = Storage::disk('public')-&gt;path('filename.json'); $cities = json_decode(file_get_contents($url), true);
              【解决方案12】:

              看看这个:How to use storage_path() to view an image in laravel 4。这同样适用于 Laravel 5:

              存储是用于文件系统的,其中大部分是Web服务器无法访问的。推荐的解决方案是将图像存储在公用文件夹(即文档根目录)中的某个位置,例如public/screenshots/。 然后当你想显示它们时,使用asset('screenshots/1.jpg')

              【讨论】:

              • 我正在尝试设置一个“磁盘”作为开发时的公用文件夹,并在运行时设置 s3
              • 没关系,Storage::path() 返回文件在你服务器上的路径,但是你需要一个指向它的 URL 并且网络服务器只能从你的文档根目录提供文件,也就是 @ 987654325@。在其中创建目录并在刀片模板中使用url()asset()
              • Storage::path() 不存在,不过我想要它
              • 好吧,我误会了,对不起。我要做的仍然是一样的:保存到数据库的完整路径,无论是本地还是 s3。上传/创建图像时,只需检查getenv('debug') 并决定使用哪一个。
              • 我试图避免保存完整路径,但也许这是最明智的做法。
              【解决方案13】:

              在我的例子中,我为本地文件创建了单独的方法,在这个文件中: src/Illuminate/Filesystem/FilesystemAdapter.php

                  /**
               * Get the local path for the given filename.
               * @param $path
               * @return string
               */
              public function localPath($path)
              {
                  $adapter = $this->driver->getAdapter();
                  if ($adapter instanceof LocalAdapter) {
                      return $adapter->getPathPrefix().$path;
                  } else {
                      throw new RuntimeException('This driver does not support retrieving local path');
                  }
              }
              

              然后,我向框架创建拉取请求,但它仍未合并到主核心中: https://github.com/laravel/framework/pull/13605 可能有人合并这个))

              【讨论】:

                猜你喜欢
                • 2017-10-21
                • 2023-04-11
                • 2021-11-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2018-02-15
                相关资源
                最近更新 更多