Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 14-02-2009 14:03:13

cortex
Membre
Date d'inscription: 22-05-2008
Messages: 33

[Zend_JSon] et fonction javascript

Bonjour,

Je voudrais pouvoir renvoyer en json quelques choses comme

Code:

{"errorCallback": function(error) { ... } }
ou
{"errorCallback": ErrorCallback}

En php, on est obligé de passer par une string pour cela et du coup

Code:

Zend_Json::encode(array("errorCallback" => "function(error) { ... }"));
Zend_Json::encode(array("errorCallback" => "ErrorCallback"));

donne

Code:

{"errorCallback": "function(error) { ... }" }
{"errorCallback": "ErrorCallback"}

La fonction de base de php json_encode n'a pas l'air d'avoir de solution pour ça et l'encoder du framework Zend non plus.

Dites-moi que je suis aveugle :p

cortex

Dernière modification par cortex (14-02-2009 14:03:43)

Hors ligne

 

#2 14-02-2009 17:44:42

mikaelkael
Administrateur
Lieu: Donges
Date d'inscription: 18-06-2007
Messages: 1176
Site web

Re: [Zend_JSon] et fonction javascript

Hello,

C'est effectivement un bug connu (http://framework.zend.com/issues/browse/ZF-4946).

A+


Less code = less bugs
Contributeur ZF - ZCE - ZFCE - Doc ZF (CHM & PDF) - Vice-trésorier AFUP 2011
Ubuntu 11.04 - ZendServer

Hors ligne

 

#3 14-02-2009 20:09:07

cortex
Membre
Date d'inscription: 22-05-2008
Messages: 33

Re: [Zend_JSon] et fonction javascript

Merci,

La solution proposée est exactement celle que j'ai implémentée.

Code:

class Freeh_Json_Expr
{
    /**
     * Storage for the javascript expression.
     *
     * @var string
     */
    protected $_expression;

    /**
     * Instantiate an expression, which is just a string stored as
     * an instance member variable.
     *
     * @param string $expression The string containing a javascript expression.
     */
    public function __construct($expression)
    {
        $this->_expression = (string) $expression;
    }

    /**
     * @return string The string of the javascript expression stored in this object.
     */
    public function __toString()
    {
        return $this->_expression;
    }

}

Code:

class Freeh_Json_Encoder extends Zend_Json_Encoder
{
    public static function encode($value, $cycleCheck = false, $options = array())
    {
        $encoder = new self(($cycleCheck) ? true : false, $options);

        return $encoder->_encodeValue($value);
    }
    
    
    protected function _encodeObject(&$val)
    {
        if ($val instanceof Freeh_Json_Expr) {
            return $val->__toString();
        }
        else return parent::_encodeObject($val) ;
    }
}

Le pattern factory du Zend_Json_Encoder n'étant pas abstrait, il a fallut redefinir la méthode encode et par conséquent, il faut appeler celle-ci ce qui empeche de passer par Zend_Json::encode en ayant mis la variable statique $useBuiltinEncoderDecoder à true.

Code:

$valueToEncode = array('errorCallback' => 'function(error) { ... } ');
$json = Freeh_Json_Encoder::encode($valueToEncode);

Voilà, en attendant une intégration plus élégante dans le framework.

Dernière modification par cortex (14-02-2009 20:09:48)

Hors ligne

 

#4 15-02-2009 15:16:24

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

Re: [Zend_JSon] et fonction javascript

personnellement je déconseille le passage de fonction par JSON
pour moi JSON ne doit porter que des données.

si un fonction doit être activée par le client alors c'est au client de le faire et de posséder cette fonction. il en va de la séparation des couche et de la pérennité du code.

en clair le serveur envois un objet erreur et le client suivant le contenu de l'erreur active une de ses propre fonctions

je dit toujours à ceux qui font ce que tu cherche à faire et si demain on te demande de faire un client JSON écrit dans un langage qui ne connais pas JavaScript tu vas reécrire ton serveur ?

si tu veux travailler en objet et que ton callback d'erreur dépende du type d'erreur c'est simple tu fais des class javascript dans des fichiers statiques et ton JSON retourne un objet erreur typé
le client lors de la réception instancie la bonne classe en fonction de l'erreur et appelle le callback défini dans la classe.

sinon si tu veux de simple fonction de callbak d'erreur tu peux faire un lib de fonctions

Code:

ErrorCallback['sqlError'] = function (errorObj) {....}

et lorsque tu reçois ta réponse JSON tu fais

Code:

response = JSON_decode(ajax.responseText);
if (isError(response)) {
   ErrorCallback[response.errorCode] (response);
} else {
...

et ton serveur s'il rencontre une erreur ne retourne qu'un objet genre

Code:

{error: true, errorCode: 'sqlError', errorMessage: 'Ilicit Syntax on line ...'}

en faisant ainsi tu définit un protocole d'échange de donnée entre le serveur et le client mais tu ne présume en rien de la façon dont il sera utilisé.

si tu cjange de langage pour le client que tu change de gestionnaire d'erreur ou tout autre chose dans ton serveur ou ton client les échange restent valables.

et pour finir si ton client est en javascript les fonction de calback étant dans un fichier js elles ne sont chargé qu'une fois compilées qu'une fois (alors que les passer dans le json t'oblige à les recompilé à chaque appel)

au final ne pas passer de fonction dans le JSON c'est
réduire la taille des échange
accélérer le traitement
séparer les couche
gagner en évolutivité
gagner en réutilisabilité

Je n'ai pour le moment pas trouvé de défaut à cette approche.
A+JYT

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