Laravel 5'te Depolama cephesini kullanarak dosya URL'si nasıl alınır?


83

Laravel 5 ile yeni Flysystem entegrasyonunu kullanarak deneyler yapıyorum. DB'ye 'yerelleştirilmiş' yolları depoluyorum ve yolu tamamlamak için Depolama cephesini alıyorum. Örneğin saklıyorum screenshots/1.jpgve kullanıyorum

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

veya

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

Aynı dosyayı farklı disklerde alabilirim.

get dosya içeriğini alır, ancak bunu şu şekilde görünümlerimde kullanmayı umuyorum:

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

ancak yol veya tam yolu alabilen herhangi bir şey mevcut değil (görebildiğim kadarıyla). Öyleyse tam yola nasıl dönebilirim? Ya da merak ediyorum, bunun tasarım gereği mi? Öyleyse, neden tam yolu alamıyorum? Yoksa bunu tamamen yanlış mı yapıyorum?


1
Yolu değil, url'yi istiyorsunuz.
Adam

Yanıtlar:


54

Düzenleme: L5.2 + için Çözüm

Daha iyi ve daha basit bir çözüm var.

Storage::url($filename)Belirli bir dosyanın tam yolunu / URL'sini almak için kullanın . Aşağıdakileri S3depolama dosya sisteminiz olarak ayarlamanız gerektiğini unutmayın config/filesystems.php:'default' => 's3'

Tabii ki Storage::disk('s3')->url($filename)aynı şekilde de yapabilirsiniz .

Gördüğünüz gibi , Bulut dosya sistemine atıfta bulunan tanımlanmış config/filesystems.phpbir parametre de var 'cloud' => 's3'. Depolama klasörünü yerel sunucuda tutmak, ancak Storage::cloud()aynı dosya sistemi yöntemlerine sahip olan bulut kullanımındaki bazı dosyaları almak / depolamak istiyorsanız , örn Storage::cloud()->url($filename).

Laravel dokümantasyonu bu yöntemden bahsetmiyor, ancak bu yöntem hakkında daha fazla bilgi edinmek istiyorsanız, buradan kaynak kodunu kontrol edebilirsiniz .


Güzel! bu yeni bir yöntem , ancak şimdi burada olduğuna sevindim! Storage sınıfı varsayılan olarak görünümlerde mi çalışır? Eğer öyleyse, bunu doğru cevap olarak işaretleyecektir.
daviestar

Evet! varsayılan olarak görünümlerinizde çalışır, bu nedenle endişelenmenize gerek kalmaz.
Pere Joan Martorell

5
Bu L5.2 + için
daviestar

154

Depolama diskinizin Yolu şöyle olacaktır:

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

Buna daha kısa bir çözüm bilmiyorum ...

$ StoragePath'i Görünümlerinizle paylaşabilir ve ardından

$storagePath."/myImg.jpg";

Bu, ortak depolama klasörünün yolunu bulmak için mükemmel bir çözümdür. Teşekkürler!
David

14
Başka bir yol da şu şekilde kullanmaktır applyPathPrefix:Storage::disk('local')->getDriver()->getAdapter()->applyPathPrefix('myImg.jpg');
Maxim Lanin

3
@maximLanin: Bir şekilde örneğinizi kopyalarsanız, sonuncusu (applyPathPrefix) h ve P (yol * Önek) arasında garip bir karaktere sahip olur. Bunu kopyalayıp yapıştırırsanız, bir hata alırsınız. İlk applyPathPrefixkopyalayabileceğiniz. Çok ilginç. (örneğinizdeki son yöntemin adını çift tıklayarak test edebilirsiniz.
Maurice

3
getDriver()Gerek yok. Basitçe Storage::disk('local')->getAdapter()->getPathPrefix()de işe yarayacak.
RA.

6
Laravel 5.4'ten bu yana yeni ve basit bir yöntem olduğunu bilmek güzel olabilir Storage::path, bkz. Bilal'in cevabı
Marten Koetsier

69

Bu yöntem Laravel 5.4'ten beri mevcuttur, bunu şu şekilde elde edebilirsiniz:

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

1
Laravel 5.6'da bir cazibe gibi çalışır. Biri API'de bunu merak ederse, işte: laravel.com/api/5.6/Illuminate/Filesystem/…
Angel Santiago Jaime Zavala

1
Görebildiğim kadarıyla, bu yöntem Laravel 5.4 ( laravel.com/api/5.4/Illuminate/Filesystem/… )
Marten Koetsier

Yukarıdaki iki yorumdaki her iki bağlantı da ölü.
dotNET

9

Bu şekilde çalışmasını sağladım - bir ortam değişkeniyle s3 ve yerel dizin yolları arasında geçiş yaparak, yolu tüm görünümlere geçirdim.

.Env olarak:

APP_FILESYSTEM=local or s3
S3_BUCKET=BucketID

Config / filesystems.php içinde:

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

İçinde 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('/');
}

1
S3 Storage'ı açıklandığı gibi kullanmak benim için bir hata oluşturdu. Ben de bunun örneğini düzelttim return Storage::disk('s3')->getDriver()->getAdapter()->getClient()->getObjectUrl(env('S3_BUCKET'), '').'/';
Lionel Morrison

5

Önce aşağıdaki gibi dosya url / bağlantısını ve ardından yolu alın:

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

5

Yalnızca depolama (disk) yolunu görüntülemek istiyorsanız, şunu kullanın:

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

Ayrıca, ilgileniyorsanız, tüm bu alanları Eloquent model alanlarında kullanabilmeniz için yalnızca Laravel için bir paket ( https://github.com/fsasvari/laravel-uploadify ) oluşturdum :

$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();

4

Haftalar önce çok benzer bir soru yaptım ( Depolama yoluyla yüklenen dosyadan CDN url'sini alın ): CDN url'sinin benim görüşümdeki resmi göstermesini istedim (sizin istediğiniz gibi).

Ancak, API paketini inceledikten sonra bu görevi yapmanın mümkün olmadığını doğruladım. Yani benim çözümüm kullanmaktan kaçınmaktı flysystem. Benim durumumda, RackSpace ile oynamam gerekiyordu. Sonunda kullanım paketimi oluşturmaya ve OpenStack için PHP SDK kullanarak kendi depolama paketimi oluşturmaya karar ver .

Bu şekilde, getPublicUrl()genel URL'yi bir cdn kapsayıcısından almak için ihtiyacınız olan işlevlere tam erişime sahip olursunuz :

/** @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);

Sonuç olarak, depolama hizmetini başka bir seviyeye almanız gerekiyorsa, o zaman flysystemyeterli değildir. İçin localamaçlar, sen nXu çözümüyle @ deneyebilirsiniz


3

Dosyanın mutlak URL'sine ihtiyacınız varsa, aşağıdaki kodu kullanın:

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

2

Mağaza yöntemi:

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

Rota:

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

Denetleyici:

 public function getImage($filename)
    {
        $file = Storage::get($filename);

        return new Response($file, 200);
    }

Görünüm:

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

neden birisi bunu yapsın, neden s3 kullanıp sonra web sunucusunda broxy !!
Shady Keshk

2

Bulduğum başka bir çözüm şudur:

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

URL'yi, belgelerin Depolamasının temel yolunu döndürür


1

Şuna bir göz atın: Bir görüntüyü laravel 4'te görüntülemek için storage_path () nasıl kullanılır? . Aynısı Laravel 5 için de geçerlidir:

Depolama, dosya sistemi içindir ve büyük bir kısmına web sunucusu tarafından erişilemez. Önerilen çözüm, görüntüleri örneğin ortak klasörde (belge kökü olan) bir yerde saklamaktır public/screenshots/. Sonra onları görüntülemek istediğinizde kullanın asset('screenshots/1.jpg').


Geliştirme sırasında ortak klasörüm ve
canlıyken

Gerçekten önemli değil Storage::path(), sunucunuzdaki dosyanın yolunu döndürür, ancak bunun için bir URL'ye ihtiyacınız vardır ve web sunucusu yalnızca belge kökünüzdeki dosyaları sunabilir, yani <project>/public. Dizinlerinizi onun içinde oluşturun ve url()veya asset()blade şablonlarında kullanın.
nXu

2
Storage::path()mevcut değil, yine de istiyorum
daviestar

Tamam, yanlış anladım, üzgünüm. Yapacağım şey yine aynı: DB'ye giden tüm yolu kaydedin, yerel veya s3 olsun. Görüntüleri yüklerken / oluştururken, getenv('debug')hangisinin kullanılacağını kontrol edin ve karar verin.
nXu

Yolun tamamını kurtarmaktan kaçınmaya çalışıyordum ama belki de gitmenin en mantıklı yolu bu.
daviestar

1

Benim durumumda, bu dosyada yerel dosyalar için ayrı bir yöntem yaptım: 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');
    }
}

sonra, çerçeveye çekme isteği oluşturuyorum, ancak henüz ana çekirdekle birleştirilmedi: https://github.com/laravel/framework/pull/13605 Biri bunu birleştirebilir))


0

bu çalışma benim için 2020'de laravel 7'de

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

yani böyle kullanabilirsin

echo Storage::disk('public')->path('');
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.