Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour,
Je voudrais pouvoir renvoyer en json quelques choses comme
{"errorCallback": function(error) { ... } } ou {"errorCallback": ErrorCallback}
En php, on est obligé de passer par une string pour cela et du coup
Zend_Json::encode(array("errorCallback" => "function(error) { ... }")); Zend_Json::encode(array("errorCallback" => "ErrorCallback"));
donne
{"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
Hello,
C'est effectivement un bug connu (http://framework.zend.com/issues/browse/ZF-4946).
A+
Hors ligne
Merci,
La solution proposée est exactement celle que j'ai implémentée.
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; } }
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.
$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
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
ErrorCallback['sqlError'] = function (errorObj) {....}
et lorsque tu reçois ta réponse JSON tu fais
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
{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