Moje pytanie w skrócie: czy mogę używać jednej fabryki dla wielu kontrolerów?Jedna fabryka dla wielu kontrolerów?
Więcej szczegółów:
Mam kilka ustawienia globalne specyficzne non-moduł w /config/autoload/global.php które wyglądają tak:
return array(
'settings' => array(
'setting_a' => 'foo',
'setting_b' => 'bar'
),
// More ZF default configuration ...
);
Teraz chcę, aby te ustawienia dostępne w każdym kontrolerze bez konieczności ciągłego dzwonienia pod numer $this->getServiceLocator()->get('config')
.
Więc moim pomysłem było wprowadzenie atrybutu klasy $settings
w moim AbstractController
, który zostanie wprowadzony z tablicą konfiguracji. Próbowałem pobrać konfigurację bezpośrednio w konstruktorze AbstractController
. Jednak getServiceLocator()
nie wydaje się gotowy w tym czasie i zwraca NULL.
mogłem budować fabryki kontroler dla każdego kontrolera i wstrzyknąć ustawienia jak poniżej:
class ControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('config');
return new \MyModule\Controller\MyController($config['settings']);
}
}
Ale byłoby to samo w kółko. Moje pytanie brzmi: czy mogę używać jednej fabryki dla wielu kontrolerów?
W moim module.config.php mogę określić pojedynczy klasy fabrycznej dla wielu kontrolerów:
return array(
'controllers' => array(
'factories' => array(
'MyModule\Controller\MyControllerA' => 'MyModule\Factory\ControllerFactory',
'MyModule\Controller\MyControllerB' => 'MyModule\Factory\ControllerFactory',
'MyModule\Controller\MyControllerC' => 'MyModule\Factory\ControllerFactory',
)
),
);
Ale w fabryce muszę wrócić rzeczywisty obiekt Controller ręcznie (patrz przykład powyżej) który oczywiście działa tylko z jedną Fabryką na Sterownika.
Mam nadzieję, że mój problem jest jasny.
UPDATE 24.03.2013:
Chociaż raz pierwszy zastosowaną sugerowane rozwiązanie tworząc inicjator, tak naprawdę nigdy nie lubiłem go używać tylko do wstrzykiwania konfiguracji.
Więc ciągle kopałem i skończyłem tworzyć wtyczkę kontrolera, aby otrzymać ustawienia.
Kod dla wtyczki wygląda następująco:
use Zend\Mvc\Controller\Plugin\AbstractPlugin;
class Settings extends AbstractPlugin
{
protected $settings;
public function __invoke()
{
$config = $this->getController()->getServiceLocator()->get('Config');
if (isset($config['settings']) && is_array($config['settings'])) {
$this->settings = $config['settings'];
}
return $this->settings;
}
}
Po dodaniu wtyczki w module.config.php z
'controller_plugins' => array(
'invokables' => array(
'settings' => 'My\Controller\Plugin\Settings',
)
),
można łatwo uzyskać dostęp do moich ustawień w sterowniku przez po prostu dzwonię pod numer $this->settings()
. Mam nadzieję, że to pomoże każdemu.
Dziękujemy za pomysł. Sam inicjalizator działa tak, jak opisałeś, jednak gdy dodam go do tablicy "kontrolerów", mapowania kontrolera jakoś się zgubią i pojawia się błąd mówiący: "Żądanego kontrolera nie można zmapować do istniejącej klasy kontrolera." * To wydaje się, że oba "invokable" i "initializers" w ramach "kontrolerów" gryzą się nawzajem. Masz jakieś sugestie? – Rob
Chciałbym przewinąć z powrotem do just invokables, a następnie zastosować inicjalizator - a następnie debugować, jeśli inicjator pobiera instancję. Komunikat o błędzie może być z wielu powodów, upewnij się, że wszystkie definicje użytkowania są poprawne i nie ma błędów. Aby zagłębić się głębiej, zajrzałbym do \ Zend \ Mvc \ Service \ ControllerLoaderFactory.php i podążałem za nim do \ Zend \ Mvc \ Controller \ ControllerManager.php - mam nadzieję, że to pomaga. – DrBeza
Znaleziono przyczynę: Jest to wywołanie '$ serviceLocator-> get ('Config')' w Initializer :: initialize(), które zgłasza wyjątek * service not found *. Wygląda na to, że konfiguracja nie jest gotowa w fazie inicjalizacji. Nadal nie mogę wprowadzić swoich ustawień do kontrolera :-(Spróbuję obejść teraz: – Rob