laravel - create - variable global para todos los controladores y vistas
globals laravel (11)
En Laravel tengo una configuración de tabla y he obtenido datos completos de la tabla en el BaseController, como sigue
public function __construct()
{
// Fetch the Site Settings object
$site_settings = Setting::all();
View::share(''site_settings'', $site_settings);
}
Ahora quiero acceder a $ site_settings. en todos los otros controladores y vistas para que no tenga que escribir el mismo código una y otra vez, así que cualquiera por favor dígame la solución o de otra forma, así puedo obtener los datos de la tabla una vez y usarlos en todos los controladores y ver.
Al principio, un archivo de configuración es apropiado para este tipo de cosas, pero también puede usar otro enfoque, que es el que se detalla a continuación (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''));
});
Para obtener los mismos datos en cualquier controlador, puede usar:
$site_settings = app(''site_settings'');
Hay muchas formas, solo use una u otra, cuál prefiere pero estoy usando el Container
.
De acuerdo, voy a ignorar por completo la ridícula cantidad de ingeniería excesiva y las suposiciones de que las otras respuestas están llenas, y sigo con la opción simple.
Si está de acuerdo con que haya una única llamada a la base de datos durante cada solicitud, entonces el método es simple y alarmante:
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);
}
}
Ahora, siempre que todos sus controladores amplíen este BaseController, pueden hacer $this->site_settings
.
Si desea limitar la cantidad de consultas en varias solicitudes, podría usar una solución de almacenamiento en caché como se proporcionó anteriormente, pero en función de su pregunta, la respuesta simple es una propiedad de clase.
En Laravel 5+, para establecer una variable una sola vez y acceder a ella ''globalmente'', me resulta más fácil simplemente agregarla como un atributo a la Solicitud:
$request->attributes->add([''myVar'' => $myVar]);
Luego puede acceder desde cualquiera de sus controladores utilizando:
$myVar = $request->get(''myVar'');
y de cualquiera de tus blades usando:
{{ Request::get(''myVar'') }}
En Laravel 5.1 necesitaba una variable global poblada con datos de modelos accesibles en todas las vistas.
Seguí un enfoque similar a la respuesta de ollieread y pude usar mi variable ($ notificaciones) en cualquier vista.
La ubicación de mi controlador: /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);
}
}
La ubicación de mi modelo: /app/Models/Main.php
namespace App/Models;
use Illuminate/Database/Eloquent/Model;
use DB;
class Main extends Model
{
public function get_notifications() {...
En Laravel, 5+ puedes crear un archivo en la carpeta de configuración y crear variables y usar eso en la aplicación. Por ejemplo, quiero almacenar información basada en el sitio. Creo un archivo llamado siteVars.php
, que se parece a esto
<?php
return [
''supportEmail'' => ''[email protected]'',
''adminEmail'' => ''[email protected]''
];
Ahora en las routes
, controller
, views
puedes acceder usando
Config::get(''siteVars.supportEmail'')
En las vistas si esto
{{ Config::get(''siteVars.supportEmail'') }}
Le dará a [email protected]
Espero que esto ayude.
Hay dos opciones:
Crea un archivo php class dentro de la aplicación / libraries / YourClassFile.php
a. Cualquier función que cree en ella sería fácilmente accesible en todas las vistas y controladores.
segundo. Si se trata de una función estática, puede acceder fácilmente por el nombre de la clase.
do. Asegúrate de incluir "aplicaciones / bibliotecas" en el mapa de clases de autocarga en el archivo del compositor.
En app / config / app.php crea una variable y puedes hacer referencia a la misma usando
Config :: get (''variable_name'');
Espero que esto ayude.
Editar 1:
Ejemplo para mi 1er punto:
// 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();
La mayoría de las respuestas populares aquí con BaseController no funcionaron para mí en Laravel 5.4, pero han funcionado en 5.3. No tengo idea por qué.
He encontrado una manera que funciona en Laravel 5.4 y proporciona variables incluso para vistas que omiten controladores. Y, por supuesto, puede obtener variables de la base de datos.
agregue su 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édito: http://laraveldaily.com/global-variables-in-base-controller/
Si le preocupa el acceso repetido a la base de datos, asegúrese de tener algún tipo de almacenamiento en caché integrado en su método, de modo que las llamadas a la base de datos solo se realicen una vez por solicitud de página.
Algo así como (ejemplo simplificado):
class Settings {
static protected $all;
static public function cachedAll() {
if (empty(self::$all)) {
self::$all = self::all();
}
return self::$all;
}
}
Luego accedería a Settings::cachedAll()
lugar de a all()
y esto solo haría una solicitud de base de datos por página. Las llamadas posteriores utilizarán los contenidos ya recuperados en caché en la variable de clase.
El ejemplo anterior es súper simple y utiliza una memoria caché en memoria, por lo que solo dura para la solicitud individual. Si quisieras, podrías usar el almacenamiento en caché de Laravel (usando Redis o Memcached) para persistir en tus configuraciones en múltiples solicitudes. Puede leer más sobre las opciones de almacenamiento en caché muy simples aquí:
Por ejemplo, podría agregar un método a su modelo de Settings
que tenga este aspecto:
static public function getSettings() {
$settings = Cache::remember(''settings'', 60, function() {
return Settings::all();
});
return $settings;
}
Esto solo haría una llamada a la base de datos cada 60 minutos; de lo contrario, devolvería el valor almacenado en caché cada vez que llame a Settings::getSettings()
.
Use la clase Config:
Config::set(''site_settings'', $site_settings);
Config::get(''site_settings'');
http://laravel.com/docs/4.2/configuration
Los valores de configuración que se configuran en tiempo de ejecución solo se configuran para la solicitud actual y no se trasladarán a solicitudes posteriores.
Veo, esto todavía es necesario para 5.4+ y tuve el mismo problema, pero ninguna de las respuestas fue lo suficientemente limpia, así que traté de lograr la disponibilidad con ServiceProviders
. Aquí esta lo que hice:
- Creado el Provider
SettingsServiceProvider
php artisan make:provider SettingsServiceProvider
- Creé el Modelo que necesitaba (
GlobalSettings
)
php artisan make:model GlobalSettings
- Editó el método de
register
generado en/App/Providers/SettingsServiceProvider
. Como puede ver, recupero mis configuraciones usando el modelo elocuente para él conSetting::all()
.
public function register()
{
$this->app->singleton(''App/GlobalSettings'', function ($app) {
return new GlobalSettings(Setting::all());
});
}
- Definió algunos parámetros y métodos útiles (incluido el constructor con el parámetro de
GlobalSettings
necesario) enGlobalSettings
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 */ }
}
- Por fin
config/app.php
el proveedor enconfig/app.php
''providers'' => [
// [...]
App/Providers/SettingsServiceProvider::class
]
- Después de borrar la caché de configuración con
php artisan config:cache
, puede usar su singleton de la siguiente manera.
$foo = app(App/GlobalSettings::class);
echo $foo->has("company") ? $foo->get("company") : "Stack Exchange Inc.";
Puede leer más acerca de los contenedores de servicios y proveedores de servicios en Laravel Docs> Service Container y Laravel Docs> Proveedores de servicios.
Esta es mi primera respuesta y no tuve mucho tiempo para escribirla, por lo que el formato es un poco escaso, pero espero que lo tengas todo.
Olvidé incluir el método de boot
de SettingsServiceProvider
, para que la variable de configuración global esté disponible en las vistas, así que aquí tienes:
public function boot(GlobalSettings $settinsInstance)
{
View::share(''globalsettings'', $settinsInstance);
}
Antes de llamar a los métodos de arranque, se han registrado todos los proveedores, por lo que solo podemos usar nuestra instancia de GlobalSettings
como parámetro, para que pueda ser inyectada por Laravel.
En la plantilla de la cuchilla:
{{ $globalsettings->get("company") }}
View::share(''site_settings'', $site_settings);
añadir
app->Providers->AppServiceProvider
método de arranque del archivo app->Providers->AppServiceProvider
es una variable global.