Page 1 sur 2

Transformer un tableau PHP en tableau Javascript

Posté : 24 sept. 2008, 16:33
par VaN
Bonjour,

Je crée un nouveau sujet, car j'ai trouvé la solution à mon problème précédent.
Mais ce nouveau problème est toujours lié à l'application sur laquelle je travaille.

J'ai un fichier PHP getPrices.php, qui me renvoie le tableau PHP suivant :

Code : Tout sélectionner

Array ( [100] => 10 [151] => 14 [201] => 18 [251] => 22 [301] => 26 [351] => 30 [401] => 34 [451] => 38 )
Ce fichier PHP est appelé via AJAX :

Code : Tout sélectionner

var pricesNoLight10 = creerXHR('getPrices.php?price_type='+ type);
J'aimerai transformer ce tableau PHP reçu par Javascript en tableau Javascript de même forme :

Code : Tout sélectionner

pricesNoLight10[100] = 10; pricesNoLight10[151] = 14; pricesNoLight10[201] = 18; pricesNoLight10[251] = 22; pricesNoLight10[301] = 26; pricesNoLight10[351] = 30; pricesNoLight10[401] = 34; pricesNoLight10[451] = 38;
Comment dois-je m'y prendre ?

Posté : 24 sept. 2008, 17:08
par Berzemus
Tout simple: tu utilises JSON.

Du côté php, il suffit d'appeler queqlue chose comme ça:
echo json_encode($montableau);
et du côté javascript, ben ce sera déjà tout de suite comme un tableau/objet/

Et pour renverser le truc, il suffit d'un json_decode.

A noter qu'il y a des scripts et astuces pour plein de langages sur http://www.json.org

Posté : 24 sept. 2008, 17:41
par VaN
Tout simple: tu utilises JSON.

Du côté php, il suffit d'appeler queqlue chose comme ça:
echo json_encode($montableau);
et du côté javascript, ben ce sera déjà tout de suite comme un tableau/objet/

Et pour renverser le truc, il suffit d'un json_decode.

A noter qu'il y a des scripts et astuces pour plein de langages sur http://www.json.org
Je viens de découvrir json, je ne connaissais pas. Dans mon fichier PHP, un json_encode($result) semble bien marcher, puisqu'il me renvoie
{"price_range_bottomvalue":"100","price_value":"10"}{"price_range_bottomvalue":"151","price_value":"14"}{"price_range_bottomvalue":"201","price_value":"18"}{"price_range_bottomvalue":"251","price_value":"22"}{"price_range_bottomvalue":"301","price_value":"26"}{"price_range_bottomvalue":"351","price_value":"30"}{"price_range_bottomvalue":"401","price_value":"34"}{"price_range_bottomvalue":"451","price_value":"38"}


Mais je ne comprend pas comment, une fois dans mon script Javascript, transformer cette valeur en tableau JS.

Posté : 24 sept. 2008, 19:05
par Cyrano
Tu affectes simplement le résultat de json_encode() à une variable JavaScript et ensuite tu peux la traiter telle-quelle en JavaScript. C'est toute la magie de la chose.

Pour mémoire, JSON = JavaScript Object Notation
En d'autres termes, on convertit d'un langage vers un objet JavaScript.

Posté : 24 sept. 2008, 19:16
par VaN
Tu affectes simplement le résultat de json_encode() à une variable JavaScript
Jusque là, pas de problème. Je fais ceci, dans mon fichier PHP :
$prices = array();
$sql = 	"SELECT price_range_bottomvalue, price_value FROM ".$cfg_prefixe."prices 
		WHERE price_type = '".$_REQUEST['price_type']."' ORDER BY price_range_bottomvalue";
$query = mysql_query($sql) or die(mysql_error());
while($result = mysql_fetch_assoc($query)) {
	$prices[] = $result;
}
echo json_encode($prices);
et mon script JS la récupère ainsi :

Code : Tout sélectionner

var JSONFile = creerXHR('getPrices.php?price_type='+ type);
Ca, ça fonctionne, un alert(JSONFile); me renvoie
[{"price_range_bottomvalue":"100","price_value":"10"},{"price_range_bottomvalue":"151","price_value":"14"},{"price_range_bottomvalue":"201","price_value":"18"},{"price_range_bottomvalue":"251","price_value":"22"},{"price_range_bottomvalue":"301","price_value":"26"},{"price_range_bottomvalue":"351","price_value":"30"},{"price_range_bottomvalue":"401","price_value":"34"},{"price_range_bottomvalue":"451","price_value":"38"}]
et ensuite tu peux la traiter telle-quelle en JavaScript. C'est toute la magie de la chose.

Pour mémoire, JSON = JavaScript Object Notation
En d'autres termes, on convertit d'un langage vers un objet JavaScript.
C'est là que ça coince. Comment je peux traiter cette chaine ? J'ai essayé pas mal de choses, en regardant entre autre sur http://www.hunlock.com/blogs/Mastering_ ... t_Notation_) mais je n'arrive pas à extraire les valeurs.

J'implore votre aide, car je suis extrêmement pressé par le temps :oops: (cette application aurait dûe être finie fin de semaine dernière).

Posté : 24 sept. 2008, 19:33
par Cyrano
Une image vaut mille mots, en l'occurence, un peu de code devrait t'éclairer :

Code : Tout sélectionner

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> <head> <title>Échanges JSON PHP/JavaScript</title> </head> <body> <script type="text/javascript">/* <![CDATA[ */ var JSONfile = [ {"price_range_bottomvalue":"100","price_value":"10"}, {"price_range_bottomvalue":"151","price_value":"14"}, {"price_range_bottomvalue":"201","price_value":"18"}, {"price_range_bottomvalue":"251","price_value":"22"}, {"price_range_bottomvalue":"301","price_value":"26"}, {"price_range_bottomvalue":"351","price_value":"30"}, {"price_range_bottomvalue":"401","price_value":"34"}, {"price_range_bottomvalue":"451","price_value":"38"} ]; var msg = ''; for(var i in JSONfile) { msg += ' - Prix bas : '+ JSONfile[i].price_range_bottomvalue +'; Prix : '+ JSONfile[i].price_value +'\n'; } alert(msg); /* ]]> */</script> </body> </html>
Essaye ça tel quel et observe le résultat :)

Explication sommaire : en JavaScript avec une notation Objet, pour créer un tableau on écrit :

Code : Tout sélectionner

var mavar = [];
et non

Code : Tout sélectionner

var mavar = new Array();
Ensuite, tu as dans ton exemple des accolades : ce sont des "sous-objets", chacun contenant deux index associatifs : price_range_bottomvalue et price_value.
Chaque accolade correspond à un élément du tableau de base JSONfile : avec ma boucle for() version JavaScript, je vais utiliser un index numérique pour pointer sur chacun de ces "sous-objets" et en récupérer la valeur.

Est-ce que comme ça tu saisis mieux le fonctionnement ?

Posté : 24 sept. 2008, 21:09
par VaN
Image

:oops:

C'est à peu près la même chose que j'ai réussi à faire lors de mes bidouillages avant de poster, du "undefined" sur tout ce que je testais : /

Je comprend un peu le principe de ton script. Saurais-tu d'où peut venir ce undefined ?

EDIT : en fait ton script marche bien. Mais il semblerait que ça soit ce que je récupère de la fonction AJAX qui ne soit pas bon.

Pourtant, lorsque je browse mon fichier php, voilà ce qu'il renvoie :
[{"price_range_bottomvalue":"100","price_value":"10"},{"price_range_bottomvalue":"151","price_value":"14"},{"price_range_bottomvalue":"201","price_value":"18"},{"price_range_bottomvalue":"251","price_value":"22"},{"price_range_bottomvalue":"301","price_value":"26"},{"price_range_bottomvalue":"351","price_value":"30"},{"price_range_bottomvalue":"401","price_value":"34"},{"price_range_bottomvalue":"451","price_value":"38"}]
c'est à dire la même chose que ta variable JSONfile.

D'où vient mon erreur ?

Code : Tout sélectionner

var JSONfile = creerXHR('getPrices.php?price_type='+ type); var msg = ''; for(var i in JSONfile){ msg += ' - Prix bas : '+ JSONfile[i].price_range_bottomvalue +'; Prix : '+ JSONfile[i].price_value +'\n'; } alert(msg);
$prices = array();

$sql = 	"SELECT price_range_bottomvalue, price_value FROM ".$cfg_prefixe."prices 
		WHERE price_type = '".$_REQUEST['price_type']."' ORDER BY price_range_bottomvalue";
$query = mysql_query($sql) or die(mysql_error());
while($result = mysql_fetch_assoc($query)) {
	$prices[] = $result;
}
echo json_encode($prices);

Posté : 24 sept. 2008, 22:17
par Cyrano
La source HTML de ta page générée ressemble à quoi au juste ?

Posté : 24 sept. 2008, 23:28
par Berzemus
Hum, un détail je crois, mais le contenu retourna par ta fonction XHR est peut-être du simple texte.. Et donc, pour que ça fonctionne, il faut que JS l'interprète..

Genre:

Code : Tout sélectionner

var monBoObjet = eval('(' + texteJson + ')');
Mais eval est dangereux, et pour ne pas se tuer en protections, des objets tout faits existent:
http://www.json.org/json2.js

J'oubliais de le préciser, comme Jquery l'interprète tout seul comme un grand.. 8-) .

source: json.org

Posté : 25 sept. 2008, 00:04
par sadeq
On peut utiliser prototype aussi qui intègre le support json et ajax.

Le principe est le suivant:
Côté PHP (version 5.2 et +) json est intégré et par défaut activé, on peut donc coder un array PHP au format json (ça c'est déjà fait) ok:
Voici donc l'exemple du serveur de notre tableau json. On l'appellera : jSonPricesArray.php
<?php 
$prices = array(
	array('price_range_bottomvalue'=>100, 'price_value'=>10),
	array('price_range_bottomvalue'=>151, 'price_value'=>14),
	array('price_range_bottomvalue'=>201, 'price_value'=>18),
);
echo json_encode($prices); 
?>
Côté HTML, on a besoin du support Ajax pour appeler le service : jSonPricesArray.php et du support jSon pour mettre en forme le résultat retourné à Ajax.
Pour celà, on va utiliser le framework prototype (dernière version stable) ainsi pour démarrer un appel Ajax on va utiliser la fonction suivante:

Code : Tout sélectionner

function getPricesFromAjaxArray() { // on utilise ici les supports Ajax et json du framework prototype new Ajax.Request("jSonPricesArray.php", { method:"get", onSuccess: function(response){ showPrices (response.responseText.evalJSON()); //avec conversion de la réponse Ajax au format jSon } }); }
L'événement onSuccess se déclenche quand Ajax reçoit la réponse du service appelé. Réponse représentée par le paramètre "response".
La fonction attachée à l'événement onSuccess appelle, en fait, une autre fonction qu'on va écrire en lui passant comme paramètre la réponse Ajax (propriété "responseText") sans oublier de la formater au format jSon par la méthode "evalJSON()" de prototype.

La fonction showPrices(untableau) attend en entrée un tableau au format objet json de javascript qu'elle va parcourir de 0 à N (length du tableau) et afficher ses cases une par une. Voici comment:

Code : Tout sélectionner

function showPrices(prices) { var msg = ''; for(var i=0; i<prices.length; i++) { msg += ' - Prix bas : '+ prices[i].price_range_bottomvalue +'; Prix : '+ prices[i].price_value +'\n'; } alert(msg); }
Et voilà, c'est fini.

Pour démarrer le processus, il faut appeler en premier la fonction Ajax: getPricesFromAjaxArray()

Voici le récap du code HTML général:

Code : Tout sélectionner

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"> <head> <title>Échanges JSON PHP/JavaScript</title> <script type="text/javascript" src="prototype-1.6.0.2.js"></script> <script type="text/javascript"> //Récupérer le tableau jSon par Ajax (données provenant d'un serveur PHP) function getPricesFromAjaxArray() { // on utilise ici les supports Ajax et json du framework prototype new Ajax.Request("jSonPricesArray.php", { method:"get", onSuccess: function(response){ showPrices (response.responseText.evalJSON()); //avec conversion de la réponse Ajax au format jSon } }); } //Afficher le tableau jSon function showPrices(prices) { var msg = ''; for(var i=0; i<prices.length; i++) { msg += ' - Prix bas : '+ prices[i].price_range_bottomvalue +'; Prix : '+ prices[i].price_value +'\n'; } alert(msg); } //Appel Ajax getPricesFromAjaxArray(); </script> </head> <body> </body> </html>

Posté : 25 sept. 2008, 02:12
par VaN
Merci beaucoup pour cette aide, je commence à avancer.

En me claquant sur ton post sadeq, j'en suis arrivé là :
Mes deux fonctions JS :

Code : Tout sélectionner

//Récupérer le tableau jSon par Ajax (données provenant d'un serveur PHP) function getPricesFromAjaxArray(){ // on utilise ici les supports Ajax et json du framework prototype new Ajax.Request("getPrices.php", { method:"get", onSuccess: function(response){ loadPrices (response.responseText.evalJSON()); //avec conversion de la réponse Ajax au format jSon } }); } //Afficher le tableau jSon function loadPrices(prices){ var msg = ''; var pricesTest = new Array(); for(var i=0; i<prices.length; i++) { pricesTest[prices[i].price_range_bottomvalue] = prices[i].price_value; } document.getElementById('pricesTab').value = pricesTest; }
Mon fichier PHP :
<?php
require_once 'connexion.php';

$prices = array();

$_REQUEST['price_type'] = 10;

$sql = 	"SELECT price_range_bottomvalue, price_value FROM ".$cfg_prefixe."prices 
		WHERE price_type = '".$_REQUEST['price_type']."' ORDER BY price_range_bottomvalue";
$query = mysql_query($sql) or die(mysql_error());
while($result = mysql_fetch_assoc($query)) {
	$prices[] = array('price_range_bottomvalue'=>$result['price_range_bottomvalue'],'price_value'=>$result['price_value']) ;
}

echo json_encode($prices);

?>
Jusque là tout va bien.
Le problème est que je dois utiliser le tableau JS pricesTest généré, dans une nouvelle fonction getPrice(), qui elle va récupérer la bonne ligne du tableau, en fonction de price_range_bottomvalue, et qui va faire quelques opérations, pour enfin afficher le résultat dans un <div>.

Ne sachant pas passer une variable d'une fonction à l'autre, sans la fournir en attribut de la fonction getPrice() (getPrice() doit rester vierge d'attribut, car elle va être appelée à de multiples reprises sur des onclick de l'utilisateur), j'ai tenté de passer le tableau pricesTest dans la value d'un <input>, comme on le voit à la fin de la fonction loadPrices(prices).

Malheureusement, lorsque je tente de le récupérer dans ma fonction de calcul du prix ( getPrice() ), un

Code : Tout sélectionner

alert(typeof(document.getElementById('pricesTab').value));
me renvoie string, et je retombe sur des undefined lorsque je tente d'afficher les valeurs du tableau.

Existe t'il une solution plus simple, qui me permetttrait de passer le tableau pricesTest vers ma fonction de calcul, sans la lui fournir en attribut ?

Posté : 25 sept. 2008, 06:39
par Cyrano
Mais eval est dangereux
Oui, si tu n'as pas le contrôle sur les paramètres que tu passes à cette fonction. Mais là, je suis moins certain que ce soit le cas.

Et mentionner AJAX dès le départ aurait fait avancer plus rapidement ... et sur ce point, Berzemus a raison : il faut faire un eval de la chaine reçue.

Maintenant je vous signale aussi qu'utiliser une librairie existante comme prototype, ou n'importe quelle autre, ça revient à ajouter un traitement de plus pour finalement découvrir que c'est toujours eval qui est utilisé...

Posté : 25 sept. 2008, 10:38
par Berzemus
Interméde d'illustration, voici la méthode de JQuery pour récupérer du Json:

Code : Tout sélectionner

$.getJSON("./getPrices.php", function(data){ loadPrices(data); });
Cé Bô 8-)

Pour ce qui est de ton tableau, pourquoi ne pas utiliser une variable globale ? ou mieux, enregistrer ton tableau dans un objet, qui en gère alors l'accès ?

Posté : 25 sept. 2008, 11:48
par VaN
Interméde d'illustration, voici la méthode de JQuery pour récupérer du Json:

Code : Tout sélectionner

$.getJSON("./getPrices.php", function(data){ loadPrices(data); });
Cé Bô 8-)

Pour ce qui est de ton tableau, pourquoi ne pas utiliser une variable globale ? ou mieux, enregistrer ton tableau dans un objet, qui en gère alors l'accès ?

Je n'y connais vraiment rien en POO. Comment je l'enregistre dans un objet ? Et comment j'appelle cette valeur, une fois dans ma fonction de calcul ?

Posté : 25 sept. 2008, 13:06
par Berzemus
Je n'y connais vraiment rien en POO. Comment je l'enregistre dans un objet ? Et comment j'appelle cette valeur, une fois dans ma fonction de calcul ?
Ah.. alors, pour faire court (a moins de préférer la voie difficile mais Ô combien valorisante), tu peux utiliser une variable globale, que tu déclares en dehors de toute fonction (avec 'var'). Ensuite, tu pourras appeler cette variable depuis tes fonctions.