2012-02-24 15 views
5

Ho letto tutti i post su routing e documentazione di Zend ma non riesco ancora a risolvere questo problema.Problemi di instradamento di Zend

Ho un'applicazione multi-lingua con due moduli: predefinito e admin. La selezione della lingua sta funzionando benissimo (in un routeShutdown Plugin Controller), ma ho alcuni problemi di configurazione del router:

voglio avere questi lavoro URL:

/ 
/controller 
/controller/action 
/action     (default controller) 
/controller/param  (default action) 
/admin 
/admin/admin-controller 
/admin/admin-controller/action 

e utilizzando la selezione della lingua, sarebbe :

/en 
/en/controller 
/en/controller/action 
/en/action     (default controller) 
/en/controller/param  (default action) 
/en/admin/admin-controller 
/en/admin/admin-controller/action 

ho aggiunto questo al mio file di bootstap (index.php):

$frontController = Zend_Controller_Front::getInstance(); 
$router = $frontController->getRouter(); 
$router->removeDefaultRoutes(); 
$router->addRoute('langmodcontrolleraction', 

new Zend_Controller_Router_Route('/:lang/:module/:controller/:action', 
    array('lang' => ':lang')) 
); 

$router->addRoute('langmodcontroller', 
new Zend_Controller_Router_Route('/:lang/:module/:controller', 
    array('lang' => ':lang', 
     'action' => 'index')) 
); 

$router->addRoute('langmod', 
new Zend_Controller_Router_Route('/:lang/:module', 
    array('lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index')) 
); 

$router->addRoute('lang', 
new Zend_Controller_Router_Route('/:lang', 
    array('lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index', 
     'module' => 'default')) 
); 

$frontController->setControllerDirectory(array(
'default'=>BASE_PATH.'app/modules/default/controllers', 
'admin'=>BASE_PATH.'app/modules/admin/controllers'));  

Al fine di verificare come il router è l'analisi dell'URL, ho aggiunto un var_dump al plugin routeShutdown:

Entrando a /it, ottengo:

array 
'lang' => string 'en' (length=2) 
'action' => string 'index' (length=5) 
'controller' => string 'index' (length=5) 
'module' => string 'default' (length=7) 

che è OK. Ma quando entro a /it/controller1 ottengo:

array 
'lang' => string 'en' (length=2) 
'module' => string 'controller1' (length=8) 
'action' => string 'index' (length=5) 
'controller' => string 'index' (length=5) 

E 'impostazione del modulo a "controller1". Come posso dire al router di impostare il valore predefinito sul modulo? E per un URL come/en/controller/param? (impostazione del modulo e azione predefinita)

risposta

6

Ho paura che tu abbia bisogno di riconsiderare il tuo schema URL un po ', o cambiare il modo in cui i percorsi sono impostati, dato che hai colpito due limiti del modo in cui ZF il routing funziona.

Il primo è che il router non è a conoscenza di cosa sia o non sia un modulo, un controller o un'azione validi; tutto ciò che fa è far corrispondere le stringhe nell'URL alle variabili nel percorso. Lo fa controllando ciascuna rotta in successione, in ordine inverso, finché non trova una corrispondenza. Quando si preme /en/controller, per prima cosa controlla il percorso /:lang, che non corrisponderà. Quindi controlla /:lang/:module, che corrisponderà, perché /:lang/:module corrisponderà a/qualsiasi cosa/qualsiasi cosa a meno che non lo dici diversamente.

Con questo in mente non sarà in grado di avere entrambi:

/en/controller 
/en/action 

se non si imposta alcune restrizioni, come un URL come /en/foo sarà sempre di pari passo con quello dei due si definisce scorso.

Se si dispone di un numero relativamente piccolo di azioni/controller che spesso non cambiano, il modo più semplice intorno a questo è quello di codificare in alcuni valori possibili per il 2 ° dei due percorsi, ad esempio:

$router->addRoute('langmod', new Zend_Controller_Router_Route(
    '/:lang/:module', 
    array(
     'lang' => ':lang', 
     'action' => 'index', 
     'controller' => 'index' 
    ), 
    array(
     'module' => '(foo|bar|something)' 
    ) 
)); 

sostituire foo, bar ecc. Con nomi di moduli validi. Ora quando si preme /en/controller1 non corrisponderà a questa rotta perché controller1 non corrisponde al modello regexp definito per la variabile: module. Avresti quindi bisogno di una route /:lang/:controller separata (o possibilmente di /:lang/:controller/:action) per farla corrispondere.

Hai chiesto come impostare un valore predefinito per alcune variabili.In effetti lo stai già facendo con l'azione in alcuni dei tuoi percorsi, ma per controller/modulo non funzionerà nel modo in cui speri. Se prendiamo il percorso langmodcontroller e modificarlo in questo modo:

$router->addRoute('langmodcontroller',new Zend_Controller_Router_Route(
    '/:lang/:module/:controller', 
    array(
     'lang' => ':lang', 
     'controller' => 'index' 
     'action' => 'index' 
    ) 
)); 

adesso c'è un valore predefinito per la variabile di controllo. Se fingiamo per un secondo che questa fosse l'unica via, una richiesta per /en/blog ora sarebbe stata abbinata a questa e impostasse i parametri della richiesta su lang = en, module = blog, controller = index, action = index. /en/blog/index/foo corrisponderebbe anche a questo percorso e ti darebbe modulo = blog, controller = index, action = foo. Ma nota che anche se controller = index hai ancora bisogno nell'URL. Quindi la limitazione numero due è che hai sempre bisogno della variabile nell'URL (anche se è impostata sul tuo valore predefinito) purché ci sia qualcosa dopo di essa che non è l'impostazione predefinita.

Con queste limitazioni in mente io suggerirei di andare con qualcosa di simile (definita in questo ordine):

/:lang/:controller/:action/ (with 'index' defaults for controller and action) 
/:lang/:action (with 'action' restricted to some predefined values) 
/:lang/admin/:controller/:action (with 'admin' as a string in the URL, and :module set to 'admin' as the default) 

Questo darebbe URL simile a questo:

/en 
/en/controller 
/en/controller/action 
/en/action 
/en/controller/param 
/en/admin/controller 
/en/admin/controller/action 

che è praticamente quello che cerchi

Il routing in ZF è molto potente, è sufficiente conoscere le sue stranezze.

+0

questa è una risposta molto utile, la tua spiegazione è perfetta, ora capisco come funziona il routing :) grazie! Quando raggiungo 15 rappresentanti. Voterò la tua risposta. Ecco il mio sito Web, dove implementerò questo: [tryandsay.com] (http://www.tryandsay.com) – Gustavo

Problemi correlati