Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 27-10-2008 21:15:40

Meardon
Nouveau membre
Date d'inscription: 10-10-2008
Messages: 7

_response et JSON

Bonsoir,

Je me suis lancé dans l'utilisation de JSON avec le Zend_Json. J'ai écrit cette action qui ne fait que répondre à une requête Ajax :

Code:

 */
    public function bardescAction()
    {
        if ($this->_request->isXmlHttpRequest())  // Appel Ajax
        { 
            $this->_helper->layout->disableLayout();
            $this->_helper->viewRenderer->setNoRender();
            
            $batiments = new Batiments();
            
            if ($this->_request->isGet())
            {
                $position = $this->_request->getParam('position');
                
                $batiment = $batiments->getBatiment($position)->toArray();
                $json = Zend_Json::encode($batiment);
                
                echo $json;  // La réponse me parvient en javascript par eval('(' + o.responseText + ')');
                
                /*
                $this->_response->setHeader('Content-Type', 'text/x-json; charset=UTF-8')
                                 ->setBody($json);
                $this->_response->sendResponse();
                */
            }
        }
        else
        {
            $this->_helper->redirector('index', 'index');
        }
    }

Cette action fonctionne, mais il paraît que ce n'est pas bien de renvoyer la réponse par un echo dans le contrôleur ? Je ne dois pas savoir m'y prendre, car si je remplace l'echo par le code en commentaires, j'obtiens une erreur "missing ) in parenthetical"...
Quelle est la bonne méthode ?

Merci pour vos conseils...

Hors ligne

 

#2 27-10-2008 22:23:14

fte
Membre
Lieu: 06 13 83
Date d'inscription: 16-05-2008
Messages: 112
Site web

Re: _response et JSON

Bonjour, l'alternative est d'utiliser les contextes, cela simplifiera ce code, car le framework peut faire cela en partie : ca affiche une vue ajax (bardesc.json par exemple) suivant le contexte ajax ou normal ou +.

http://framework.zend.com/manual/fr/zen … lpers.html

Hors ligne

 

#3 27-10-2008 22:40:06

Meardon
Nouveau membre
Date d'inscription: 10-10-2008
Messages: 7

Re: _response et JSON

Merci fte, apparemment c'est bien ce qu'il me faut smile
Par contre je n'ai pas très bien compris comment s'utilisent les contextes, pourrais-tu me montrer ce que ça donne avec mon action ? Car je n'ai pas de vue "bardesc" (d'où le setNoRender), et je ne trouve pas comment envoyer le tableau $batiment avec les contextes...

Hors ligne

 

#4 28-10-2008 18:18:06

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: _response et JSON

j'ai moi aussi travaillé dans cette voie

Code:

<?php
Zend_Loader::loadClass("Application_Controllers_Action");

class Application_Controllers_Json extends Application_Controllers_Action
{
    protected $_useHistory = false;

    /**
     * initialise le controleur
     * tout les controleur ajax ne retourne pas de vue
     * ils envoient du json au client
     */
    public function init()
    {
    parent::init();
        $this->getFrontController()->setParam('noViewRenderer', true);
        if ($this->_request->isXmlHttpRequest()) {
            $this->_response->setHeader('Content-Type', 'application/json; charset=UTF-8', true);
        } else {
            // on envoie la reponse en texte lors d'une invocation via le navigateur
            // cela permet de tester la réponse.
            $this->_response->setHeader('Content-Type', 'text/plain; charset=UTF-8', true);
        }
        $this->response = array();
    }

    public function postDispatch() {
        Zend_Loader::loadClass('Zend_Json_Encoder');
        echo utf8_encode(ereg_replace('"__className":"[^\"]+",', '',Zend_Json_Encoder::encode($this->response)));
        parent::postDispatch();

    }
}

Application_Controllers_Action est une classe commune à tous mes contrôleur sans utilité ici. elle dérive simplement de Zend_Controller_Action

pour utiliser
Application_Controllers_Json
il suffit de faire dériver son contrôleur de celle-ci en lieu et place de  Zend_Controller_Action.

tout comme un contrôleur utilise $this->view celui-ci utilise $this->response.
il suffit d'ajouter des membres à $this->response pour qu'il soient envoyé au client.

au passage je supprime les membres __className de l'objet car il ne sont pas utile en JSON et j'encode en UTF8 car XMLHttpRequest attends de l'UTF8 par défaut

un exemple

Code:

<?php
Zend_Loader::loadClass("Application_Controllers_Json ");

class SiteController extends Application_Controllers_Json 
{
    /**
     * GetAll retourne la liste de tout les sites disponibles pour les stat
     * c'est adire tous les sites sauf ceux déjà soucrits et pour lesquels la demande à déja
     * ete faite. la liste est paginée
     *
     * @param start curseur de départ de la page
     * @param limit nombre d'élément à retourner
     * @param sort attribut à utiliser pour le tri
     * @param dir direction du tri
     *
     * @see getOrder
     * @see getBasket
     */
    public function getAllAction()
    {
        /*
        params :
            start=96
            limit=24
            sort=site_name
            dir=DESC
        */
        $user = Zend_Auth::getInstance()->getIdentity();
        $userid = $user->usr_id;
        $data = $this->model->getDispoListByUserId($userid);
        $this->_setListResponse($data);
    }

    /**
     * GetOrder retourne la liste de tout les sites déjà soucrits
     *
     * @param sort attribut à utiliser pour le tri
     * @param dir direction du tri
     *
     * @see getAll
     * @see getBasket
     */
    public function getOrderAction()
    {
        $user = Zend_Auth::getInstance()->getIdentity();
        $userid = $user->usr_id;
        $data = $this->model->getSiteListByUserId($userid, true);
        $this->_setListResponse($data);
    }

    /**
     * GetBascket retourne la liste de tout les sites pour lesquels la demande a
     * ete faite.
     *
     * @param sort attribut à utiliser pour le tri
     * @param dir direction du tri
     *
     * @see getOrder
     * @see getAll
     */
    public function getBasketAction()
    {
        $user = Zend_Auth::getInstance()->getIdentity();
        $userid = $user->usr_id;
        $data = $this->model->getAccessListByUserId($userid);
        $this->_setListResponse($data);
    }
...

    protected function _setListResponse($data) {
        if ($data) {
            $this->response = array(
                'success' => true,
                'results' =>count($data),
                'rows'=> $data
            );
        } else {
            $this->response = array(
                'success' => false
            );
        }
    }
}

j'en fais un gros usage en ce moment une grosse appli tout en Ajax.
9 contrôleurs au total 1 contrôleur standard qui retourne l'interface utilisateur et quelque bricoles et 8 contrôleurs qui ne font que du JSON

A+JYT
PS: je suis en ZF 1.0.4

Hors ligne

 

#5 29-10-2008 09:31:02

Roulio
Membre
Lieu: Alsace
Date d'inscription: 20-11-2007
Messages: 137
Site web

Re: _response et JSON

Bonjour,

@sekaijin :

Merci pour tes exemples complets et bien écrit. J'ai cependant quelques questions de débutant (?!?):
- Pourquoi ne pas utiliser un helper d'action pour la méthode _setListResponse() ? de cette façon, n'est-il pas plus simple d'y accéder à partir de tous les contrôleurs ?

- Je me pose également la question de savoir pourquoi la version de ZF que tu utilise est la 1.0.4. Quelles en sont les raisons ? problèmes de mise à jour (compatibilité avec l'existant) ? C'est sans intérêt pour ton projet ? ...

a+, Roulio

Dernière modification par Roulio (29-10-2008 09:31:24)

Hors ligne

 

#6 29-10-2008 11:20:57

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: _response et JSON

pourquoi pas mais je n'en ai pas besoin dans tous mes contrôleurs la plus part ne retournent pas de liste
je vais avoir par exemple un membre par objet retourné

Code:

$this->response = array(
    'success' => true,
    'user' =>$user,
    'profile'=> $profile,
    'lang' => 'en'
);

J'ai pour habitude de toujours mettre un membre success à true ou false.
en cas de false j'ajoute aussi souvent un membre errors qui est une liste d'objet error qui contienne un code et un message. le message sert à débuger le code lui sert à l'application pour afficher un message local (traitement coté client des erreurs localisé)

A+JYT

je suis en 1.0.4 pour des raison de compatibilité php sur mes hébergements qui n'ont pas évolués.

Dernière modification par sekaijin (29-10-2008 11:48:01)

Hors ligne

 

#7 29-10-2008 17:21:30

phpman
Membre
Date d'inscription: 20-03-2008
Messages: 138

Re: _response et JSON

Perso je procède avec les contexte ainsi (Exemple simple sans controlle de présence/contenu des variables) :

Code:

public function init()
{        
    $contexts = array(    
                'update-mesure-audience' => 'json', 
                'delete-mesure-audience' => 'json',
                'insert-mesure-audience' => 'json',
    );
    $this->_helper->contextSwitch->addActionContexts($contexts)->initContext();
        
    if(!$this->_helper->contextSwitch->hasActionContext($this->_request->getActionName(),'json'))
    {
        //Action à exectuer hors contexte json
    }
}

public function insertMesureAudienceAction()
{
    if($this->_request->isPost())
    {
        $table = new factory_listeMesuresAudience();
        $mesure_audience = $table->createRow();
        $mesure_audience->id_etude         = $this->_getParam('id_etude');
        $mesure_audience->intitule         = $this->_getParam('intitule');
        $mesure_audience->fk_id_societe = $this->_getParam('id_societe');
        $id = $mesure_audience->save();
            
        if($id)
        {
            $this->view->message = $this->view->_('succes ajout');
            $this->view->id = $id;
        }
        else
        {
            $this->view->message = $this->view->_('echec ajout');
        }
        }
}

Le Js qui va avec ...

Code:

var result = new Ajax.Request
        (    
            base_url+'/administration/insert-mesure-audience/?format=json', 
            { 
                method:'post' ,
                parameters:{ 'id_societe' : id_societe, 'intitule' : libelle} ,
                onSuccess: function(response)
                    {
                        var responseObject = eval('(' + response.responseText + ')');
                        message(responseObject.message);
                        var id= responseObject.id;
                        //Suite ...                        
                    }
            }
        );


Par contre je ne trouve pas le moyen de ne pas avoir à faire "var responseObject = eval('(' + response.responseText + ')');" sur le retour js pour pouvoir choper mes variables.

Quelqu'un saurait comment faire pour récuperer mes variables en faisant directement "response.id", "response.message" .. etc?

Dernière modification par sebondus (29-10-2008 17:22:29)

Hors ligne

 

#8 03-11-2008 12:56:27

phpman
Membre
Date d'inscription: 20-03-2008
Messages: 138

Re: _response et JSON

personne?

Hors ligne

 

#9 03-11-2008 13:10:38

alien7
Membre
Date d'inscription: 29-04-2007
Messages: 447

Re: _response et JSON

Bonjour sebondus,
Pourquoi ne pa sutiliser le helper Json ?

Code:

$this->_helper->json(?); // ? à encoder

Ce helper désactibe automatquement la vue, le layout en envoi le bon header, tu n'as plus grand chose à écrire.


ZF 2.3 - Twitter Bootstrap 3.2
Local: Ubuntu  -> Apache2 2.4 - MariaDB 10 - PHP 5.6

Hors ligne

 

#10 03-11-2008 13:57:14

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: _response et JSON

Tu es obligé de faire un eval en javascript
Le protocole HTTP ne sait pas ce que c'est un objet Javascript, tu fois faire un eval pour interprété ta chaine (objet javascript sérialisé) en objet javascript.

Perso, j'utilise Jquery pour faire mes requête ajax, et la fonction fait elle même appel à 'eval'.

De plus, j'utilise AjaxContext, et pas ContextSwitch. (voir la doc pour la différence)

En plus de plus, pour le contexte prédéfini 'json',  la vue n'est pas nécessaire. Il désactive automatiquement le layout et envoi les variables de vue sérialisée (sauf si on ne le veut pas, voir la doc et la fonction setAutoJsonSerialization). Donc, le helper n'est pas nécessaire.


----
Gruiiik !

Hors ligne

 

#11 13-11-2008 14:19:13

Meardon
Nouveau membre
Date d'inscription: 10-10-2008
Messages: 7

Re: _response et JSON

alien7 a écrit:

Bonjour sebondus,
Pourquoi ne pa sutiliser le helper Json ?

Code:

$this->_helper->json(?); // ? à encoder

Ce helper désactibe automatquement la vue, le layout en envoi le bon header, tu n'as plus grand chose à écrire.

Voila the réponse on dirait ^^ Merci !

Hors ligne

 

#12 13-11-2008 19:27:29

sekaijin
Membre
Date d'inscription: 17-08-2007
Messages: 1137

Re: _response et JSON

j'utilse ça

Code:

            success:function(form, action){
                var res = Ext.util.JSON.decode(action.response.responseText);
...

mais avec EXtJS pour ce qui est des grid combo form et autre composant il suffit de lui donner l'url et de décrire la structure de la réponse. il fait le reste tout seul.

Je ne fais donc ça que dans de très rares cas.
A+JYT

Hors ligne

 

#13 14-11-2008 08:44:39

grandlap
Membre
Date d'inscription: 22-07-2008
Messages: 50

Re: _response et JSON

Salut,

la page de json recense des classes dans pas mal de langages pour parser du json
http://www.json.org/

Perso, je n'utilise pas eval en js et je ne le faisais pas non plus en actionscript1 (flash), ça peut créer des erreurs ou des trous de sécu...

a+

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages