Il ContextSwitch action helper ci permette di scegliere il formato in cui visualizzare i dati della view, oltre al classico html, anche altri formati come per esempio xml o json, nonchè alcuni formati personalizzati che possiamo definire. Questo è decisamente utile per le richieste XmlHttpRequests o la creazione di Web Services.
Utilizzo
Per utilizzare ContextSwitch dovremo definire nel nostro Controller i contesti, ovvero creare un array associativo che relaziona una action ad uno o più formati, quindi inizializzare l’helper nel metodo init()
class MyController extends Zend_Controller_Action
{
public $contexts = array(
'listato' => array('xml'),
'commenti' => array('xml', 'json')
);
public function init()
{
$this->_helper->contextSwitch()->initContext();
}
public function listatoAction()
{
// codice
}
public function commentiAction()
{
// codice
}
}
Per ogni nuovo formato associato ad una action avremo la necessità di creare una view script, con estensione {nome-formato}.phtml, nel caso dell’esempio di sopra, listato.xml.phtml e commenti.xml.phtml.
Queste view script definiranno al loro interno il tipo di xml da restituire, prendendo i dati passati dal controller.
Per quanto riguarda il formato json, questo di default non ha la necessità che sia creato un nuovo file della vista ( as esempio commenti.json.phtml ), in quanto sarà Zend Framework ad occuparsi della serializzazione delle variabili della vista.
Questo comportamento può essere modificato settando l’autoserializzazione a false
$this->_helper->contextSwitch()->setAutoJsonSerialization(false);
Per “switchare” i vari contesti sarà necessario passare la variabile ‘format’ nella richiesta
- {nome-sito}/{nome-controller}/{nome-action}/format/xml
- {nome-sito}/{nome-controller}/{nome-action}/format/json
Oltre che ad indicare la corretta view script da renderizzare, contextSwitch si occupa di
- Disabilitare il layout, se attivato
- Settare gli headers appropriati per la risposta
- Se specificato, richiamare delle funzionalità di callback per il settaggio del contesto e per azioni post-processing
Per esempio, nel caso di richiesta del formato xml il ‘Content-Type’ della risposta sarà settato a ‘text/xml’.
Formati personalizzati ( Custom Context )
ContextSwitch ci offre la possibilità di creare dei formati personalizzati. Per aggiungere un contesto personalizzato ( custom context ) procederemo alla sua aggiunta all’helper
public function init()
{
$this->_helper->contextSwitch()->addContext($context, array $spec)->initContext();
}
dove $context è il nome che attribuiamo al contesto personalizzato e $spec è un array di opzioni per il nuovo contesto. Queste opzioni sono:
- suffix: il suffisso del file della vista per il custom context
- headers: un array di headers dove la chiave è il nome dell’header e il valore è appunto suo valore es array(‘Content-Type’ => ‘text/xml’)
- callbacks: un array contenente una o più chiavi init o post, che puntano a delle funzionalità PHP usate per l’inizializzazione del contesto o per il suo post-processing.
Oltre che aggiungere il custom context all’helper, per utilizzarlo sarà necessario relazionarlo alle action del controller
public $contexts = array(
'listato' => array('xml'),
'commenti' => array('xml', 'json',{nome-custom-context})
);
Se avete dei dubbi sul contextSwitch action helper potete visitare la documentazione ufficiale zend contextSwitch, o in alternativa, lasciare un commento a questo post.

ciao,
in risposta ad una chiamata ajax
con il metodo descritto da te la risposta è di circa 500KB mentre
se provo senza lo Zend Framework, in php con la funzione json_encode
la risposta è di circa 100KB.
Nel primo caso (500KB) nell’header http della risposta ho:
Content-Type application/json
mentre nel secondo caso (100KB):
Content-Encoding gzip
Content-Type text/html
quindi non provvede alla compressione….
come posso mandare json compresso?
il mio controller:
// ...
public function init() {
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('myload', 'json')
->initContext();
}
// ...
public function myloadAction(){
$myObj = new ... ;
$json = $myObj->getJsonCode();
$this->_helper->json->sendJson( $json );
}
//...