Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [ZendFramework][ZF2][ZendFramework2] Factories i ServiceManager - do czego uzyc
elmozaur
post
Post #1





Grupa: Zarejestrowani
Postów: 518
Pomógł: 18
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


Witam.
Zaczynam dopiero przygode z zendem i przerabiajac tutorial o dodawaniu albumow plytowych do bazy nasunelo mi sie pytanie:

1) co to jest service manager, do czego można go używać, co można do niego dodawać (doczytalem ze factories mozna tu podpiac ale dlaczego questionmark.gif?)?
2) co to jest factory/factories (w tutorialach to ma cos wspolnego z konfigami ale nie jestem pewien)questionmark.gif?

pytania o podstawy zenda2 zadawać tutaj czy w "przedszkolu" ?

za cierpliwosc i zrozumienie dziekuje i pozdrawiam
Grzegorz
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 3)
RiE
post
Post #2





Grupa: Zarejestrowani
Postów: 97
Pomógł: 45
Dołączył: 5.05.2010

Ostrzeżenie: (0%)
-----


Service Manager jest oparty o wzorzec Service Locator i jest to mechanizm slużący do pobierania innych obiektów. Używa się go w module.config.php lub Module.php i składa się z 7 typów(kategorii).

1. abstract_factories pod tym kluczem definiuje się klasy, które muszą implementować ZendServiceManagerAbstractFactoryInterface. Rzadko używane.
2. aliases nadaje klasie alias, np:
  1. 'aliases' => array(
  2. 'translator' => 'MvcTranslator',
  3. ),


Teraz jesteśmy w stanie się odwołać za pomocą

  1. $this->getServiceLocator()->get('translator')


3. factories deklaruje klasy, które powinny implementować Zend/ServiceManager/FactoryInterface. Dość często używane. Np:

  1. 'factories' => array(
  2. 'UserTable' => function($sm) {
  3. $tableGateway = $sm->get('UserTableGateway');
  4. $table = new UserTable($tableGateway);
  5. return $table;
  6. },


Jeżeli klasa ma konstruktor lub jeśli potrzebujemy dodać do klasy obiekty innej klasy to używamy do tego celu właśnie klucza factories. Obiekt jest inicjowany od razu- w momencie kiedy jest wczytywany do Service Managera.

4. invokables definiujemy klasy, które nie mają konstruktora lub jeśli nie musimy z niego(konstruktora) skorzystać. Również dość często używane, jak chociażby dla naszych klas kontrolera. Np:

  1. 'invokables' => array(
  2. 'Application\Controller\Index' => 'Application\Controller\IndexController',
  3. )


Klasy pod tym kluczem są inicjowane dopiero w momencie odwołania się do danego klucza, a nie w momencie 'pobrania' przez ServiceManager

5. services służy głównie do deklarowania 'service'ów' lub klas, które są już zainicjowane. Np:

  1. 'services' => array(
  2. 'name' => $zmienna,
  3. ),


6. initializers nie miałem okazji jeszcze z tego korzystać. Ten klucz definiuje callback, który jest uruchamiany za każdym razem gdy jest tworzony obiekt, w ten sposób jeśli obiekt spełnia wymagania(np. implementuje konkretny interfejs) jeśtemy w stanie 'wstrzepić' inny obiekt.

  1. 'initializers' => array(
  2. function ($instance, $sm) {
  3. if ($instance instanceof AuthorizeAwareInterface) {
  4. $instance->setAuthorizeService($sm->get('auth_service'));
  5. }
  6. }
  7. )


7. shared domyślnie wszystkie service'y od ServiceManagera są 'shared', czyli pracujemy na tym samym obiekcie. Tutaj jesteśmy w stanie to zmienić, gdy np. chcemy żeby za każdym razem był tworzony nowy obiekt.

  1. $table1 = $this->getServiceLocator()->get('UserTable');
  2. $table2 = $this->getServiceLocator()->get('UserTable');
  3. // table1 i table2 to ten sam obiekt


Gdy dodamy:

  1. 'shared' => array(
  2. 'UserTable' => false,
  3. ),


  1. $table1 = $this->getServiceLocator()->get('UserTable');
  2. $table2 = $this->getServiceLocator()->get('UserTable');
  3. // table1 i table2 to różne obiekty



Jak napisałem na początku, Service Manager służy do łatwego dostępu do obiektów. Np. wyobraźmy sobie że tylko dla pewnej akcji chcesz dodać jakiś plik js, możesz to zrobić tak:

  1.  
  2. public function addAction()
  3. {
  4. $this->getServiceLocator()
  5. ->get('viewhelpermanager')
  6. ->get('HeadScript')
  7. ->appendFile('/js/ckeditor/ckeditor.js','text/javascript');
  8. }


Tutaj za pomocą Service Managera dostajemy się do obiektu HeadScript i dzięki temu jesteśmy w stanie dodać plik js z poziomu akcji kontrolera

Najczęśniej używane są factories i invokables. Co to są factories to napisałem wyżej, ale może dodam jeszcze jeden przykład żeby lepiej zobrazować co robi.

Mamy klasę:

  1. class HelloService
  2. {
  3. public function sayHello()
  4. {
  5. return 'Hello World';
  6. }
  7. }


I załóżmy że chcemy wyświetlić w widoku to co zwraca metoda sayHello().
Możemy to zrobić na dwa sposoby.

1. Invokables

W pliku Module.php dodajemy:

  1. public function getServiceConfig()
  2. {
  3. return array(
  4. 'invokables' => array(
  5. 'HelloService'
  6. => 'Helloworld\Service\HelloService'
  7. )
  8. );
  9. }


I teraz w akcji:

  1. public function indexAction()
  2. {
  3. $hello = $this->getServiceLocator()
  4. ->get('HelloService');
  5.  
  6. return new ViewModel(
  7. array('hello' => $hello->sayHello())
  8. );
  9. }


Najpierw dodajmy do ServiceManagera klasę HelloService, później w akcji pobieramy z Service Managera i odwołujemy się do metody sayHello(). Trochę to toporne i niewydajne.

2. Factories

  1.  
  2. 'factories' => array(
  3. 'Helloworld\Controller\Index' => function($sm) {
  4. $controller = new Helloworld\Controller\IndexController();
  5.  
  6. $controller->setHelloService(
  7. $sm->getServiceLocator()
  8. ->get('HelloService')
  9. );
  10.  
  11. return $controller;
  12. }
  13. )


I w akcji:

  1. class IndexController extends AbstractActionController
  2. {
  3. private $helloService;
  4.  
  5. public function indexAction()
  6. {
  7.  
  8. return new ViewModel(
  9. 'hello' => $this->helloService->sayHello()
  10. )
  11. );
  12. }
  13.  
  14. public function setHelloService($service)
  15. {
  16. $this->helloService = $service;
  17. }
  18. }


Tym sposobem dodajemy obiekt klasy HelloService do kontrolera w Service Managerze i teraz w akcji nie musimy pobierać tego obiektu, tylko bezpośrednio możemy na nim pracować. Bardziej czytelniejsze rozwiązanie, wydajne i zalecane.
Go to the top of the page
+Quote Post
elmozaur
post
Post #3





Grupa: Zarejestrowani
Postów: 518
Pomógł: 18
Dołączył: 21.07.2008

Ostrzeżenie: (0%)
-----


RiE: dla Ciebie powini stworzyć przycisk "Bardzo pomógł"
Go to the top of the page
+Quote Post
irmidjusz
post
Post #4





Grupa: Zarejestrowani
Postów: 279
Pomógł: 60
Dołączył: 25.02.2012

Ostrzeżenie: (0%)
-----


zgadzam się z elmozaurem smile.gif


--------------------
there is much to be learned
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 19.08.2025 - 07:07