Laravel: Gdzie przechowywać dane i stałe dotyczące tablic globalnych?

82

Właśnie zacząłem pracować z Laravelem. Muszę przepisać cały system, który zrobiłem kilka lat temu, używając Laravel 4 jako podstawy. W moim starym systemie miałem constant.phpplik z zadeklarowanymi stałymi i globals.phpplik, który zawierał wiele zestawów tablic (na przykład statusy kategorii, typy zdarzeń, języki itp.). Robiąc to, mógłbym użyć czegoś takiego

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

w dowolnym miejscu mojej aplikacji.

Moje pytanie brzmi, jak mogę przechowywać te informacje w tak zwany „laravel way”. Próbowałem użyć jakiegoś obiektu do przechowywania tych informacji, ustawiając to jako usługę i tworząc dla niego fasadę:

app / libraries / Project / 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'
        ];
}

app / libraries / Project / ConstantsServiceProvider.php

namespace PJ;

use Illuminate\Support\ServiceProvider;

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

app / libraries / Project / 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"
},

więc mam dostęp do tej właściwości jako PJ\Constants::$langs.

To działa, ale wątpię, czy jest to najbardziej efektywny lub poprawny sposób na zrobienie tego. Chodzi mi o to, czy jest to właściwy sposób na „propagowanie” zmiennej poprzez tworzenie całego usługodawcy, fasad i tego typu rzeczy? Albo gdzie mam umieścić te dane?

Dzięki za każdą radę.

EDYCJA # 01

Dane, które chcę przekazać do wszystkich kontrolerów i widoków można ustawić bezpośrednio w skrypcie, jak w przykładzie na początku mojego wpisu, ale można je też generować dynamicznie, np. Z bazy danych. Te dane mogą być listą kategorii. Potrzebuję ich we wszystkich widokach, aby wygenerować pasek nawigacji, ale potrzebuję ich również do zdefiniowania niektórych wzorców routingu (takich jak /category/subcategory/product), a także do przeanalizowania niektórych informacji w kilku kontrolerach (na przykład uzyskanie informacji z kategorii, która zawiera produkt X).

Moja tablica to coś takiego:

$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...']
]

Jako przykład. Indeks to identyfikator kategorii, a wartość to informacje skojarzone z kategorią.

Potrzebuję tej tablicy, również dostępnej we wszystkich kontrolerach i widokach.

Czy powinienem zatem zapisać go jako zmienną konfiguracyjną? Jak inaczej mógłbym przechowywać te dane; jaki byłby najlepszy i poprawny semantycznie sposób?

Marco Madueño Mejía
źródło

Odpowiedzi:

118

W przypadku większości stałych używanych globalnie w całej aplikacji wystarczy przechowywać je w plikach konfiguracyjnych. Jest to również całkiem proste

Utwórz nowy plik w app/configkatalogu. Nazwijmy toconstants.php

Tam musisz zwrócić tablicę wartości konfiguracyjnych.

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

Dostęp do nich można uzyskać w następujący sposób

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

Możesz je również ustawić

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

Zwróć uwagę, że ustawione wartości nie zostaną zachowane. Są dostępne tylko dla bieżącego żądania.

Aktualizacja

Konfiguracja prawdopodobnie nie jest odpowiednim miejscem do przechowywania informacji wygenerowanych z bazy danych. Możesz po prostu użyć Elokwentnego Modelu, takiego jak:

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

I przeszukaj wszystkie kategorie

Category::all();

Jeśli z jakiegoś powodu cała sprawa z Modelami nie wychodzi, możesz zacząć myśleć o stworzeniu własnej klasy i fasady. Lub możesz po prostu utworzyć klasę ze wszystkimi statycznymi zmiennymi i metodami, a następnie użyć jej bez elementów fasady.

lukasgeiter
źródło
Łatwy sposób! Robienie tego w ten sposób jest przyjemne dla „stałych tablic” już ustawionych w kodzie projektu. Ale co ze zmiennymi lub tablicami generowanymi w czasie wykonywania, do których chcę mieć globalny dostęp z dowolnego miejsca. Mam podstawowy kod startowy w global.php i są tam tworzone zmienne, których będę potrzebować w niektórych kontrolerach lub widokach. Czy istnieje sposób na ustawienie wartości tych zmiennych konfiguracyjnych, a nawet utworzenie nowych w czasie wykonywania?
Marco Madueño Mejía
Nie sądziłem, że to może być takie łatwe. Oznaczę to jako odpowiedź, ale mam co do tego ostatnią wątpliwość. Jedna z tych zmiennych, które muszę udostępnić globalnie, zawiera zestaw kategorii pobranych z bazy danych. Jest wymagany dla wszystkich widoków, ponieważ będzie używany w menu nawigacji, ale jest również wymagany w niektórych kontrolerach, a nawet do routingu. Czy jest poprawne (mówiąc semantycznie) zapisywanie tego typu danych jako zmiennej konfiguracyjnej? Czy powinienem to przechowywać w inny sposób?
Marco Madueño Mejía
2
@Corner od wersji 5.0 katalog konfiguracyjny znajduje się bezpośrednio w katalogu głównym twojego projektu.
lukasgeiter
4
Dla osób używających Laravel 5 lub nowszego musisz dodać 'use Config;' w kontrolerze lub umieść ukośnik w czcionce Config w następujący sposób: \ Config :: get ('constants.langs');
rotaercz
2
Możesz użyć config()pomocnika zamiast używać Config::get()teraz.
Leith,
23

Dla stałych

Utwórz plik constants.php w katalogu konfiguracyjnym: -

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

return [

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

];

Możesz ich używać jak: -

echo YOUR_DEFINED_CONST . '<br>';

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

Dla tablic statycznych

Utwórz plik static_arrays.php w katalogu konfiguracyjnym: -

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'
    ];

}

Możesz go używać tak, jak: -

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

Uwaga: Laravel automatycznie dołącza wszystkie pliki konfiguracyjne, więc nie ma potrzeby ręcznego dołączania :)

Gagandeep Gambhir
źródło
Niedostępne w niektórych poleceniach konsoli, takich jak route:cache:Use of undefined constant ID - assumed 'ID'
AliN11
13

Utwórz wspólny plik stałych w Laravel

app / constants.php

    define('YOUR_CONSTANT_VAR', 'VALUE');

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

composer.json dodaj lokalizację pliku podczas automatycznego ładowania w pliku composer.json

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

Zanim ta zmiana zacznie obowiązywać, musisz uruchomić następujące polecenie w Terminalu, aby zregenerować pliki automatycznego ładowania Laravel:

composer dump-autoload
Parth kharecha
źródło
1
Dzięki za udostępnienie. Zapomniałem o automatycznym
doładowaniu
It's my pleasure @ChannaveerHakari
Parth kharecha
8

W przypadku stałych globalnych w Laravel 5 nie lubię wywoływać dla nich Config. Definiuję je w grupie Route w ten sposób:

// global contants for all requests
Route::group(['prefix' => ''], function() {
    define('USER_ROLE_ADMIN','1');
    define('USER_ROLE_ACCOUNT','2');
});
Mladen Janjetovic
źródło
Jeśli mam dużą liczbę stałych, czy istnieje sposób na przechowywanie ich w innym pliku (plikach), a następnie uwzględnienie ich w funkcji trasy? Co robi linia ['prefix' => '']? Wiem, że jest to tablica asocjacyjna, ale czy dzięki temu stałe są dostępne dla wszystkich tras? Dzięki.
user3089840
1
Aha cóż, wymyśliłem część prefiksu: laravel.com/docs/5.1/routing#route-group-prefixes
user3089840
Kolejna uwaga na marginesie, bez względu na to, co robię, wydaje się, że PHPUnit tego nie lubi. Kiedy robię to na swój sposób, wszystko działa dobrze w przeglądarce, ale PHPUnit mówi mi, że moje stałe są już zdefiniowane, a to po prostu nieprawda.
user3089840
Jeśli buforujesz swoje konfiguracje, definiowanie w nich stałych nie zadziała.
zera i jedynki
Świetny pomysł na użycie przedrostka
Arun Yokesh
4

Myślę, że najlepszym sposobem jest użycie lokalizacji.

Utwórz nowy plik messages.phpw resources/lang/en( enponieważ tak jest w moim config/app 'locale'=>'en') zwróć tablicę wszystkich wartości

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

pobrać dla laravel 5.3 i niższych

echo trans('messages.welcome');

lub

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

do 5,4 użycia

echo __('messages.welcome') 

Lokalizacja laravel 5.0

lub

Lokalizacja laravel 5.4

Bill Stephen
źródło
To jest poprawne. Zapytanie podrzędne od początkującego polega na tym, jak odczytać ten plik message.php i pobrać wartość klucza w postaci tablicy? Chcę odczytać to jako tablicę i wysłać jako odpowiedź json dla mojej biblioteki po stronie klienta, tj. Angular JS do obsługi niektórych ciągów.
Gopinath
2

Aby dodać do powyższej odpowiedzi, będziesz musiał dołączyć klasę config, zanim zaczniesz jej używać w Laravel 5.3

use Illuminate\Support\Facades\Config;
Jignesh Rawal
źródło
Lub po prostu użyj funkcji config ().
ademers
2

Co najmniej w Laravel 5.4 możesz je tworzyć w swoim konstruktorze;

public function __construct()
{
  \Config::set('privileged', array('user1','user2');
  \Config::set('SomeOtherConstant', 'my constant');     
}     

Następnie możesz nazwać je w ten sposób w swoich metodach;

\Config::get('privileged');

Szczególnie przydatne w przypadku metod statycznych w modelu itp.

Odniesienie na Laracasts.com https://laracasts.com/discuss/channels/general-discussion/class-apphttpcontrollersconfig-not-found

rana
źródło
0

Po prostu umieść plik constants.php w katalogu konfiguracyjnym i zdefiniuj swoje stałe w tym pliku, plik zostanie automatycznie załadowany, przetestowany w Laravel 6+

Engr Syed Rowshan Ali
źródło