Laravel 5 - Görünüm içinde depoya yüklenen resme nasıl erişilir?


172

Kullanıcının avatarlarını Laravel depolama alanına yükledim. Onlara nasıl erişebilir ve bir görünümde oluşturabilirim?

Sunucu tüm istekleri işaret ediyor /public, öyleyse /storageklasördeyse onlara nasıl gösterebilirim ?

Yanıtlar:


349

En iyi yaklaşım oluşturmaktır sembolik bağlantıyı çok iyi de işaret @SlateEntropy gibi aşağıda cevabını . Bu konuda yardımcı olmak için, 5.3 sürümünden beri, Laravel bunu inanılmaz derecede kolaylaştıran bir komut içerir :

php artisan storage:link

Yani bir sembolik oluşturur public/storageiçin storage/app/publicsize ve bunun için vardır hepsi bu. Artık içindeki herhangi bir dosyaya /storage/app/publicaşağıdaki gibi bir bağlantı üzerinden erişilebilir:

http://somedomain.com/storage/image.jpg

Herhangi bir nedenle, sembolik bağlantılar oluşturamazsanız (belki paylaşılan barındırmada bulunuyorsunuz, vb.) Veya bazı erişim kontrol mantığının arkasındaki bazı dosyaları korumak istiyorsanız, aşağıdakileri okuyan ve görüntüyü sunar. Örneğin, aşağıdaki gibi basit bir kapatma yolu:

Route::get('storage/{filename}', function ($filename)
{
    $path = storage_path('public/' . $filename);

    if (!File::exists($path)) {
        abort(404);
    }

    $file = File::get($path);
    $type = File::mimeType($path);

    $response = Response::make($file, 200);
    $response->header("Content-Type", $type);

    return $response;
});

Artık dosyalarınıza, bir sembolik bağlantınız gibi erişebilirsiniz:

http://somedomain.com/storage/image.jpg

Eğer kullanıyorsanız Müdahale Resmi Kütüphane sen onun yerleşik kullanabilirsiniz responseyapmak şeyler daha özlü yöntem:

Route::get('storage/{filename}', function ($filename)
{
    return Image::make(storage_path('public/' . $filename))->response();
});

UYARI

Tarafından unutmayın elle hizmet veren dosyaları bir oluşturduğunuzu performans kaybına okuyup olan dosya içeriğini, göndermek için tüm laravel isteği ömrü geçiyor çünkü, önemli ölçüde daha yavaş HTTP sunucusu kolu o kalmadan daha.


İyi görünüyor. Bir soru daha sormak istiyorum. Avatar, başparmak vb. Gibi dosyaların (kullanıcılardan yüklenen dosyalar) depolanmasında saklanması tavsiye edilir mi?
Tadeáš Jílek

5
Onları istediğiniz yerde saklayabilirsiniz, ancak bunlar özel dosyalar olmadıkça onları publicdizinde saklamaktan daha iyi olduğunuzu düşünüyorum . Bu şekilde, HTTP sunucusu tarafından çok daha hızlı işlenebilecek bir görüntü yanıtı oluşturmak zorunda kaldığınız yükü ortadan kaldıracaksınız.
Bogdan

2
Şahsen kullanıcı dosyalarını ortak klasörde saklamam, depolama klasörü depolama için kullanıldığında daha düzenli ve yönetilebilir şeyler buluyorum.
ArduvazEtropisi

2
Bunlardan birini tavsiye etmem çünkü o zaman Laravel'i tekrar yükleyerek ve / veya her görüntüyü okumak için PHP'den yararlanıyorsunuz. CmdSft tarafından açıklanan şekilde bir sembolik bağlantı kullanmak çok daha hızlı olacaktır.
user1960364

4
@ user1960364 Bu yüzden son paragraf symlink yaklaşımını kullanmanızı önerir. Ancak yanıtın kendisi, performans açısından en iyi çözüm olmasa da, hala geçerlidir ve sembolik bağlantıların kurulumunun imkansız olduğu paylaşılan sunucularda uygulama çalıştıran kişiler için tek yaklaşım olabilir. Cevap ayrıca, ihtiyaç duyulduğu takdirde, belki de bu sorudaki gibi şifrelenmiş dosyaları sunmak için, dosyaları programlı olarak nasıl sunabileceğinizi de gösterir .
Bogdan

53

Seçeneklerden biri, depolama dizininizdeki bir alt klasör ile ortak dizin arasında sembolik bir bağlantı oluşturmak olabilir.

Örneğin

ln -s /path/to/laravel/storage/avatars /path/to/laravel/public/avatars

Bu aynı zamanda Laravel'in geliştiricisi Taylor Otwell tarafından kurulan bir dağıtım yöneticisi Envoyer tarafından kullanılan yöntemdir.


Biraz yeniyim. Bunun terminalde çalıştırılması veya laravel'in herhangi bir yerinde bir yapılandırma dosyasında tanımlanması gerekiyor mu?
Gaurav Mehta

evet, bunu komut satırından çalıştırmanız gerekir. Uygulamayı kurduğunuz her yerde ayarlanması gerekir.
SlateEntropy

Windows kullanıcıları için, CMD'yi
David

3
Soru, storageherkese açık olarak depolanan kullanıcı avatarlarının nasıl gösterileceğini sordu , genellikle avatarlar herhangi bir erişim kontrolü gerektirmez. Herhangi bir ara katman yazılımı veya rota kullanmak için herhangi bir güvenlik gerekmiyorsa, kaynaklarınızı israf edersiniz. Ayrıca Laravel 5.2'den halka açık dosyalar ( laravel.com/docs/5.2/filesystem ) için sembolik bağlantıları kullanan ayrı bir "disk" dosyası bulunduğundan da bahsetmek gerekir .
SlateEntropy

6
Laravel 5.3'te bunu yapmak için bir esnaf komutu var: $ php artisan storage: link
Phil

22

Laravel 5.2 belgelerine göre, herkese açık dosyalarınız dizine eklenmelidir

storage/app/public

Web'den bunları erişilebilir hale getirmek için, sembolik bir bağlantı oluşturmalısınız public/storageiçin storage/app/public.

ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage

Artık görünümünüzde öğe yardımcısını kullanarak dosyalara bir URL oluşturabilirsiniz:

echo asset('storage/file.txt');


13

Her şeyden önce, artisan komutunu kullanarak depolama dizini için sembolik bir bağlantı oluşturmanız gerekir

php artisan storage:link

Daha sonra herhangi bir görünümde resminize böyle url yardımcısı aracılığıyla erişebilirsiniz.

url('storage/avatars/image.png');

4

Tüm özel görüntüleri ve dokümanları depolama dizinine kaydetmek iyidir, o zaman dosya eteri üzerinde tam kontrole sahip olursunuz, belirli kullanıcı türünün dosyaya erişmesine veya kısıtlamasına izin verebilirsiniz.

Bir rota / doküman yapın ve herhangi bir denetleyici yöntemine işaret edin:

public function docs() {

    //custom logic

    //check if user is logged in or user have permission to download this file etc

    return response()->download(
        storage_path('app/users/documents/4YPa0bl0L01ey2jO2CTVzlfuBcrNyHE2TV8xakPk.png'), 
        'filename.png',
        ['Content-Type' => 'image/png']
    );
}

Ne zaman vuracağınız varsa localhost:8000/docsdosya indirilir.

Dosya root/storage/app/users/documentsyukarıdaki koda göre dizinde olmalıdır , bu üzerinde test edilmiştir Laravel 5.4.


4

Az sayıda Özel görüntü yüklemek istiyorsanız Görüntüleri base64'e kodlayabilir ve <img src="{{$image_data}}">doğrudan yansıtabilirsiniz :

$path = image.png
$full_path = Storage::path($path);
$base64 = base64_encode(Storage::get($path));
$image_data = 'data:'.mime_content_type($full_path) . ';base64,' . $base64;

Özel olarak bahsetmiştim, çünkü bu yöntemleri yalnızca url aracılığıyla herkesin erişebileceği görüntüleri saklamak istemiyorsanız kullanmalısınız, bunun yerine her zaman standart yolu kullanmalısınız (depolama / ortak klasör bağlantısı ve resimleri HTTP sunucusuyla sunmanız gerekir).

base64()İki önemli aşağı tarafı olması için kodlamaya dikkat edin :

  1. Bu, görüntü boyutunu ~% 30 artıracaktır.
  2. Tüm görüntü boyutlarını bir istekte birleştirirsiniz, paralel olarak yüklemek yerine, bu bazı küçük küçük resimler için sorun olmamalı, ancak birçok görüntü için bu yöntemi kullanmaktan kaçının.

2

Eğer php kullanıyorsanız, lütfen aşağıdaki gibi php symlink işlevini kullanın:

symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')

kullanıcı adını ve proje adını doğru adlarla değiştirin.


1

site adı olmadan

{{Storage::url($photoLink)}}

api JSON felids'e eklemek için site adı eklemek istiyorsanız örnek

 public function getPhotoFullLinkAttribute()
{
    return env('APP_URL', false).Storage::url($this->attributes['avatar']) ;
}

0

Benim gibiyseniz ve bir şekilde tam dosya yollarına sahipseniz (gerekli fotoğraflarda bazı glob () desen eşleştirmesi yaptım, bu yüzden tam dosya yollarıyla sonuçlanıyorum) ve depolama kurulumunuz iyi bağlanmış (yani yollarınız dize var storage/app/public/), o zaman aşağıdaki benim küçük kirli kesmek kullanabilirsiniz: p)

 public static function hackoutFileFromStorageFolder($fullfilePath) {
        if (strpos($fullfilePath, 'storage/app/public/')) {
           $fileParts = explode('storage/app/public/', $fullfilePath);
           if( count($fileParts) > 1){
               return $fileParts[1];
           }
        }

        return '';
    }

0

'Local' diski sizin için çalışmıyorsa şunu deneyin:

  1. Halka yerel değiştirin 'default' => env('FILESYSTEM_DRIVER', 'public'),danproject_folder/config/filesystem.php
  2. Yapılandırma önbelleğini temizle php artisan config:clear
  3. Sonra sym bağlantısı oluşturun php artisan storage:link

Yüklenen resmin URL'sini almak için bunu kullanabilirsiniz Storage::url('iamge_name.jpg');

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.