• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Laravel Service Container

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
0 głosów
410 wizyt
pytanie zadane 12 sierpnia 2019 w PHP przez Artek Stary wyjadacz (11,840 p.)

Przerabiam dokumentację Laravel'a i natrafiłem na dział "Service Container".  Na początku można przeczytać :

The Laravel service container is a powerful tool for managing class dependencies and performing dependency injection.

Czyli dokładnie na czym miałoby polegać zarządzanie zależnościami klas( managing class dependencies)?

Czy dzięki temu można zmieniać skąd dana klasa dziedziczy, albo jakie implementuje interface'y, trait'y ? Co dokładnie to miałoby oznaczać?

 

Następnie

Within a service provider, you always have access to the container via the $this->appproperty. We can register a binding using the bind method, passing the class or interface name that we wish to register along with a Closure that returns an instance of the class:

$this->app->bind('HelpSpot\API', function ($app) {
    return new HelpSpot\API($app->make('HttpClient'));
});

No i co dokładnie robi ten kod? Ja rozumiem tylko tyle, że jest jakaś klasa o nazwie API w przestrzeni nazw HelpSpot i do niej jest coś bindowane(związane), tylko co? Co się dzieje z tym domknięciem później? Dlaczego zwraca instancję  HelpSpot\API ?

 

Następnie

Note that we receive the container itself as an argument to the resolver

Container itself czyli chodzi o to?

$this->app

 I dalej

We can then use the container to resolve sub-dependencies of the object we are building.

I też nic z tego nie rozumiem. Czy ktoś mógłby objaśnić o co tu chodzi? Najlepiej obszernie i szczegółowo. 

1 odpowiedź

0 głosów
odpowiedź 12 sierpnia 2019 przez Artek Stary wyjadacz (11,840 p.)

Poczytałem więcej różnych źródeł. Podzielę się tym do czego doszedłem, może komu się przyda. Sam temat nie jest bardzo skomplikowany ale wiele tutoriali podaje skąpy i niepełny opis. Jeżeli cokolwiek napisałem niepoprawnie proszę od razu dać znać.

Załóżmy, że mamy taki kod

namespace App;

class Foo
{
    public function hello()
    {
        return 'Hello World';
    }
}


Route::get('/foo', function (App\Foo $foo) {
    return $foo->hello(); // Hello World
});

 

Zauważmy, że nigdzie tutaj ręcznie nie tworzymy żadnej instancji obiektu klasy App\Foo( chodzi o new App\Foo) - takowa instancja jest oczekiwana przez funkcję anonimową przekazywaną jako drugi parametr do metody get. Zatem skoro nigdzie nie ma żadnej instancji tej klasy to czy wyświetli się błąd? Nie, ponieważ Laravel sam automatycznie utworzy za nas instancję klasy App\Foo. Takie udogodnienie, które zaoszczędzi nam pisania. Automatycznie jest tworzony obiekt.

 

Jednakże inteligencja tego mechanizmu jest ograniczona. Załóżmy,że klasa potrzebuje nazwy naszej aplikacji np.

namespace App;

class Foo
{
    public function __construct($appName)
    {
        $this->appName = $appName;
    }

    public function hello()
    {
        return "Hello {$this->appName}";
    }
}

Z tym Laravel sam sobie nie poradzi. W konstruktorze pojawia się jakiś bliżej niezidentyfikowany parametr i nie za bardzo wiadomo co z nim zrobić. Musimy laravela nauczyć i pokazać mu jak się zachować w takiej sytuacji. Robi się to poprzez metodę bind

App::Bind(\App\Foo::class, function ($app) {
        return new \App\Foo($app->config['app.name']);
    });

Nazywa się to wiązaniem. Jako pierwszy parametr podajemy nazwę naszej klasy a następnie podajemy domknięcie, które będzie uruchamiane gdy zajdzie potrzeba automatycznego stworzenia obiektu. W tym domknięciu można wykonać różne czynności związane np. z konfigurowaniem czegoś w naszym obiekcie. Na koniec funkcja musi jeszcze utworzyć nowy obiekt i go zwrócić. Nie musi to być obiekt klasy którą podaliśmy jako pierwszy parametr (w tym wypadku \App\Foo), może to być obiekt innej klasy.

Pozostaje jeszcze kwestia kwestia parametru, który pojawia się w domknięciu($app). Z tego co wyczaiłem to parametr ten można nazwać dowolnie i wewnątrz naszego domknięcia można go wykorzystywać do pobierania przeróżnych informacji o aplikacji.

 

Można też zrobić tak 

App::Bind('Bar','Baz');

Co powoduje, że gdy Laravel spróbuje automatycznie stworzyć obiekt klasy Bar to uruchomi się to co zdefiniowaliśmy w wiązaniu(jeżeli takowe istnieje) dla klasy Baz.

Chcąc stworzyć obiekt na podstawie zdefiniowanego przez nas wiązania to należy użyć

App::Make('NazwaKlasy')

O czymś zapomniałem? Coś przekręciłem?

Podobne pytania

0 głosów
0 odpowiedzi 85 wizyt
pytanie zadane 24 lipca 2020 w PHP przez Greeenone Pasjonat (16,120 p.)
0 głosów
2 odpowiedzi 750 wizyt
0 głosów
1 odpowiedź 166 wizyt
pytanie zadane 22 grudnia 2020 w HTML i CSS przez Łukasz Halicki Nowicjusz (150 p.)

90,818 zapytań

139,493 odpowiedzi

313,553 komentarzy

60,311 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...