web-dev-qa-db-fra.com

variable globale pour tous les contrôleurs et vues

Dans Laravel, j'ai un tableau de paramètres et j'ai récupéré les données complètes de la table dans BaseController, comme suit 

public function __construct() 
{
    // Fetch the Site Settings object
    $site_settings = Setting::all();
    View::share('site_settings', $site_settings);
}

Maintenant, je veux accéder à $ site_settings. dans tous les autres contrôleurs et vues, de sorte que je n'ai pas besoin d'écrire le même code encore et encore, afin que tout le monde me dise s'il vous plaît la solution ou tout autre moyen afin que je puisse extraire les données de la table une fois et les utiliser dans tous les contrôleurs et vue.

40
Deepak Goyal

Au début, un fichier de configuration est approprié pour ce genre de choses, mais vous pouvez aussi utiliser une autre approche, qui est donnée ci-dessous (Laravel - 4):

// You can keep this in your filters.php file
App::before(function($request) {
    App::singleton('site_settings', function(){
        return Setting::all();
    });

    // If you use this line of code then it'll be available in any view
    // as $site_settings but you may also use app('site_settings') as well
    View::share('site_settings', app('site_settings'));
});

Pour obtenir les mêmes données dans n’importe quel contrôleur, vous pouvez utiliser:

$site_settings = app('site_settings');

Il y a plusieurs façons, utilisez simplement l’une ou l’autre, celle que vous préférez, mais j’utilise la variable Container.

38
The Alpha

D'accord, je vais complètement ignorer la quantité ridicule d'ingénierie excessive et d'hypothèses avec lesquelles les autres réponses sont légion, et opter pour la simple option.

Si vous êtes d'accord pour qu'il y ait un seul appel de base de données lors de chaque demande, la méthode est simple, ce qui est alarmant:

class BaseController extends \Controller
{

    protected $site_settings;

    public function __construct() 
    {
        // Fetch the Site Settings object
        $this->site_settings = Setting::all();
        View::share('site_settings', $this->site_settings);
    }

}

Maintenant, à condition que tous vos contrôleurs étendent ce BaseController, ils peuvent simplement faire $this->site_settings.

Si vous souhaitez limiter le nombre de requêtes sur plusieurs requêtes, vous pouvez utiliser une solution de mise en cache telle que fournie précédemment, mais en fonction de votre question, la réponse simple est une propriété de classe.

37
ollieread

Utilisez la classe de configuration:

Config::set('site_settings', $site_settings);

Config::get('site_settings');

http://laravel.com/docs/4.2/configuration

Les valeurs de configuration définies au moment de l'exécution ne sont définies que pour la demande en cours et ne seront pas reprises dans les demandes suivantes.

20
malhal

Dans Laravel 5, vous pouvez créer un fichier dans le dossier config, y créer des variables et l'utiliser dans l'application. Par exemple, je veux stocker des informations basées sur le site . Je crée un fichier appelé siteVars.php, Qui ressemble à ceci

<?php
return [
    'supportEmail' => '[email protected]',
    'adminEmail' => '[email protected]'
];

Maintenant, dans les routes, controller, views vous pouvez y accéder en utilisant 

Config::get('siteVars.supportEmail')

Dans les vues si je cela

{{ Config::get('siteVars.supportEmail') }}

Cela donnera [email protected]

J'espère que cela t'aides.

5
Koushik Das

Dans Laravel 5.1, j'avais besoin d'une variable globale contenant des données de modèle accessibles dans toutes les vues.

J'ai suivi une approche similaire à la réponse d'ollieread et j'ai pu utiliser ma variable ($ notifications) dans n'importe quelle vue.

Mon emplacement de contrôleur: /app/Http/Controllers/Controller.php

<?php

namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;

use App\Models\Main as MainModel;
use View;

abstract class Controller extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function __construct() {
        $oMainM = new MainModel;
        $notifications = $oMainM->get_notifications();
        View::share('notifications', $notifications);
    }
}

Mon emplacement de modèle: /app/Models/Main.php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use DB;

class Main extends Model
{
    public function get_notifications() {...
5
Martin Carstens

Si vous craignez un accès répété à la base de données, assurez-vous que votre méthode dispose d'une sorte de cache afin que les appels à la base de données ne soient effectués qu'une seule fois par demande de page.

Quelque chose comme (exemple simplifié):

class Settings {

    static protected $all;

    static public function cachedAll() {
        if (empty(self::$all)) {
           self::$all = self::all();
        }
        return self::$all;
    }
}

Ensuite, vous accéderiez à Settings::cachedAll() au lieu de all() et vous ne feriez qu’un appel de base de données par requête de page. Les appels suivants utiliseront le contenu déjà récupéré et mis en cache dans la variable de classe.

L'exemple ci-dessus est très simple et utilise un cache en mémoire pour qu'il ne dure que pour une requête unique. Si vous le souhaitez, vous pouvez utiliser la mise en cache de Laravel (à l'aide de Redis ou de Memcached) pour conserver vos paramètres dans plusieurs demandes. Vous pouvez en savoir plus sur les options de mise en cache très simples ici:

http://laravel.com/docs/cache

Par exemple, vous pouvez ajouter à votre modèle Settings une méthode ressemblant à ceci:

static public function getSettings() {
    $settings = Cache::remember('settings', 60, function() {
        return Settings::all();
    });
    return $settings;
}

Cela ne ferait qu'un appel de base de données toutes les 60 minutes, sinon la valeur mise en cache serait renvoyée à chaque appel de Settings::getSettings().

3
Seb Barre

Les réponses les plus populaires ici avec BaseController n'ont pas fonctionné pour moi sous Laravel 5.4, mais elles ont fonctionné sous 5.3. Aucune idée pourquoi.

J'ai trouvé un moyen qui fonctionne sur Laravel 5.4 et donne des variables même pour les vues ignorant les contrôleurs. Et, bien sûr, vous pouvez obtenir des variables de la base de données.

ajoutez dans votre app/Providers/AppServiceProvider.php

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // Using view composer to set following variables globally
        view()->composer('*',function($view) {
            $view->with('user', Auth::user());
            $view->with('social', Social::all()); 
            // if you need to access in controller and views:
            Config::set('something', $something); 
        });
    }
}

crédit: http://laraveldaily.com/global-variables-in-base-controller/

3
Gediminas

Je vois que cela est toujours nécessaire pour la version 5.4+ et que je n’avais que le même problème, mais qu’aucune des réponses n’était suffisamment claire, j’ai donc essayé d’obtenir la disponibilité avec ServiceProviders. Voici ce que j'ai fait:

  1. Créé le fournisseur SettingsServiceProvider
 Fabricant de php artisan: fournisseur SettingsServiceProvider 
  1. Créé le modèle dont j'avais besoin (GlobalSettings)
 Fabrication artisanale php: modèle GlobalSettings 
  1. Edité la méthode register générée dans \App\Providers\SettingsServiceProvider. Comme vous pouvez le constater, je récupère mes paramètres en utilisant le modèle éloquent correspondant à Setting::all().


    public function register()
    {
        $this->app->singleton('App\GlobalSettings', function ($app) {
            return new GlobalSettings(Setting::all());
        });
    }

  1. Défini quelques paramètres et méthodes utiles (y compris le constructeur avec le paramètre Collection nécessaire) dans GlobalSettings


    class GlobalSettings extends Model
    {
        protected $settings;
        protected $keyValuePair;

        public function __construct(Collection $settings)
        {
            $this->settings = $settings;
            foreach ($settings as $setting){
                $this->keyValuePair[$setting->key] = $setting->value;
            }
        }

        public function has(string $key){ /* check key exists */ }
        public function contains(string $key){ /* check value exists */ }
        public function get(string $key){ /* get by key */ }
    }

  1. Enfin, j'ai enregistré le fournisseur dans config/app.php


    'providers' => [
        // [...]

        App\Providers\SettingsServiceProvider::class
    ]

  1. Après avoir effacé le cache de configuration avec php artisan config:cache, vous pouvez utiliser votre singleton comme suit.


    $foo = app(App\GlobalSettings::class);
    echo $foo->has("company") ? $foo->get("company") : "Stack Exchange Inc.";

Pour en savoir plus sur les conteneurs de services et les fournisseurs de services, accédez à Laravel Docs> Service Container et à Laravel Docs> Fournisseurs de services.

C’est ma première réponse et j’ai eu peu de temps pour la rédiger. Le formatage est un peu trop volumineux, mais j’espère que vous aurez tout.


J'ai oublié d'inclure la méthode boot de SettingsServiceProvider, afin de rendre les paramètres variables globaux disponibles dans les vues, alors voici:



    public function boot(GlobalSettings $settinsInstance)
    {
        View::share('globalsettings', $settinsInstance);
    }

Avant que les méthodes de démarrage ne soient appelées, tous les fournisseurs ont été enregistrés. Nous pouvons donc simplement utiliser notre instance GlobalSettings en tant que paramètre pour qu'elle puisse être injectée par Laravel.

Dans le modèle de lame:



    {{ $globalsettings->get("company") }}

3
nbsp
View::share('site_settings', $site_settings);

Ajouter à 

méthode de démarrage du fichier app->Providers->AppServiceProvider

c'est la variable globale.

2
Rasim

Dans Laravel 5+, pour définir une variable une seule fois et y accéder «globalement», il est plus facile de l'ajouter simplement en tant qu'attribut à la requête:

$request->attributes->add(['myVar' => $myVar]);

Ensuite, vous pouvez y accéder depuis n’importe quel de vos contrôleurs en utilisant:

$myVar = $request->get('myVar');

et de n'importe lequel de vos lames en utilisant:

{{ Request::get('myVar') }}
1
spedley

J'ai trouvé un meilleur moyen de fonctionner avec Laravel 5.5 et de rendre les variables accessibles par les vues. Et vous pouvez récupérer des données de la base de données, faire votre logique en important votre modèle comme vous le feriez dans votre contrôleur.

Le "*" signifie que vous faites référence à toutes les vues. Si vous recherchez plus, vous pouvez choisir les vues à affecter.

ajouter dans votre application/Fournisseurs/AppServiceProvider.php

<?php

    namespace App\Providers;

    use Illuminate\Contracts\View\View;

    use Illuminate\Support\ServiceProvider;
    use App\Setting;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
    */
    public function boot()
    {
        // Fetch the Site Settings object
        view()->composer('*', function(View $view) {
            $site_settings = Setting::all();
            $view->with('site_settings', $site_settings);
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {

    }
}
0
Etimbuk

Vous pouvez également utiliser Laravel helper que j'utilise . Créez simplement Helpers dossier sous App dossier Puis ajoutez le code suivant:

namespace App\Helpers;
Use SettingModel;
class SiteHelper
{
    public static function settings()
    {
        if(null !== session('settings')){
          $settings = session('settings');
        }else{
          $settings = SettingModel::all();
          session(['settings' => $settings]);
        }
        return $settings;
    }
}

puis ajoutez-le sur config> app.php sous alliases

'aliases' => [
....
'Site' => App\Helpers\SiteHelper::class,
]

1. À utiliser dans Contrôleur

use Site;
class SettingsController extends Controller
{
    public function index()
    {
        $settings = Site::settings();
        return $settings;
    }
}

2. À utiliser dans Voir

Site::settings()
0
Joesel T Duazo