Глобальная переменная для всех контроллеров и просмотров
В Laravel У меня есть настройки таблицы, и я получил полные данные из таблицы в BaseController, как показано ниже.
public function __construct()
{
// Fetch the Site Settings object
$site_settings = Setting::all();
View::share('site_settings', $site_settings);
}
Теперь я хочу получить доступ к $site_settings. во всех других контроллерах и представлениях, так что мне не нужно писать один и тот же код снова и снова, поэтому кто-нибудь, пожалуйста, скажите мне решение или любым другим способом, чтобы я мог однажды извлечь данные из таблицы и использовать их во всех контроллерах и вид.
Ответы
Ответ 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
. Вот что я сделал:
- Создан провайдер
SettingsServiceProvider
php artisan make:provider SettingsServiceProvider
- Создана нужная мне модель (
GlobalSettings
)
php artisan make:model GlobalSettings
- Отредактировал созданный метод
register
в \App\Providers\SettingsServiceProvider
. Как видите, я извлекаю свои настройки, используя для этого красноречивую модель с помощью Setting::all()
.
public function register()
{
$this->app->singleton('App\GlobalSettings', function ($app) {
return new GlobalSettings(Setting::all());
});
}
- Определены некоторые полезные параметры и методы (включая конструктор с необходимым параметром
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 */ }
}
- Наконец я зарегистрировал провайдера в
config/app.php
'providers' => [
// [...]
App\Providers\SettingsServiceProvider::class
]
- После очистки кеша конфигурации с помощью
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();