Laravel: ¿Dónde almacenar datos y constantes de matrices globales?

82

Acabo de empezar a trabajar con Laravel. Necesito reescribir todo un sistema que hice hace algunos años, usando Laravel 4 como marco base. En mi antiguo sistema, solía tener un constant.phparchivo con algunas constantes declaradas y un globals.phparchivo que contenía muchos conjuntos de matrices (por ejemplo, estados de categorías, tipo de eventos, langs, etc.). Al hacerlo, podría usar algo como

foreach ( $langs as $code => $domain ) {
    // Some stuff
}

en cualquier lugar de mi aplicación.

Mi pregunta es, ¿cómo puedo almacenar esa información en la llamada "forma laravel". Intenté usar algún tipo de objeto para almacenar esta información, configurándolo como un servicio y creando para él una fachada:

aplicación / bibliotecas / Proyecto / Constants.php

namespace PJ;

class Constants {

    public static $langs = [
            'es' => 'www.domain.es',
            'en' => 'www.domain.us',
            'uk' => 'www.domain.uk',
            'br' => 'www.domain.br',
            'it' => 'www.domain.it',
            'de' => 'www.domain.de',
            'fr' => 'www.domain.fr'
        ];
}

aplicación / bibliotecas / Proyecto / ConstantsServiceProvider.php

namespace PJ;

use Illuminate\Support\ServiceProvider;

class ConstantsServiceProvider extends ServiceProvider {
    public function register() {
        $this->app->singleton('PJConstants', function() {
            return new Constants;
        });
    }
}

aplicación / bibliotecas / Proyecto / ConstantsFacade.php

namespace PJ;

use Illuminate\Support\Facades\Facade;

class ConstantsFacade extends Facade {
    protected static function getFacadeAccessor() { 
        return 'PJConstants';
    }
}

composer.json

"psr-4": {
     "PJ\\": "app/libraries/Project"
},

y así accedo a esa propiedad como PJ\Constants::$langs.

Esto funciona, pero dudo que sea la forma más eficiente o correcta de hacerlo. Quiero decir, ¿es la forma correcta de "propagar" una variable mediante la creación de un proveedor de servicios completo y fachadas y todo eso? ¿O dónde debería poner estos datos?

Gracias por cualquier consejo.

EDITAR # 01

Los datos que quiero pasar a todos los controladores y las vistas se pueden configurar directamente en un script, como en el ejemplo al comienzo de mi publicación, pero también se pueden generar dinámicamente, desde una base de datos, por ejemplo. Estos datos pueden ser una lista de categorías. Los necesito en todas las vistas para generar una barra de navegación, pero también los necesito para definir algunos patrones de enrutamiento (como /category/subcategory/product), y también para analizar información en varios controladores (como obtener información de la categoría que contiene el producto X).

Mi matriz es algo como:

$categories = [
    1 => ['name' => 'General', 'parent' => 0, 'description' => 'Lorem ipsum...'],
    2 => ['name' => 'Nature', 'parent' => 0, 'description' => 'Lorem ipsum...'],
    3 => ['name' => 'World', 'parent' => 0, 'description' => 'Lorem ipsum...'],
    4 => ['name' => 'Animals', 'parent' => 2, 'description' => 'Lorem ipsum...']
]

Solo como un ejemplo. El índice es la identificación de la categoría y el valor es la información asociada con la categoría.

Necesito esta matriz, también, disponible en todos los controladores y vistas.

Entonces, ¿debería guardarlo como una variable de configuración? ¿De qué otra manera podría almacenar estos datos? ¿Cuál sería la mejor y semánticamente correcta forma?

Marco Madueño Mejía
fuente

Respuestas:

117

Para la mayoría de las constantes utilizadas globalmente en la aplicación, es suficiente almacenarlas en archivos de configuración. También es bastante simple

Cree un nuevo archivo en el app/configdirectorio. Vamos a llamarloconstants.php

Allí debe devolver una matriz de valores de configuración.

return [
    'langs' => [
        'es' => 'www.domain.es',
        'en' => 'www.domain.us'
        // etc
    ]
];

Y puede acceder a ellos de la siguiente manera

Config::get('constants.langs');
// or if you want a specific one
Config::get('constants.langs.en');

Y también puedes configurarlos

Config::set('foo.bar', 'test');

Tenga en cuenta que los valores que establezca no se mantendrán. Solo están disponibles para la solicitud actual.

Actualizar

La configuración probablemente no sea el lugar adecuado para almacenar la información generada a partir de la base de datos. Podrías usar un modelo elocuente como:

class Category extends Eloquent {
    // db table 'categories' will be assumed
}

Y consulta todas las categorías

Category::all();

Si todo el asunto del Modelo por alguna razón no funciona, puede comenzar a pensar en crear su propia clase y una fachada. O simplemente puede crear una clase con todas las variables y métodos estáticos y luego usarla sin las cosas de la fachada.

lukasgeiter
fuente
¡Manera fácil! Hacerlo así es bueno para "matrices constantes" ya establecidas en el código del proyecto. Pero, ¿qué pasa con las variables o matrices generadas en tiempo de ejecución a las que quiero acceder globalmente desde cualquier otro lugar? Tengo un código de inicio básico en global.php, y algunas variables se crean allí que necesitaré después en algunos controladores o vistas. ¿Hay alguna forma de establecer el valor de esas variables de configuración, o incluso crear nuevas en tiempo de ejecución?
Marco Madueño Mejía
No pensé que pudiera ser tan fácil. Lo marcaré como respuesta, pero tengo una última duda al respecto. Una de esas variables que necesito hacer accesible globalmente contiene un conjunto de categorías tomadas de la base de datos. Es necesario para todas las vistas, ya que se utilizará para el menú de navegación, pero también es necesario en algunos controladores e incluso para el enrutamiento. ¿Es correcto (semánticamente hablando) guardar este tipo de datos como una variable de configuración? ¿O debería almacenarlo de otra manera?
Marco Madueño Mejía
2
@Corner desde 5.0, el directorio de configuración se encuentra directamente en la raíz del directorio de su proyecto.
lukasgeiter
4
Para las personas que usan Laravel 5 o superior, debe agregar 'use Config;' en su controlador o ponga una barra en la fuente de Config como esta: \ Config :: get ('constants.langs');
rotaercz
2
Puede usar el config()asistente en lugar de usar Config::get()ahora.
Leith
23

Para constantes

Cree el archivo constants.php en el directorio de configuración: -

define('YOUR_DEFINED_CONST', 'Your defined constant value!');

return [

'your-returned-const' => 'Your returned constant value!'

];

Puedes usarlos como: -

echo YOUR_DEFINED_CONST . '<br>';

echo config('constants.your-returned-const');

Para matrices estáticas

Cree el archivo static_arrays.php en el directorio de configuración: -

class StaticArray
{

    public static $langs = [
        'es' => 'www.domain.es',
        'en' => 'www.domain.us',
        'uk' => 'www.domain.uk',
        'br' => 'www.domain.br',
        'it' => 'www.domain.it',
        'de' => 'www.domain.de',
        'fr' => 'www.domain.fr'
    ];

}

Puedes usarlo como: -

echo StaticArray::$langs['en'];

Nota: Laravel incluye todos los archivos de configuración automáticamente, por lo que no es necesario incluirlos manualmente :)

Gagandeep Gambhir
fuente
No disponible en algunos comandos de la consola como route:cache:Use of undefined constant ID - assumed 'ID'
AliN11
13

Crea un archivo de constantes comunes en Laravel

app / constants.php

    define('YOUR_CONSTANT_VAR', 'VALUE');

    //EX
    define('COLOR_TWO', 'red');

composer.json agregue la ubicación del archivo en la carga automática en composer.json

"autoload": {
    "files": [
        "app/constants.php"
    ]
}

Antes de que este cambio entre en vigencia, debe ejecutar el siguiente comando en la Terminal para regenerar los archivos de carga automática de Laravel:

composer dump-autoload
Parth kharecha
fuente
1
Gracias por compartir. Me había olvidado de la carga automática: D
Channaveer Hakari
es un placer @ChannaveerHakari
Parth kharecha
8

Para las constantes globales en Laravel 5, no me gusta llamar a Config para ellas. Los defino en el grupo de Ruta así:

// global contants for all requests
Route::group(['prefix' => ''], function() {
    define('USER_ROLE_ADMIN','1');
    define('USER_ROLE_ACCOUNT','2');
});
Mladen Janjetovic
fuente
Si tengo una gran cantidad de constantes, ¿hay alguna manera de almacenarlas en otro (s) archivo (s) y luego incluirlas en la función de la ruta? Además, ¿qué está haciendo la línea ['prefix' => '']? Sé que es una matriz asociativa, pero ¿esto hace que las constantes estén disponibles para todas las rutas? Gracias.
user3089840
1
Ajá, bueno, descubrí la parte del prefijo: laravel.com/docs/5.1/routing#route-group-prefixes
user3089840
Otra nota al margen, no importa lo que haga, parece que a PHPUnit no le gusta. Cuando lo intento a tu manera, todo funciona bien en el navegador, pero PHPUnit me dice que mis constantes ya están definidas, y eso simplemente no es cierto.
user3089840
Si está almacenando en caché sus configuraciones, la definición de constantes en ellas no funcionará.
ceros y unos
Gran idea para usar el prefijo
Arun Yokesh
4

Creo que la mejor forma es utilizar la localización.

Cree un nuevo archivo messages.phpen resources/lang/en( enporque eso es lo que está configurado en mi config/app 'locale'=>'en') devuelva una matriz de todos sus valores

return [
    'welcome' => 'Welcome to our application'
];

para recuperar para laravel 5.3 y anteriores

echo trans('messages.welcome');

o

echo Lang::get('messages.welcome');

para uso 5.4

echo __('messages.welcome') 

localización de laravel 5.0

o

localización de laravel 5.4

Bill Stephen
fuente
Eso es correcto. La sub consulta de un novato es cómo leer ese archivo message.php y obtener el valor de la clave como matriz. Quiero leerlo como una matriz y enviarlo como respuesta json para mi biblioteca del lado del cliente, es decir, Angular JS para manejar ciertas cadenas.
Gopinath
2

Solo para agregar a la respuesta anterior, tendrá que incluir la clase de configuración antes de poder comenzar a usarla en Laravel 5.3

use Illuminate\Support\Facades\Config;
Jignesh Rawal
fuente
O simplemente use la función config ().
ademers
0

Simplemente coloque un archivo constants.php en el directorio de configuración y defina sus constantes en ese archivo, ese archivo se cargará automáticamente, probado en Laravel 6+

Ing. Syed Rowshan Ali
fuente