Подтвердить что ты не робот

Глобальная переменная для всех контроллеров и просмотров

В Laravel У меня есть настройки таблицы, и я получил полные данные из таблицы в BaseController, как показано ниже.

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

Теперь я хочу получить доступ к $site_settings. во всех других контроллерах и представлениях, так что мне не нужно писать один и тот же код снова и снова, поэтому кто-нибудь, пожалуйста, скажите мне решение или любым другим способом, чтобы я мог однажды извлечь данные из таблицы и использовать их во всех контроллерах и вид.

4b9b3361

Ответ 1

Сначала файл конфигурации подходит для такого рода вещей, но вы также можете использовать другой подход, который описан ниже (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'));
});

Чтобы получить те же данные в любом контроллере, вы можете использовать:

$site_settings = app('site_settings');

Есть много способов, просто используйте один или другой, который вы предпочитаете, но я использую Container.

Ответ 2

Хорошо, я собираюсь полностью игнорировать смехотворную сумму над разработкой и предположениями, что другие ответы изобилуют и идут с простым вариантом.

Если у вас все в порядке, чтобы быть единственным вызовом базы данных во время каждого запроса, тогда метод прост, тревожно:

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

}

Теперь, когда все ваши контроллеры расширяют этот BaseController, они могут просто сделать $this->site_settings.

Если вы хотите ограничить количество запросов несколькими запросами, вы можете использовать кэширующее решение, как было указано ранее, но на основе вашего вопроса простой ответ - это свойство класса.

Ответ 3

Используйте класс Config:

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

Config::get('site_settings');

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

Значения конфигурации, установленные во время выполнения, устанавливаются только для текущего запроса и не переносятся на последующие запросы.

Ответ 4

В Laravel 5.1 мне нужна глобальная переменная, заполненная данными модели, доступными во всех представлениях.

Я следовал аналогичному подходу к ответу ollieread и смог использовать мою переменную ($ notifications) в любом представлении.

Местоположение моего контроллера:/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);
    }
}

Расположение моей модели:/app/Models/Main.php

namespace App\Models;

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

class Main extends Model
{
    public function get_notifications() {...

Ответ 5

В Laravel, 5+, вы можете создать файл в папке config и создать в нем переменные и использовать его в приложении. Например, я хочу сохранить некоторую информацию на основе сайта. Я создаю файл с именем siteVars.php, который выглядит следующим образом

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

Теперь в routes, controller, views вы можете получить к нему доступ, используя

Config::get('siteVars.supportEmail')

В представлениях, если я это

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

Он отправит [email protected]

Надеюсь, что это поможет.

Ответ 6

Если вас беспокоит многократный доступ к базе данных, убедитесь, что у вас есть какое-то кэширование, встроенное в ваш метод, чтобы вызовы базы данных делались только один раз на запрос страницы.

Что-то вроде (упрощенный пример):

class Settings {

    static protected $all;

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

Затем вы получите доступ к Settings::cachedAll() вместо all(), и это приведет только к одному запросу базы данных на страницу. Последующие вызовы будут использовать уже полученное содержимое, кэшированное в переменной класса.

Приведенный выше пример очень прост и использует кеш в памяти, поэтому он длится только для одного запроса. Если вы захотите, вы можете использовать кеша Laravel (используя Redis или Memcached), чтобы сохранить свои настройки в нескольких запросах. Вы можете узнать больше о самых простых вариантах кеширования здесь:

http://laravel.com/docs/cache

Например, вы можете добавить метод в свою модель Settings, которая выглядит так:

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

Это вызовет только вызов базы данных каждые 60 минут, в противном случае оно вернет кешированное значение всякий раз, когда вы вызываете Settings::getSettings().

Ответ 7

Самые популярные ответы здесь, в BaseController, не работали для меня на Laravel 5.4, но они работали над 5.3. Не знаю, почему.

Я нашел способ, который работает на Laravel 5.4 и дает переменные даже для просмотров, которые пропускают контроллеры. И, конечно же, вы можете получить переменные из базы данных.

добавьте в свой 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); 
        });
    }
}

кредит: http://laraveldaily.com/global-variables-in-base-controller/

Ответ 8

Я вижу, что это все еще нужно для 5. 4+, и у меня просто была та же самая проблема, но ни один из ответов не был достаточно чист, поэтому я попытался добиться доступности с ServiceProviders. Вот что я сделал:

  1. Создан провайдер SettingsServiceProvider
    php artisan make:provider SettingsServiceProvider
  1. Создана нужная мне модель (GlobalSettings)
    php artisan make:model GlobalSettings
  1. Отредактировал созданный метод register в \App\Providers\SettingsServiceProvider. Как видите, я извлекаю свои настройки, используя для этого красноречивую модель с помощью Setting::all().
 

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

 
  1. Определены некоторые полезные параметры и методы (включая конструктор с необходимым параметром Collection) в 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. Наконец я зарегистрировал провайдера в config/app.php
 

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

        App\Providers\SettingsServiceProvider::class
    ]

 
  1. После очистки кеша конфигурации с помощью php artisan config:cache вы можете использовать ваш синглтон следующим образом.
 

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

 

Вы можете узнать больше о сервисных контейнерах и поставщиках услуг в Laravel Docs> Service Container и Laravel Docs> Поставщики услуг.

Это мой первый ответ, и у меня не было много времени, чтобы записать его, поэтому форматирование немного пространственное, но я надеюсь, что вы все поняли.


Я забыл включить boot метод SettingsServiceProvider, чтобы сделать переменную настроек глобальной доступной в представлениях, так что здесь вы идете:

 

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

 

Перед вызовом методов загрузки все провайдеры были зарегистрированы, поэтому мы можем просто использовать наш экземпляр GlobalSettings качестве параметра, чтобы он мог быть добавлен Laravel.

В шаблоне лезвия:

 

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

 

Ответ 9

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

Добавить в

app->Providers->AppServiceProvider способ загрузки файла

это глобальная переменная.

Ответ 10

В Laravel 5+, чтобы установить переменную всего один раз и получить к ней доступ "глобально", проще всего добавить ее в качестве атрибута в запрос:

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

Затем вы можете получить к нему доступ с любого из ваших контроллеров, используя:

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

и от любого из ваших лезвий, используя:

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

Ответ 11

Вы также можете использовать Laravel Helper, который я использую. Просто создайте папку " Helpers" в папке " App " и добавьте следующий код:

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

затем добавьте его в config> app.php под псевдонимами

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

1. Использовать в контроллере

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

2. Использовать в представлении:

Site::settings()

Ответ 12

Я нашел лучший способ, который работает на Laravel 5.5 и делает переменные доступными для представлений. И вы можете извлекать данные из базы данных, делать свою логику, импортируя вашу модель так же, как вы это делали бы в своем контроллере.

"*" Означает, что вы ссылаетесь на все виды, если вы исследуете больше, вы можете выбрать виды, которые будут влиять.

добавьте в свое приложение /Providers/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()
    {

    }
}

Ответ 13

Есть два варианта:

  • Создайте файл класса php внутри приложения/библиотеки/YourClassFile.php

    а. Любая функция, которую вы создаете в ней, будет легко доступна во всех представлениях и контроллерах.

    б. Если это статическая функция, вы можете легко получить к ней доступ по имени класса.

    с. Удостоверьтесь, что вы включили "приложение/библиотеки" в classlap для автозагрузки в файле композитора.

  • В app/config/app.php создайте переменную, и вы можете ссылаться на нее с помощью

    Config:: получить ( 'имя_переменной');

Надеюсь, что это поможет.

Изменить 1:

Пример для моей первой точки:

// app/libraries/DefaultFunctions.php

class DefaultFunctions{

    public static function getSomeValue(){
     // Fetch the Site Settings object
     $site_settings = Setting::all();
     return $site_settings; 
    }
}

//composer.json

"autoload": {
        "classmap": [
..
..
..  
        "app/libraries" // add the libraries to access globaly.
        ]
    }

 //YourController.php

   $default_functions  = new DefaultFunctions();
    $default_functions->getSomeValue();