Ho gli avatar dell'utente caricati nello spazio di archiviazione di Laravel. Come posso accedervi e renderli in una vista?
Il server punta a tutte le richieste /public
, quindi come posso mostrarle se si trovano nella /storage
cartella?
Ho gli avatar dell'utente caricati nello spazio di archiviazione di Laravel. Come posso accedervi e renderli in una vista?
Il server punta a tutte le richieste /public
, quindi come posso mostrarle se si trovano nella /storage
cartella?
Risposte:
L' approccio migliore è quello di creare un collegamento simbolico come @SlateEntropy ben indicato nella risposta di seguito . Per aiutarlo, dalla versione 5.3, Laravel include un comando che lo rende incredibilmente facile da eseguire:
php artisan storage:link
Questo crea un collegamento simbolico da public/storage
a storage/app/public
per te e questo è tutto ciò che c'è da fare. Ora è /storage/app/public
possibile accedere a qualsiasi file in tramite un collegamento come:
http://somedomain.com/storage/image.jpg
Se, per qualsiasi motivo, non riesci a creare collegamenti simbolici (forse sei su hosting condiviso, ecc.) O vuoi proteggere alcuni file dietro una logica di controllo dell'accesso, c'è l'alternativa di avere un percorso speciale che legge e serve l'immagine. Ad esempio una semplice via di chiusura come questa:
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;
});
Ora puoi accedere ai tuoi file come faresti se avessi un link simbolico:
http://somedomain.com/storage/image.jpg
Se stai utilizzando la libreria di immagini di intervento , puoi utilizzare il suo response
metodo integrato per rendere le cose più sintetiche:
Route::get('storage/{filename}', function ($filename)
{
return Image::make(storage_path('public/' . $filename))->response();
});
AVVERTIMENTO
Tieni presente che servendo manualmente i file stai subendo una penalità per le prestazioni , perché stai attraversando l'intero ciclo di vita della richiesta Laravel per leggere e inviare il contenuto del file, che è notevolmente più lento rispetto alla gestione da parte del server HTTP.
public
directory. In questo modo eviterai il sovraccarico di dover comporre una risposta di immagine che potrebbe essere gestita molto più velocemente dal server HTTP.
Un'opzione sarebbe quella di creare un collegamento simbolico tra una sottocartella nella directory di archiviazione e nella directory pubblica.
Per esempio
ln -s /path/to/laravel/storage/avatars /path/to/laravel/public/avatars
Questo è anche il metodo utilizzato da Envoyer , un gestore di distribuzione creato da Taylor Otwell, lo sviluppatore di Laravel.
storage
pubblicamente, di solito gli avatar non richiedono alcun tipo di controllo degli accessi. Se non è richiesta alcuna sicurezza utilizzando qualsiasi tipo di middleware o route è solo uno spreco di risorse. Vale anche la pena notare dal momento che Laravel 5.2 esiste un "disco" di file separato per i file pubblici ( laravel.com/docs/5.2/filesystem ) utilizzando i collegamenti simbolici.
Secondo i documenti di Laravel 5.2, i file accessibili al pubblico dovrebbero essere inseriti nella directory
storage/app/public
Per renderli accessibili dal Web, è necessario creare un collegamento simbolico da public/storage
a storage/app/public
.
ln -s /path/to/laravel/storage/app/public /path/to/laravel/public/storage
Ora puoi creare nella tua vista un URL per i file usando l'assistente risorse:
echo asset('storage/file.txt');
Se sei su Windows puoi eseguire questo comando su cmd:
mklink /j /path/to/laravel/public/avatars /path/to/laravel/storage/avatars
da: http://www.sevenforums.com/tutorials/278262-mklink-create-use-links-windows.html
Prima di tutto devi creare un collegamento simbolico per la directory di archiviazione usando il comando artisan
php artisan storage:link
Quindi, in qualsiasi vista, puoi accedere alla tua immagine tramite l'URL helper in questo modo.
url('storage/avatars/image.png');
È bene salvare tutte le immagini e i documenti privati nella directory di archiviazione, quindi avrai il pieno controllo sull'etere del file e potrai consentire a determinati tipi di utenti di accedere al file o limitare.
Crea un percorso / documenti e punta a qualsiasi metodo del controller:
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']
);
}
Quando si preme il localhost:8000/docs
file verrà scaricato se esiste.
Il file deve essere nella root/storage/app/users/documents
directory in base al codice sopra, questo è stato testato Laravel 5.4
.
Se si desidera caricare un numero limitato di immagini private È possibile codificare le immagini in base64 ed eseguirne l'eco <img src="{{$image_data}}">
direttamente in:
$path = image.png
$full_path = Storage::path($path);
$base64 = base64_encode(Storage::get($path));
$image_data = 'data:'.mime_content_type($full_path) . ';base64,' . $base64;
Ho parlato di privato perché dovresti usare questi metodi solo se non vuoi archiviare immagini accessibili pubblicamente tramite url, invece devi sempre usare il modo standard (collega l'archiviazione / cartella pubblica e servi le immagini con il server HTTP).
Fai attenzione alla codifica per base64()
avere due lati negativi importanti:
Se stai usando php, usa semplicemente la funzione php symlink, come segue:
symlink('/home/username/projectname/storage/app/public', '/home/username/public_html/storage')
cambia il nome utente e il nome del progetto con i nomi giusti.
senza nome del sito
{{Storage::url($photoLink)}}
se si desidera aggiungere il nome del sito al suo esempio da aggiungere su api JSON felids
public function getPhotoFullLinkAttribute()
{
return env('APP_URL', false).Storage::url($this->attributes['avatar']) ;
}
Se sei come me e in qualche modo hai percorsi di file completi (ho fatto una corrispondenza del modello glob () sulle foto richieste, quindi finisco praticamente con percorsi di file completi) e la tua configurazione di archiviazione è ben collegata (cioè tale che i tuoi percorsi avere la stringa storage/app/public/
), quindi puoi usare il mio piccolo trucco sporco qui sotto: 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 '';
}
Se il disco 'local' non funziona per te, prova questo:
'default' => env('FILESYSTEM_DRIVER', 'public'),
daproject_folder/config/filesystem.php
php artisan config:clear
php artisan storage:link
Per ottenere l'URL dell'immagine caricata è possibile utilizzare questo Storage::url('iamge_name.jpg');