Amaury.net Amaury.net
Discutons ! / Let's talk !
 
 FAQFAQ   RechercherRechercher   Liste des MembresListe des Membres   Groupes d'utilisateursGroupes d'utilisateurs   S'enregistrerS'enregistrer 
 ProfilProfil   Se connecter pour vérifier ses messages privésSe connecter pour vérifier ses messages privés   ConnexionConnexion 

Exemple : communication anet.ajax / serveur PHP

 
Poster un nouveau sujet   Répondre au sujet    Amaury.net Index du Forum -> Anet
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
amaury
Administrateur - Site Admin


Inscrit le: 04 Juin 2006
Messages: 72

MessagePosté le: Dim Nov 05, 2006 2:07 pm    Sujet du message: Exemple : communication anet.ajax / serveur PHP Répondre en citant

Nous allons faire un exemple très simple. Côté client, nous allons faire une calculatrice tellement bête qu'elle est obligée de demander au serveur de lui donner le résultat d'une opération. La communication entre les deux va se faire en utilisant anet.ajax, c'est-à-dire en envoyant et en recevant du JSON.

Si tout est bien intégré côté client, grâce à toute la librairie Anet, du côté serveur c'est une autre paire de manches. Vu qu'il va falloir recevoir, interpréter et renvoyer du JSON, il faut que nos scripts PHP aient à disposition des fonctions pour transformer le JSON en objets PHP (et inversement).
Pour cela, deux solutions s'offrent à nous :
1) Le mieux est d'ajouter la librairie json_php dans le serveur PHP. Il s'agit d'un module compilé, qui est donc incroyablement rapide. On peut soit installer "proprement" cette extension si elle est proposée par le système (commande "apt-get install php5-json" sous Linux Ubuntu par exemple), ou on peut la télécharger et l'installer (pas de crainte, c'est très simple).
2) S'il ne vous est pas possible de toucher à la configuration de votre serveur PHP, il faudra passer par des fonctions écrites en pur PHP. Vous pouvez télécharger le fichier et l'inclure pour bénéficier des mêmes fonctions que l'extension dont je parlais précédemment, mais évidemment avec une rapidité d'exécution moindre.

Maintenant, voyons nos fonctions Javascript, côté client. Pour simplifier les choses, nous allons limiter notre exemple aux fonctions d'addition et de multiplication.
Code:

function addition(valeur1, valeur2) {
    // creation de l'objet contenant les paramètres
    var parametres = {
        operateur: "+",
        operande1: valeur1,
        operande2: valeur2
    };
    // appel du serveur
    anet.ajax.send("communication.php", retour_addition, parametres);
}

function multiplication(valeur1, valeur2) {
    // creation de l'objet contenant les paramètres
    var parametres = {
        operateur: "*",
        operande1: valeur1,
        operande2: valeur2
    };
    // appel du serveur
    anet.ajax.send("communication.php", retour_multiplication, parametres);
}


Comme on peut le voir, les deux opérations se connectent au même script serveur. La différence se fait dans les paramètres envoyés au serveur (l'opérateur). On peut voir aussi que la fonction de retour n'est pas la même (retour_addition dans un cas, et retour_multiplication dans l'autre), et que les mécanismes de gestion de timeout n'ont pas été utilisés. Ca semble simple, non ?

Voici d'ailleurs un exemple de fonctions de callback :
Code:

function retour_addition(donnees) {
    alert("Resultat de l'addition : " + donnees.resultat);
    alert("Message : " + donnes.message);
}

function retour_multiplication(donnes) {
    alert("Resultat de la multiplication : " + donnees.resultat);
    alert("Message : " + donnes.message);
}


On se contente d'afficher le résultat, qui est sotcké dans l'attribut "resultat" de l'objet reçu du serveur. Au passage, on en profite pour afficher aussi un message envoyé en même temps par le serveur (ça ne sert à rien, c'est juste pour l'exemple).

Occupons-nous maintenant de nos script PHP, qui doit donc être disponible à l'adresse "communication.php".
Code:

<?php

// récupération des paramètres d'entrée
$input = json_decode(urldecode($HTTP_RAW_POST_DATA));
$operateur = $input->operateur;
$operande1 = $input->operande1;
$operande2 = $input->operande2

// calcul du résultat en fonction de l'opérateur demandé
if ($operateur == "+")
    $result = $operande1 + $operande2;
else if ($operateur == "*")
    $result = $operande1 * $operande2;

// préparation des données qui vont être renvoyées au client,
// constituées du résultat du calcul et d'un message textuel
$data = array(
    "resultat" => $result,
    "message" => "pouet pouet"
);

// envoit des informations, encodées en JSON
print(json_encode($data));

?>


Bon, cette partie est un peu moins simple, mais ça reste très accessible.


Astuce : Si vous ne savez pas si votre serveur contient l'extension json_php, vous pourriez être tenté d'inclure systématiquement la librairie JSON en PHP pur. Mais cela voudrait dire que vous risqueriez de perdre le bénéfice de l'extension json_php lorsqu'elle est installée. Vous pouvez dire à votre script de vérifier la présence de cette extension, et d'inclure la librairie que dans le cas où l'extension n'est pas présente. Pour cela, ajoutez le code suivant au début de votre script :
Code:

// inclusion de fonctions JSON si le module PHP JSON n'est pas charge
if (!function_exists("json_encode"))
    require_once("json.php");
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
Marcel



Inscrit le: 01 Nov 2006
Messages: 4

MessagePosté le: Dim Mar 25, 2007 5:58 pm    Sujet du message: HTTP_RAW_POST_DATA, array/object, extension Data Tamper Répondre en citant

Trois remarques:
1. Je n'ai rien dans ma variable $HTTP_RAW_POST_DATA. Sur le site de php j'ai trouvé une option qui expliquerait que cette variable ne soit pas renseignée. Avais-tu activé always_populate_raw_post_data dans ton php.ini ? Il serait peut-etre plus polyvalent de mettre dans ton exemple
Code:
$request = file_get_contents('php://input');

Ca m'a évité de toucher à php.ini.

2. Quelle est la nature de parametres qui ressort du json_decode ? car j'ai du transformer tes appels $input->XYZ en $input['XYZ'] dans le code PHP pour qu'il fonctionne. La notation que tu utilises semble créer un tableau associatif plutôt qu'un objet, non ?
Code:
        var parametres = {
                param1: ABC,
                param2: DEF
        };

Comment ferais-tu pour créer un objet JS et le récupèrerait-on alors comme un objet sous PHP ?

3. Enfin, je recommande fortement l'excellente extension firefox pour débugguer les appels ajax: Tamper Data. On retrouve les paramètres POST envoyés (avec la possibilité de décoder la notation URLencoded par un double click) et le code JSON retourné par le serveur (à l'aide du bouton droit puis "View Source").


Dernière édition par Marcel le Jeu Avr 12, 2007 4:44 pm; édité 1 fois
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
amaury
Administrateur - Site Admin


Inscrit le: 04 Juin 2006
Messages: 72

MessagePosté le: Lun Mar 26, 2007 10:57 pm    Sujet du message: Répondre en citant

Marcel a écrit:
Avais-tu activé always_populate_raw_post_data dans ton php.ini ?

Non, ce paramètre est commenté dans mon php.ini. Je ne sais pas d'où vient ton problème... Peut-être une différence de fonctionnement de base entre les PHP compilés sur Ubuntu et sur Gentoo ?

Marcel a écrit:
Il serait peut-etre plus polyvalent de mettre dans ton exemple
Code:
$request = file_get_contents('php://input');

Ca m'a évité de toucher à php.ini.

Dans la mesure où mon php.ini ne semble pas concerné, ça doit venir d'ailleurs. Wink

Marcel a écrit:
2. Quelle est la nature de parametres qui ressort du json_decode ? car j'ai du transformer tes appels $input.XYZ en $input['XYZ'] dans le code PHP pour qu'il fonctionne.

Attention, il y a des différences possibles de résultat entre le module php_json (à compiler dans PHP5, ou à ajouter comme module) et la librairie json.php. Peut-être que ça vient de là ?

Marcel a écrit:
La notation que tu utilises semble créer un tableau associatif plutôt qu'un objet, non ?
Code:
        var parametres = {
                param1: ABC,
                param2: DEF
        };

Ah non, désolé.
En Javascript, le bout de code que tu cites donne un objet. On peut accéder aux attributes en tapant "parametres.param1" et "parametres.param2". Si tu voulais avoir un tableau associatif, et accéder aux données par "parametres['param1']" et "parametres['param2']", il te faudrait écrire :
Code:
var parametres = new Array();
parametres["param1"] = ABC;
parametres["param2"] = DEF;


Marcel a écrit:
3. Enfin, je recommande fortement l'excellente extension firefox pour débugguer les appels ajax: Tamper Data.

Je ne connaissais pas. Merci pour l'astuce.
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un e-mail
Marcel



Inscrit le: 01 Nov 2006
Messages: 4

MessagePosté le: Mar Mar 27, 2007 10:11 am    Sujet du message: Répondre en citant

Citation:
Attention, il y a des différences possibles de résultat entre le module php_json (à compiler dans PHP5, ou à ajouter comme module) et la librairie json.php. Peut-être que ça vient de là ?
Les fonctions JSON ont été intégrées à PHP à partir de la version 5.2. Je prévois de me mettre à jour, alors je me contenterai de la lib json.php pour l'instant. C'est embêtant tout de même qu'elle ait ce défaut... je crains de devoir modifier mon code à l'upgrade. Merci pour les précisions syntaxiques.

Citation:
Non, ce paramètre est commenté dans mon php.ini. Je ne sais pas d'où vient ton problème...
Regarde ton phpinfo(). Chez moi la valeur est mise à zéro par défaut et ça semble être la valeur standard. Je suggère d'utiliser le bout de code
Code:
if (!isset($HTTP_RAW_POST_DATA))
   $HTTP_RAW_POST_DATA = file_get_contents("php://input");


Une petite précision trouvée sur www.php.net:
Citation:
This substitutes the old $HTTP_RAW_POST_DATA variable available in some of the previous 4.x versions. It is available for other upload methods different from POST too, but it is not available for POSTs with multipart/form-data content type, since the file upload handler has already taken care of the content in that case.
et dans http://fr2.php.net/manual/fr/wrappers.php.php
Citation:
php://input permet de lire des données POST bruts. C'est moins gourmand en mémoire que $HTTP_RAW_POST_DATA et il n'y a pas de directive spéciale dans php.ini. php://input n'est pas disponible avec enctype="multipart/form-data".
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
Marcel



Inscrit le: 01 Nov 2006
Messages: 4

MessagePosté le: Jeu Avr 12, 2007 4:58 pm    Sujet du message: Différence json.php: json_decode cast un objet en tableau Répondre en citant

amaury a écrit:

Marcel a écrit:
2. Quelle est la nature de parametres qui ressort du json_decode ? car j'ai du transformer tes appels $input->XYZ en $input['XYZ'] dans le code PHP pour qu'il fonctionne.

Attention, il y a des différences possibles de résultat entre le module php_json (à compiler dans PHP5, ou à ajouter comme module) et la librairie json.php. Peut-être que ça vient de là ?

Je confirme ! Je viens de passer à la version PHP5.2.1 qui intègre désormais les deux fonctions json compilées en code natif, et le comportement est différent. Pour que les choses soient claires:
* La librairie json.php: un object côté Javascript est décodé en un tableau par PHP. J'aurai peut-être d'autres surprises dans l'autre sens ? Confused
* Le code compilé respecte bien l'objet et l'objet Javascript réapparaît bien comme un objet à la sortie du json_decode. Je n'ai pas essayé de passer un objet contenant un objet. Je ne sais pas si on recevrait dans le cas de la librairie json.php un tableau contenant un objet ou un tableau contenant un tableau.
Pour ceux qui ont la flemme de ré-écrire leur application, le transtypage est pratique:
Code:
$input = (array) json_decode(...)
[/code].
Revenir en haut de page
Voir le profil de l'utilisateur Envoyer un message privé
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    Amaury.net Index du Forum -> Anet Toutes les heures sont au format GMT + 2 Heures
Page 1 sur 1

 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum


Powered by phpBB © 2001, 2005 phpBB Group
Traduction par : phpBB-fr.com