लारवेल 5 - व्यू के भीतर स्टोरेज में अपलोड की गई इमेज को कैसे एक्सेस करें?


171

मुझे Laravel स्टोरेज में उपयोगकर्ता के अवतार अपलोड हो गए हैं। मैं उन्हें कैसे एक्सेस कर सकता हूं और उन्हें एक दृश्य में प्रस्तुत कर सकता हूं?

सर्वर सभी अनुरोधों की ओर इशारा /publicकर रहा है, इसलिए यदि वे /storageफ़ोल्डर में हैं तो मैं उन्हें कैसे दिखा सकता हूं ?

जवाबों:


349

सबसे अच्छा तरीका है नीचे दिए गए उत्तर में @SlateEntropy जैसे प्रतीकात्मक लिंक को बहुत अच्छी तरह से बनाना । 5.3 से संस्करण की मदद से, लारवेल में एक कमांड शामिल है जो इसे करने के लिए अविश्वसनीय रूप से आसान बनाता है:

php artisan storage:link

यही कारण है कि एक से सिमलिंक बनाता public/storageकरने के लिए storage/app/publicआप के लिए और कहा कि इसके लिए बस इतना ही है। अब किसी भी फ़ाइल /storage/app/publicको एक लिंक के माध्यम से एक्सेस किया जा सकता है जैसे:

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

अगर, किसी भी कारण से, आप प्रतीकात्मक लिंक नहीं बना सकते हैं (हो सकता है कि आप साझा होस्टिंग आदि पर हों) या आप कुछ एक्सेस कंट्रोल लॉजिक के पीछे कुछ फ़ाइलों को सुरक्षित रखना चाहते हैं, तो एक विशेष मार्ग होने का विकल्प है जो पढ़ता है और छवि प्रदान करता है। उदाहरण के लिए इस तरह से एक साधारण क्लोजर मार्ग:

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

अब आप अपनी फ़ाइलों को उसी तरह एक्सेस कर सकते हैं, जैसे आप एक सिमलिंक करते हैं:

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

यदि आप इंटरवेंशन इमेज लाइब्रेरी का उपयोग कर रहे हैं, तो आप इसके बिल्ट इन responseविधि का उपयोग कर चीजों को अधिक रसीला बना सकते हैं:

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

चेतावनी

ध्यान रखें कि आप मैन्युअल रूप से उन फ़ाइलों की सेवा कर रहे हैं , जो आप परफ़ॉर्मेंस पेनल्टी लगा रहे हैं, क्योंकि आप फ़ाइल सामग्री को पढ़ने और भेजने के लिए पूरे लारवेल अनुरोध जीवनचक्र से गुज़र रहे हैं, जो HTTP सर्वर को संभालने की तुलना में काफी धीमा है।


जो अच्छा लगता है। मैं एक और सवाल पूछना चाहूंगा। क्या स्टोरेज में अवतार, अंगूठे और इसी तरह (फाइलों को अपलोड करना) जैसी फाइलों को स्टोर करने की सिफारिश की गई है?
तदेसी जलेक

5
आप जहां चाहें उन्हें संग्रहीत कर सकते हैं, लेकिन जब तक कि वे निजी फाइलें नहीं हैं, मुझे लगता है कि आप उन्हें publicनिर्देशिका में संग्रहीत करने से बेहतर हैं । इस तरह आप एक ऐसी छवि प्रतिसाद लिखने के ओवरहेड से बच रहे होंगे जो HTTP सर्वर द्वारा बहुत तेजी से संभाला जा सकता है।
बोगदान

2
व्यक्तिगत रूप से मैं सार्वजनिक फ़ोल्डर में उपयोगकर्ता फ़ाइलों को संग्रहीत नहीं करूंगा, मुझे भंडारण के लिए भंडारण फ़ोल्डर का उपयोग करने पर चीजें बहुत अधिक स्पष्ट और अधिक प्रबंधनीय लगती हैं।
स्लेटएंट्रोपी

2
मैं इनमें से किसी की भी सिफारिश नहीं करूंगा क्योंकि तब आप लारवेल को फिर से लोड करने के ओवरहेड जोड़ रहे हैं और / या प्रत्येक छवि को पढ़ने के लिए PHP का लाभ उठा रहे हैं। CmdSft द्वारा वर्णित एक सिम्लिंक का उपयोग करना अधिक तेज होगा।
user1960364

4
@ user1960364 यही कारण है कि आखिरी पैराग्राफ में सिमिलिंक दृष्टिकोण का उपयोग करने के लिए दृढ़ता से सुझाव दिया गया है। लेकिन खुद का जवाब, जबकि एक प्रदर्शन के दृष्टिकोण से सबसे अच्छा समाधान नहीं है, अभी भी मान्य है और साझा सर्वर पर ऐप चलाने वाले लोगों के लिए एकमात्र दृष्टिकोण हो सकता है जहां सेलिंक को सेटअप करना असंभव हो सकता है। उत्तर यह भी दिखाता है कि अगर जरूरत पड़ने पर आप प्रोग्राम की सेवा कैसे कर सकते हैं, तो शायद इस प्रश्न में पूछी गई एन्क्रिप्टेड फ़ाइलों की सेवा के लिए ।
बोगदान

53

एक विकल्प आपके भंडारण निर्देशिका और सार्वजनिक निर्देशिका में सबफ़ोल्डर के बीच एक प्रतीकात्मक लिंक बनाना होगा।

उदाहरण के लिए

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

यह भी विधि है, जिसका उपयोग Envoyer द्वारा किया गया है , जो लारावेल के डेवलपर टेलर ओटवेल द्वारा निर्मित एक तैनाती प्रबंधक है।


मैं इसके लिए थोड़ा नया हूं। क्या इसे टर्मिनल पर चलाने की आवश्यकता है या लार्वा में कहीं एक कॉन्फ़िगर फ़ाइल में परिभाषित किया जाना चाहिए?
गौरव मेहता

हां, आपको इसे चलाने की आवश्यकता है, हालांकि कमांड लाइन। कहीं भी आप एप्लिकेशन को तैनात करने के लिए इसे सेटअप करने की आवश्यकता होगी।
स्लेटएंट्रोपी

विंडोज उपयोगकर्ताओं के लिए, यहां एक स्टैंडअलोन टूल है, अगर आप CMD का उपयोग नहीं करना चाहते हैं: github.com/amd989/Symlinker#downloads
डेविड

3
यह सवाल पूछा गया कि storageसार्वजनिक रूप से संग्रहीत उपयोगकर्ता अवतार को कैसे दिखाया जाए , आमतौर पर अवतार को किसी प्रकार के अभिगम नियंत्रण की आवश्यकता नहीं होती है। यदि किसी भी प्रकार के मिडलवेयर या रूट का उपयोग करके कोई सुरक्षा की आवश्यकता नहीं है, तो यह आपके संसाधनों के लिए एक व्यर्थ हिट है। लारवेल 5.2 के बाद से यह भी ध्यान देने योग्य है कि एक अलग फाइल "डिस्क" सार्वजनिक फ़ाइलों के लिए मौजूद है ( लारवेल . com/docs/5.2/filesystem ) सीमलिंक का उपयोग करके।
स्लेटएंट्रोपी

6
Laravel 5.3: $ php कारीगर भंडारण में इसे करने के लिए एक कारीगर कमांड है: लिंक
फिल

22

लारवेल 5.2 डॉक्स के अनुसार, आपकी सार्वजनिक रूप से सुलभ फ़ाइलों को निर्देशिका में रखा जाना चाहिए

storage/app/public

उन्हें वेब से सुलभ बनाने के लिए, आप से एक प्रतीकात्मक कड़ी बनाने चाहिए public/storageकरने के लिए storage/app/public

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

अब आप परिसंपत्ति सहायक का उपयोग करके फ़ाइलों के लिए अपने URL को URL में बना सकते हैं:

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


13

सबसे पहले आपको कारीगर कमांड का उपयोग करके भंडारण निर्देशिका के लिए एक प्रतीकात्मक लिंक बनाने की आवश्यकता है

php artisan storage:link

फिर किसी भी दृश्य में आप इस तरह url हेल्पर के माध्यम से अपनी छवि तक पहुँच सकते हैं।

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

4

सभी निजी छवियों और डॉक्स को स्टोरेज डायरेक्टरी में सहेजना अच्छा है, फिर फ़ाइल ईथर पर आपका पूरा नियंत्रण होगा, आप कुछ प्रकार के उपयोगकर्ता को फ़ाइल तक पहुंचने या प्रतिबंधित करने की अनुमति दे सकते हैं।

एक मार्ग / डॉक्स बनाएं और किसी भी नियंत्रक विधि को इंगित करें:

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

जब आप हिट localhost:8000/docsफाइल करेंगे तो कोई मौजूद होगा।

फ़ाइल root/storage/app/users/documentsको उपरोक्त कोड के अनुसार निर्देशिका में होना चाहिए , इस पर परीक्षण किया गया था Laravel 5.4


4

यदि आप कम संख्या में निजी छवियों को लोड करना चाहते हैं, तो आप छवियों को बेस 64 में एन्कोड कर सकते हैं और उन्हें <img src="{{$image_data}}">सीधे इको में बदल सकते हैं:

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

मैंने निजी उल्लेख किया है क्योंकि आपको केवल इन विधियों का उपयोग करना चाहिए यदि आप url के माध्यम से सार्वजनिक रूप से सुलभ छवियों को संग्रहीत नहीं करना चाहते हैं, इसके बजाय आपको हमेशा मानक तरीके (लिंक भंडारण / सार्वजनिक फ़ोल्डर और HTTP सर्वर के साथ छवियों की सेवा) का उपयोग करना चाहिए।

base64()दो महत्वपूर्ण नीचे की ओर एन्कोडिंग से सावधान रहें :

  1. इससे छवि का आकार ~ 30% बढ़ जाएगा।
  2. आप सभी छवियों के आकारों को एक अनुरोध में जोड़ते हैं, उन्हें समानांतर में लोड करने के बजाय, यह कुछ छोटे थंबनेल के लिए समस्या नहीं होनी चाहिए, लेकिन कई छवियों के लिए इस पद्धति का उपयोग करने से बचें।

2

यदि आप php का उपयोग कर रहे हैं तो कृपया निम्न की तरह php सिम्लिंक फ़ंक्शन का उपयोग करें:

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

उपयोगकर्ता नाम और प्रोजेक्ट का नाम सही नामों में बदलें।


1

बिना साइट का नाम

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

अगर आप api JSON felids पर जोड़ने के लिए साइट का नाम इसमें जोड़ना चाहते हैं

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

0

यदि आप मेरी तरह हैं और आपके पास किसी तरह से पूर्ण फ़ाइल पथ हैं (मैंने आवश्यक फ़ोटो पर कुछ ग्लोब () पैटर्न का मिलान किया है तो मैं पूर्ण फ़ाइल पथों के साथ बहुत अधिक अंत करता हूं), और आपका संग्रहण सेटअप अच्छी तरह से जुड़ा हुआ है (जैसे कि आपके पथ स्ट्रिंग है storage/app/public/), तो आप नीचे मेरे छोटे गंदे हैक का उपयोग कर सकते हैं: पी)

 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

यदि डिस्क 'लोकल' आपके लिए काम नहीं कर रही है तो यह प्रयास करें:

  1. में जनता के लिए स्थानीय बदले 'default' => env('FILESYSTEM_DRIVER', 'public'),सेproject_folder/config/filesystem.php
  2. कैश कॉन्फ़िगर करें php artisan config:clear
  3. फिर सिंपल लिंक बनाएं php artisan storage:link

अपलोड की गई छवि का url प्राप्त करने के लिए आप इसका उपयोग कर सकते हैं Storage::url('iamge_name.jpg');

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.