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

Laravel Service Container

Object Storage Arubacloud
0 głosów
464 wizyt
pytanie zadane 12 sierpnia 2019 w PHP przez Artek Stary wyjadacz (11,800 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,800 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 116 wizyt
pytanie zadane 24 lipca 2020 w PHP przez Greeenone Pasjonat (16,100 p.)
0 głosów
2 odpowiedzi 924 wizyt
+1 głos
1 odpowiedź 79 wizyt

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...