La mia domanda in breve: Posso utilizzare una singola fabbrica per più controller?Fabbrica singola per più controller?
Maggiori dettagli:
Ho alcune impostazioni specifiche non modulo globale in /config/autoload/global.php che assomigliano a questo:
return array(
'settings' => array(
'setting_a' => 'foo',
'setting_b' => 'bar'
),
// More ZF default configuration ...
);
Ora voglio fare queste impostazioni accessibile in ogni controller senza dover chiamare il $this->getServiceLocator()->get('config')
tutto il tempo.
Quindi la mia idea era di introdurre un attributo di classe $settings
nel mio AbstractController
che viene iniettato con l'array di configurazione. Ho provato a recuperare la configurazione direttamente nel costruttore di AbstractController
. Tuttavia, getServiceLocator()
non sembra pronto al momento e restituisce NULL.
ho potuto costruire fabbriche controller per ogni controller e iniettare le impostazioni di questo tipo:
class ControllerFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator) {
$config = $serviceLocator->get('config');
return new \MyModule\Controller\MyController($config['settings']);
}
}
ma sarebbe lo stesso più e più volte. Quindi la mia domanda è: Posso usare una singola fabbrica per più controller?
Nel mio module.config.php ho potuto specificare una singola classe fabbrica per più controller:
return array(
'controllers' => array(
'factories' => array(
'MyModule\Controller\MyControllerA' => 'MyModule\Factory\ControllerFactory',
'MyModule\Controller\MyControllerB' => 'MyModule\Factory\ControllerFactory',
'MyModule\Controller\MyControllerC' => 'MyModule\Factory\ControllerFactory',
)
),
);
Ma in fabbrica ho bisogno di restituire l'oggetto controller attuale a mano (vedi esempio sopra) che ovviamente funziona solo con una fabbrica per controller.
Spero, ho chiarito il mio problema.
UPDATE 2013/03/24:
Anche se ho seguito la soluzione suggerita attraverso la creazione di un inizializzatore, non ho mai veramente piaciuto usarlo solo per l'iniezione della configurazione.
Quindi ho continuato a scavare e ho finito per creare un plug-in Controller per ricevere le impostazioni.
Il codice per il plugin si presenta così:
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;
}
}
Dopo aver aggiunto il plugin nella module.config.php con
'controller_plugins' => array(
'invokables' => array(
'settings' => 'My\Controller\Plugin\Settings',
)
),
posso accedere con facilità le impostazioni all'interno di un controllore semplicemente chiamando $this->settings()
. Spero che questo aiuti chiunque.
Grazie per la vostra idea. Lo stesso inizializzatore funziona come descritto, tuttavia una volta aggiunto all'array 'controller', i mapping del controller si perdono in qualche modo e viene visualizzato un errore che dice * "Il controller richiesto non può essere mappato su una classe controller esistente." * sembra che sia i "invokable" che gli "inizializzatori" all'interno dei "controllers" si mordano a vicenda. Hai qualche suggerimento? – Rob
Vorrei tornare indietro ai soli invokable, quindi applicare l'inizializzatore, quindi eseguire il debug se l'inizializzatore riceve un'istanza. Il messaggio di errore generato potrebbe essere per una serie di motivi, assicurarsi che tutte le definizioni di utilizzo siano corrette e che non vi siano errori. Per scavare più a fondo vorrei dare un'occhiata a \ Zend \ Mvc \ Service \ ControllerLoaderFactory.php e seguirlo fino a \ Zend \ Mvc \ Controller \ ControllerManager.php - spero che aiuti. – DrBeza
Trovato la causa: è la chiamata '$ serviceLocator-> get ('Config')' in Initializer :: initialize() che genera un'eccezione * servizio non trovata *. Quindi sembra che la configurazione non sia pronta alla fase di inizializzazione. E ancora non riesco a ottenere le mie impostazioni nel controller :-(Proverò ora una soluzione. – Rob