web-dev-qa-db-fra.com

Comment devrais-je servir une image avec Laravel?

Je stocke les images de profil utilisateur dans le dossier de stockage laravel au lieu du dossier public, car je souhaite que le dossier public reste propre et sans encombrement.

Afin de servir une image de ce dossier, j'ai créé une action de contrôleur simple, comme suit:

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

Cela peut-il être considéré comme une bonne pratique, ou devrais-je simplement enregistrer des images dans le dossier public?

17
clod986

La réponse courte à votre question

Cela peut-il être considéré comme une bonne pratique, ou devrais-je simplement enregistrer des images dans le dossier public? Vais-je rencontrer des problèmes de performances d'ici Ce faisant?

Ce n'est pas une pratique recommandée, car vous lisez le fichier et le générez à nouveau, cela prendra du temps à charger et à charger le serveur, mais tout dépend du nombre de demandes, de la taille de l'image, etc. J'ai utilisé cette pratique pour sécuriser/protéger images/fichiers de l'accès public, de sorte que seul membre authentifié peut accéder aux images/fichiers comme il est dans cette réponse . Encore une fois, en fonction de la taille du fichier, du nombre de requêtes et de la spécification du serveur, je l'utilise depuis tout temps et je n'ai eu aucun problème de performances, cela a fonctionné correctement (mon serveur est une solution de 512 Mo, de mémoire, de CoreProcessor et de 20 GoSSD). Vous pourriez essayer pendant un moment et voir.

Solution de lien symbolique

Il est également possible de créer un lien symbolique comme

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

Cette solution n'affectera pas les performances, mais vous devez la documenter dans votre documentation interne si vous déplacez votre configuration vers un nouveau fournisseur ou si vous devez vous reconnecter au dossier de stockage. 

Mais si vous souhaitez toujours disposer de la solution complète pour renvoyer une image à partir d'un dossier de stockage, nous devons tout d'abord installer Intervention Image for Laravel. Je ne sais pas si cela est déjà fait ou non. Si vous l'avez installé, continuez ici, mais sinon, suivez la dernière partie de cette réponse et continuez avec la solution Laravel.

Solution de Laravel

Comme dit, nous supposons que votre intervention fonctionne, vous devez d’abord créer un itinéraire. La Route transmettra tous les accès aux demandes d’images à notre contrôleur.

Créer un itinéraire

Route::get('profile/{person}', 'ImagesController@profilePicture');

Après avoir créé un itinéraire, nous devons créer un contrôleur pour prendre en charge les demandes d’image de notre itinéraire. 

Create ImagesController

De commande 

php artisan make:controller ImagesController

Et votre contrôleur devrait ressembler à ceci.

class ImagesController extends Controller {

    public function profilePicture($person, $size = 40)
    {
        $storagePath = storage_path('/profile_pictures/' . $person . '/profile_' . $size . '.jpg');

        return Image::make($storagePath)->response();
    }
}

Et n'oubliez pas d'ajouter

use Intervention\Image\Facades\Image;

dans votre classe ImagesController

Enfin, assurez-vous d'avoir créé la structure de dossiers avec l'image test.

storage/profile_pictures/person/profile_40.jpg

Maintenant si vous écrivez dans votre navigateur

http://laravelLocalhostUrl/profile/person

Il montrera votre image, je me suis construit et le tester . enter image description here

Remarque: j'ai essayé de faire en sorte que le dossier reflète votre question, mais vous pouvez facilement le modifier pour l'adapter à votre guise.


Install Intervention (ignorez cette partie si vous l'avez déjà installée)

Suivez ces instructions: http://image.intervention.io/getting_started/installation } _

En bref: php composer require intervention/image

Et dans votre config/app, le tableau $ providers ajoute les fournisseurs de services pour ce paquet.

Intervention\Image\ImageServiceProvider::class

Ajoutez la façade de ce paquet au tableau $ aliases.

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

La solution inspirée de cette réponse mais celle-ci est de protéger l’image avec l’authentification en général et cette réponse .

29

L'utilisation de Laravel 5.2+ Image::make($pathToFile)->response() peut être considérée comme une mauvaise pratique. Toute personne à la recherche d'une solution pour servir des images de Laravel devrait utiliser return response() -> file($pathToFile, $headers);. Cela produira beaucoup moins de temps système, car il ne sert que le fichier au lieu de "l'ouvrir dans Photoshop" - du moins, c'est ce que dit mon moniteur de processeur.

Voici le lien vers la documentation

13
lukas83

Dans votre modèle User.php

protected $appends = ['avatar'];

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

Ainsi, chaque fois que vous appelez une instance get, vous aurez son avatar avec elle. 

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

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

0
zhwei