web-dev-qa-db-fra.com

Laravel 5 - Comment accéder aux images chargées en stockage dans View?

Les avatars des utilisateurs sont téléchargés dans le stockage Laravel. Comment puis-je y accéder et les rendre dans une vue?

Le serveur pointe toutes les demandes sur /public, alors comment puis-je les afficher si elles se trouvent dans le dossier /storage?

145
Tadeáš Jílek

La meilleure approche consiste à créer un lien symbolique comme @SlateEntropy souligné dans la réponse ci-dessous . Pour vous aider avec ceci, depuis la version 5.3, Laravel inclut une commande , ce qui rend cela incroyablement facile à faire:

php artisan storage:link

Cela crée un lien symbolique de public/storage vers storage/app/public pour vous et c’est tout. Désormais, tous les fichiers de /storage/app/public sont accessibles via un lien tel que:

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

Si, pour une raison quelconque, vous ne pouvez pas créer de lien symbolique (vous êtes peut-être sur un hébergement partagé, etc.) ou si vous souhaitez protéger certains fichiers derrière une logique de contrôle d'accès, vous pouvez utiliser un itinéraire spécial qui lit et sert l'image. Par exemple, un itinéraire de fermeture simple comme celui-ci:

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

Vous pouvez maintenant accéder à vos fichiers comme si vous aviez un lien symbolique:

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

Si vous utilisez la Intervention Image Library , vous pouvez utiliser sa méthode intégrée response pour rendre les choses plus succinctes:

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

WARNING

Gardez à l'esprit que, en servant manuellement les fichiers que vous subissez une pénalité de performance , car vous parcourez tout le cycle de vie de la demande Laravel afin de lire et d’envoyer le contenu du fichier, ce qui est considérablement plus lent que d'avoir le serveur HTTP à gérer.

297
Bogdan

Une option serait de créer un lien symbolique entre un sous-dossier de votre répertoire de stockage et un répertoire public.

Par exemple

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

C'est également la méthode utilisée par Envoyer , un gestionnaire de déploiement construit par Taylor Otwell, le développeur de Laravel.

49
SlateEntropy

Selon Laravel 5.2 docs, vos fichiers accessibles au public doivent être placés dans un répertoire.

storage/app/public

Pour les rendre accessibles depuis le Web, vous devez créer un lien symbolique de public/storage à storage/app/public.

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

Vous pouvez maintenant créer dans votre vue une URL vers les fichiers à l'aide de l'assistant d'actifs:

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

Si vous êtes sur Windows, vous pouvez exécuter cette commande sur cmd:

mklink /j /path/to/laravel/public/avatars /path/to/laravel/storage/avatars 

à partir de: http://www.sevenforums.com/tutorials/278262-mklink-create-use-links-windows.html

14
cabs

Tout d’abord, vous devez créer un lien symbolique pour le répertoire de stockage en utilisant la commande artisan.

php artisan storage:link

Dans n'importe quelle vue, vous pouvez accéder à votre image via url helper comme ceci.

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

Il est bon de sauvegarder toutes les images et documents privés dans le répertoire de stockage, vous aurez alors un contrôle total sur les fichiers. Vous pouvez autoriser certains types d’utilisateurs à accéder au fichier ou à le restreindre.

Créez un itinéraire/une documentation et pointez sur n’importe quelle méthode de contrôleur:

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

Lorsque vous appuierez sur la touche localhost:8000/docs, le fichier sera téléchargé, le cas échéant.

Le fichier doit être dans le répertoire root/storage/app/users/documents conformément au code ci-dessus, cela a été testé sur Laravel 5.4.

3
Syed Shibli

Si vous utilisez php, utilisez simplement la fonction php symlink, comme suit:

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

remplacez le nom d'utilisateur et le nom du projet par les bons noms.

2
dagogodboss

Si vous souhaitez charger un petit nombre d'images Private Vous pouvez coder les images au format base64 et les répercuter directement dans <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;

J'ai mentionné privé parce que vous ne devriez utiliser ces méthodes que si vous ne voulez pas stocker d'images accessibles publiquement via une URL, mais vous devez toujours utiliser la méthode standard (stockage de liens/dossier public et diffusion d'images avec un serveur HTTP).

Méfiez-vous l'encodage en base64() a deux inconvénients importants:

  1. Cela augmentera la taille de l’image d’environ 30%.
  2. Vous combinez toutes les tailles d'images en une seule demande, au lieu de les charger en parallèle, cela ne devrait pas poser de problème pour certaines petites vignettes, mais pour de nombreuses images, évitez d'utiliser cette méthode.
2
Arash Moosapour

sans nom de site

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

si vous souhaitez ajouter un nom de site à cet exemple, à ajouter aux félidés JSON de l'API

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

Si vous êtes comme moi et que vous avez en quelque sorte les chemins de fichiers complets (j’ai fait quelques correspondances glob () sur les photos requises afin de me retrouver avec des chemins de fichiers complets), et votre configuration de stockage est bien liée = (c’est-à-dire que vos chemins ont la chaîne storage/app/public/), alors vous pouvez utiliser mon petit bidouillage sale ci-dessous: 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
Damilola Olowookere