Laravel 5 - Bagaimana cara mengakses gambar yang diunggah dalam penyimpanan dalam View?

172

Saya sudah mendapat avatar pengguna yang diunggah di penyimpanan Laravel. Bagaimana saya bisa mengaksesnya dan menjadikannya dalam tampilan?

Server menunjuk semua permintaan /public, jadi bagaimana saya bisa menunjukkannya jika ada di /storagefolder?

Tadeáš Jílek
sumber

Jawaban:

349

The terbaik pendekatan adalah untuk membuat link simbolik seperti @SlateEntropy sangat baik tunjukkan dalam jawaban di bawah ini . Untuk membantu ini, sejak versi 5.3, Laravel menyertakan perintah yang membuatnya sangat mudah dilakukan:

php artisan storage:link

Itu menciptakan symlink dari public/storageuntuk storage/app/publicuntuk Anda dan hanya itu yang ada untuk itu. Sekarang semua file di /storage/app/publicdapat diakses melalui tautan seperti:

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

Jika, karena alasan apa pun, Anda tidak dapat membuat tautan simbolis (mungkin Anda menggunakan hosting bersama, dll.) Atau Anda ingin melindungi beberapa file di balik beberapa logika kontrol akses, ada alternatif memiliki rute khusus yang berbunyi dan melayani gambar. Misalnya rute penutupan sederhana seperti ini:

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;
});

Sekarang Anda dapat mengakses file seperti yang Anda lakukan jika memiliki symlink:

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

Jika Anda menggunakan Pustaka Gambar Intervensi, Anda dapat menggunakan responsemetode bawaannya untuk membuat segalanya lebih ringkas:

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

PERINGATAN

Ingatlah bahwa dengan menyajikan file secara manual , Anda akan dikenakan penalti kinerja , karena Anda akan melalui seluruh siklus hidup permintaan Laravel untuk membaca dan mengirim konten file, yang jauh lebih lambat daripada server HTTP yang menanganinya.

Bogdan
sumber
Sepertinya bagus. Saya ingin mengajukan satu pertanyaan lagi. Apakah disarankan untuk menyimpan file seperti avatar, jempol, dan sebagainya (file yang diunggah dari pengguna) di penyimpanan?
Tadeáš Jílek
5
Anda dapat menyimpannya di mana pun Anda suka, tetapi kecuali jika itu adalah file pribadi saya pikir Anda lebih baik menyimpannya di publicdirektori. Dengan cara ini Anda akan menghindari overhead karena harus menyusun respons gambar yang bisa ditangani lebih cepat oleh server HTTP.
Bogdan
2
Secara pribadi saya tidak akan menyimpan file pengguna di folder publik, saya menemukan banyak hal lebih rapi dan lebih mudah dikelola ketika folder penyimpanan digunakan untuk penyimpanan.
SlateEntropy
2
Saya tidak akan merekomendasikan salah satu dari ini karena Anda menambahkan overhead memuat Laravel lagi dan / atau meningkatkan PHP untuk membaca setiap gambar. Menggunakan symlink seperti yang dijelaskan oleh CmdSft akan jauh lebih cepat.
user1960364
4
@ user1960364 Itu sebabnya paragraf terakhir sangat menyarankan untuk menggunakan pendekatan symlink. Tetapi jawabannya sendiri, meskipun bukan solusi terbaik dari sudut pandang kinerja, masih valid dan mungkin menjadi satu-satunya pendekatan bagi orang yang menjalankan aplikasi di server bersama di mana symlink tidak mungkin untuk diatur. Jawabannya juga menunjukkan bagaimana Anda dapat menyajikan file secara programatik jika diperlukan, mungkin untuk menyajikan file yang dienkripsi seperti yang ditanyakan dalam pertanyaan ini .
Bogdan
53

Salah satu opsi adalah membuat tautan simbolis antara subfolder di direktori penyimpanan Anda dan direktori publik.

Sebagai contoh

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

Ini juga merupakan metode yang digunakan oleh Envoyer , manajer penempatan yang dibangun oleh Taylor Otwell, pengembang Laravel.

SlateEntropy
sumber
Saya agak baru dalam hal ini. Apakah ini perlu dijalankan pada terminal atau didefinisikan dalam file konfigurasi di suatu tempat di laravel?
Gaurav Mehta
ya, Anda perlu menjalankan ini melalui baris perintah. Itu harus diatur di mana saja Anda menyebarkan aplikasi.
SlateEntropy
Untuk pengguna Windows, berikut ini adalah alat mandiri untuk itu jika Anda tidak ingin menggunakan CMD: github.com/amd989/Symlinker#downloads
David
3
Pertanyaan yang diajukan adalah bagaimana memperlihatkan avatar pengguna yang disimpan di tempat storageumum, biasanya avatar tidak memerlukan kontrol akses apa pun. Jika tidak diperlukan keamanan menggunakan middleware atau rute apa pun hanya merupakan serangan terbuang ke sumber daya Anda. Ini juga patut dicatat karena Laravel 5.2 ada file "disk" yang terpisah untuk file publik ( laravel.com/docs/5.2/filesystem ) menggunakan symlinks.
SlateEntropy
6
Ada perintah pengrajin untuk melakukan ini di Laravel 5.3: $ penyimpanan artisan php: tautan
Phil
22

Menurut Laravel 5.2 docs, file Anda yang dapat diakses publik harus dimasukkan ke dalam direktori

storage/app/public

Untuk membuatnya dapat diakses dari web, Anda harus membuat tautan simbolik dari public/storageke storage/app/public.

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

Sekarang Anda dapat membuat URL dalam tampilan Anda ke file menggunakan bantuan aset:

echo asset('storage/file.txt');
Piotr
sumber
13

Pertama-tama Anda perlu membuat tautan simbolis untuk direktori penyimpanan menggunakan perintah tukang

php artisan storage:link

Maka dalam tampilan apa pun Anda dapat mengakses gambar Anda melalui bantuan url seperti ini.

url('storage/avatars/image.png');
Ali Haider
sumber
4

Adalah baik untuk menyimpan semua gambar pribadi dan dokumen dalam direktori penyimpanan maka Anda akan memiliki kontrol penuh atas file ether Anda dapat mengizinkan tipe pengguna tertentu untuk mengakses file atau membatasi.

Buat rute / dokumen dan arahkan ke metode pengontrol apa pun:

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']
    );
}

Kapan Anda akan menekan localhost:8000/docsfile akan diunduh jika ada.

File harus dalam root/storage/app/users/documentsdirektori sesuai dengan kode di atas, ini diuji pada Laravel 5.4.

Syed Shibli
sumber
4

Jika Anda ingin memuat sejumlah kecil gambar Privat Anda dapat menyandikan gambar ke base64 dan menggemakannya <img src="{{$image_data}}">langsung:

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

Saya sebutkan pribadi karena Anda hanya boleh menggunakan metode ini jika Anda tidak ingin menyimpan gambar yang dapat diakses publik melalui url, sebagai gantinya Anda harus selalu menggunakan cara standar (tautan penyimpanan / folder publik dan sajikan gambar dengan server HTTP).

Waspadai penyandian untuk base64()memiliki dua sisi penting:

  1. Ini akan meningkatkan ukuran gambar hingga ~ 30%.
  2. Anda menggabungkan semua ukuran gambar dalam satu permintaan, alih-alih memuatnya secara paralel, ini seharusnya tidak menjadi masalah untuk beberapa thumbnail kecil tetapi untuk banyak gambar hindari menggunakan metode ini.
Arash Moosapour
sumber
2

Jika Anda menggunakan php maka silakan gunakan fungsi symlink php, seperti berikut:

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

ubah nama pengguna dan nama proyek menjadi nama yang tepat.

dagogodboss
sumber
1

tanpa nama situs

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

jika Anda ingin menambahkan nama situs ke contoh untuk menambahkan pada api JSON api

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

Jika Anda seperti saya dan Anda entah bagaimana memiliki path file lengkap (saya melakukan beberapa glob () mencocokkan pola pada foto yang diperlukan jadi saya cukup banyak berakhir dengan path file lengkap), dan setup penyimpanan Anda terhubung dengan baik (yaitu sedemikian rupa sehingga jalur Anda miliki string storage/app/public/), maka Anda dapat menggunakan hack kecil kotor saya di bawah ini: 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 '';
    }
Damilola Olowookere
sumber
0

Jika disk 'lokal' tidak berfungsi untuk Anda maka coba ini:

  1. Ubah lokal menjadi publik 'default' => env('FILESYSTEM_DRIVER', 'public'),dariproject_folder/config/filesystem.php
  2. Hapus cache konfigurasi php artisan config:clear
  3. Kemudian buat tautan sym php artisan storage:link

Untuk mendapatkan url gambar yang diunggah, Anda dapat menggunakan ini Storage::url('iamge_name.jpg');

Dnyaneshwar Harer
sumber