Come devo servire un'image con Laravel?

Sto memorizzando le immagini del profilo utente nella cartella di archiviazione di laravel invece della cartella pubblica perché vorrei mantenere la cartella pubblica pulita dalla confusione degli utenti.

Per servire un'image da quella cartella, ho creato una semplice azione controller come segue:

public function profilePicture($person, $size = 40){ $profile_picture_url = storage_path().'/profile_pictures/'.$person['id'].'/profile_'.$size.'.jpg'; if(!File::exists( $profile_picture_url )) App::abort(404); return Image::make($profile_picture_url)->response('jpg'); } 

Può essere considerata una buona pratica o devo semplicemente salvare le immagini nella cartella pubblica? Farò problemi di performance facendo così?

La breve risposta alla tua domanda

Può essere considerata una buona pratica o devo semplicemente salvare le immagini nella cartella pubblica? Farò problemi di performance facendo così?

Non è consigliato, perché si legge il file e lo si rigenera, ciò richiederà tempo di elaborazione e carica il server, ma tutto dipende da quante richieste, size dell'image, ecc. Ho usato questa pratica per proteggere / proteggere immagini / file dall'accesso pubblico, quindi solo i membri autenticati possono accedere alle immagini / ai file così come sono in questa risposta . Sempre a seconda delle size del file, del numero di richieste e delle specifiche del server, l'ho usato per un po 'e non ho avuto problemi con le performance, ha funzionato bene (il mio server è 512MBMemory, 1 CoreProcessor, 20GBSSD Disk VPS solution). Si potrebbe fare un tentativo per mentre e vedere.

Soluzione di collegamento simbolico

È anche ansible creare collegamenti simbolici come

 ln -s /pathof/laravel/storage/profile_pictures /pathof/laravel/public/profile 

Questa soluzione non influisce sulle performance, ma è necessario documentare la soluzione nella documentazione interna, nel caso in cui si sposti la configuration con un nuovo provider o nel caso in cui sia necessario ricollegarsi alla cartella di archiviazione.

Ma se vuoi ancora avere la soluzione completa per restituire l'image dalla cartella di archiviazione, prima di tutto dobbiamo installare Intervention Image per Laravel, non sono sicuro che sia già stato fatto. se lo hai installato, continua qui, ma se non segui l'ultima parte di questa risposta e continua con la soluzione di Laravel.

Soluzione di Laravel

Come detto, assumiamo che il tuo intervento funzioni, prima di tutto devi creare un path. Il path inoltrerà tutte le richieste di immagini per l'accesso al nostro controller.

Crea rotta

 Route::get('profile/{person}', '[email protected]'); 

Dopo aver creato un path, abbiamo bisogno di creare un controller per occuparci delle richieste di immagini dal nostro path.

Crea ImagesController

Dal command

 php artisan make:controller ImagesController 

E il tuo controller dovrebbe assomigliare a questo.

 class ImagesController extends Controller { public function profilePicture($person, $size = 40) { $storagePath = storage_path('/profile_pictures/' . $person . '/profile_' . $size . '.jpg'); return Image::make($storagePath)->response(); } } 

E ricorda di aggiungere

 use Intervention\Image\Facades\Image; 

nella tua class ImagesController

Infine assicurati di aver creato la struttura delle cartelle con l'image di prova.

 storage/profile_pictures/person/profile_40.jpg 

Ora se scrivi nel tuo browser

 http://laravelLocalhostUrl/profile/person 

Mostrerà la tua image, l'ho fatta da sola e l'ho testata. inserisci la descrizione dell'immagine qui

Nota: ho cercato di fare in modo che la cartella rispecchiasse la domanda, ma è ansible modificarla facilmente per adattarla al modo desiderato.


Installa Intervento (salta questa parte se l'hai già installata)

Segui questa linea guida per questo: http://image.intervention.io/getting_started/installation

In breve: php composer require intervention/image

E nella tua config/app l'arrays $ providers aggiunge i fornitori di servizi per questo pacchetto.

 Intervention\Image\ImageServiceProvider::class 

Aggiungi la facciata di questo pacchetto alla matrix $ alias.

 'Image' => Intervention\Image\Facades\Image::class 

La soluzione si ispira a questa risposta, ma quella è proteggere l'image con l'authentication in generale e questa risposta .

Nel tuo model User.php :

 protected $appends = ['avatar']; public function getAvatarAttribute($size=null) { return storage_path().'/profile_pictures/'.$this->id.'/profile_'.$size.'.jpg'; } 

Quindi, each volta che chiami un'istanza Utente, avrai il suo avatar insieme ad esso.

Usare Laravel 5.2+ Image::make($pathToFile)->response() può essere considerato una ctriggers pratica. Chiunque cerchi una soluzione per pubblicare immagini da Laravel deve utilizzare return response() -> file($pathToFile, $headers); . Ciò produrrà molto less overhead, in quanto serve solo il file invece di "aprirlo in Photoshop" – alless questo è quello che dice il mio monitor della CPU.

Ecco il link alla documentazione

 Response::stream(function() use($fileContent) { echo $fileContent; }, 200, $headers); 

https://github.com/laravel/framework/issues/2079#issuecomment-22590551