JeuWeb - Crée ton jeu par navigateur
[Résolu][Javascript] Ajax et variables globales - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Résolu][Javascript] Ajax et variables globales (/showthread.php?tid=3101)

Pages : 1 2


[Résolu][Javascript] Ajax et variables globales - Ruz - 27-09-2008

Et me revoilà avec une variable qui m'ennuie profondément...

je vous donne un code complet de test:
fichier .php
Code PHP :
<?php
session_start
();
require_once(
'../Admin/config.php');
$code_html_0='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//FR" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Supra Online : Test comportement Ajax</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />'
;
//récupération du perso
$req='SELECT `ID_kalidhia`,`CSS`, `Libre`, `Objet` FROM `perso` WHERE `ID`='.$_SESSION["ID_perso"].' LIMIT 1';
$res=mysql_query($req,$base_id) or die ('Erreur de chargement des données du personnage');
if(
mysql_num_rows($res)==1){$perso=mysql_fetch_assoc($res);}
else{}
//recréer perso
//CSS
$code_CSS="";
$code_CSS.='<link rel="stylesheet" type="text/css" href="../CSS/Style.css">';
$code_CSS.='<link rel="stylesheet" type="text/css" href="../CSS/mini.css">';
//JS
$code_JS='<script type="text/javascript" src="../Scripts/overlib.js"><!-- overLIB (c) Erik Bosrup --></script>';
$code_menu='</head><body>
<div id="menu">
<ul>
<li><a href="entree.php"'
; if($_GET["p"]=="connect"){$code_menu.=' class="actif"';} $code_menu.='><span>Changer de perso</span></a></li>
<li><a href="index.php?p=perso"'
; if($_GET["p"]=="perso"){$code_menu.=' class="actif"';} $code_menu.='><span>'.$_SESSION["Nom_perso"].'</span></a></li>
<li><a href="index.php?p=inventaire"'
; if($_GET["p"]=="inventaire"){$code_menu.=' class="actif"';} $code_menu.='><span>Inventaire</span></a></li>
<li><a href="index.php?p=compet"'
; if($_GET["p"]=="compet"){$code_menu.=' class="actif"';} $code_menu.='><span>Compétences</span></a></li>
<li><a href="index.php?p=map" title="votre vue"'
; if($_GET["p"]=="map"){$code_menu.=' class="actif"';} $code_menu.='><span>Carte</span></a></li>
<li><a href="index.php?p=lieu"'
; if($_GET["p"]=="lieu"){$code_menu.=' class="actif"';} $code_menu.='><span>Lieu</span></a></li>
<li><a href="index.php?p=messagerie"'
; if($_GET["p"]=="messagerie"){$code_menu.=' class="actif"';} $code_menu.='><span>Messagerie</span></a></li>
<li><a href="index.php?p=journal"'
; if($_GET["p"]=="journal"){$code_menu.=' class="actif"';} $code_menu.='><span>Journal de bord</span></a></li>
<li><a href="index.php?p=compagnie"'
; if($_GET["p"]=="compagnie"){$code_menu.=' class="actif"';} $code_menu.='><span>Compagnie</span></a></li>
<li><a href="index.php?p=guilde"'
; if($_GET["p"]=="guilde"){$code_menu.=' class="actif"';} $code_menu.='><span>Guilde(s)</span></a></li>
<li><a href="index.php?p=option"'
; if($_GET["p"]=="option"){$code_menu.=' class="actif"';} $code_menu.='><span>Options</span></a></li>
<li><a href="../forum/index.php"><span>Forums</span></a></li>'
;
if(
$_SESSION["Admin"]==1){$code_menu.='<li><a href="../Dvlpt/index.php"><span>Administration</span></a></li>';}
$code_menu.='<li><a href="../index.php?action=Déconnecter"><span>Déconnection</span></a></li>
</ul>
</div>
<div id="content">'
;
$code_JS.='<script type="text/javascript" src="test_ajax_comportement.js"></script>';
//calcul X et Y
$X=$perso["ID_kalidhia"]%190;
$Y=floor($perso["ID_kalidhia"]/190);

$requete="SELECT ID, Nom, x, y FROM ville WHERE x=".$X." AND y=".$Y;
//echo '<p class="info">Requête : '.$requete.'</p>';
$resultat=mysql_query($requete,$base_id) or die ('[Lieu] Requête impossible : '.mysql_error());
if(
mysql_num_rows($resultat)==0)
{
//echo '<p class="info">Vous ne vous trouvez pas sur un lieu particulier</p>';
//donc, carte normale... génération, ou pas?
include ('mini_map_controle.inc.php');
//récupérer le dernier ID du chat au chargement
$res=mysql_query('SELECT `ID` FROM `chat_kalidhia` ORDER BY `ID` DESC LIMIT 1',$base_id);
if(
mysql_num_rows($res)==1){$d=mysql_fetch_assoc($res); $last_IDchat=$d["ID"]; mysql_free_result($res);}
else{
$last_IDchat=0;}
//affichage
echo $code_html_0.$code_CSS.$code_JS.$code_menu;


//quoiqu'il arrive, on rentre en mini-carte
echo '<div>Votre position continent : X='.$X.'/ Y='.$Y.'</div>';
echo
'<div id="barre_comp"></div>';
echo
'<div id="carte"><img src="images/ajax-loader.gif" /></div>';

echo
'<div id="mini-move">';
include(
'mini_map_mouvement.inc.php');
echo
'</div>';
echo
'<span class="info" id="msg" style="border: double 3px black;">messages de retour</span>';
echo
'<span class="info" id="info"></span>';
echo
'<div class="info" id="sortie"></div>';
echo
'</div>';
//debug
echo '<input type="button" id="test" onClick="alert(\'Décor demandé (12)= \' + load_decor(12));" value="test decor" />';
//les appels ajax
echo '<script language="javascript">show_decor();var rep=load_decor("5,8,12"); SetDiv(rep,"info"); show_decor();</script>';
}
?>

un fichier .js intégré:
Code PHP :
<?php 
var t_decor = new Array();
var
t_decor_2 = new Array();
var
mem_d= new Array();

function
addslashes(str) {
str=str.replace(/\'/g,'\\\'');
str=str.replace(/\"/g,'\\"');
str=str.replace(/\\/g,'
\\\\');
str=str.replace(/\0/g,'
\\0');
return str;
}
function stripslashes(str) {
str=str.replace(/\\'
/g,'\'');
str=str.replace(/\\"/g,'"');
str=str.replace(/\\\\/g,'
\\');
str=str.replace(/\\0/g,'
\0');
return str;
}
function SetDiv(text,div)
{
if (document.getElementById)
{
document.getElementById(div).innerHTML = '';
document.getElementById(div).innerHTML = text;
}
else if (document.all)
{
x = document.all[div];
x.innerHTML = text;
}
else if (document.layers)
{
x = document.layers[div];
text2 = '
<p class="testclass">' + text + '</p>';
x.document.open();
x.document.write(text2);
x.document.close();
}
}

function load_decor(liste_ID)
{
var suivi='
<u>Suivi de la requete Ajax :</u>';
var cpt = -1;
//méthode AJAX
var xhr_object = null;
if(window.XMLHttpRequest){xhr_object = new XMLHttpRequest();} // FIREFOX
else if(window.ActiveXObject){xhr_object = new ActiveXObject("Microsoft.XMLHTTP");} // IE
else{alert('
Votre navigateur ne supporte pas les objets XMLHttpRequest');}
//on spécifie la méthode de transfert des données
xhr_object.open("GET", '
ajax.load_decor.php?ID=' + liste_ID , true); //synchrone => on affiche rien tant que ce n'est pas chargé
//on éxécute la requête
xhr_object.onreadystatechange = function()
{
try
{
if(
xhr_object.readyState == 4) //données reçues!
{
suivi +='<br />Réponse reçue';
SetDiv(suivi,'msg');
var
Data = xhr_object.responseText;
SetDiv(Data, 'info');
// message recu: Etat*detail
var reg=new RegExp("[*]+", "g");
var
tab=Data.split(reg);
//on met à jour
if(tab[0]=="KO"){SetDiv('Décor erreur : ' + tab[1],'info');}
else if(
tab[0]=="OK")
{
//detail contient plusieurs décors séparés par "µ"
reg=new RegExp("[µ]", "g");
var
grp=tab[1].split(reg);
for
each(a in grp)
{
var
reg=new RegExp("[¤]+", "g");
var
d=a.split(reg);
cpt=t_decor.length;
suivi +='<br />Traitement Décor N°' + d[0];
SetDiv(suivi,'msg');
t_decor[cpt]= new Array(d[0],stripslashes(d[1]),d[2],d[3],d[4],d[5],d[6],d[7],d[8]);
//ID, nom, Image, Bloc, Hauteur, Largeur, Transparent, Action, remplacement
//SetDiv('','info');
//test variables
t_decor_2[d[0]]=new Array(d[0],stripslashes(d[1]),d[2],d[3],d[4],d[5],d[6],d[7],d[8]);
}
}
suivi +='<br />Fin de la requete';
SetDiv(suivi,'msg');
suivi='';
//affichage du contenu des variables globales
for(a in t_decor){suivi +='<br />t_decor['+a+'][0]='+t_decor[a][0]+'<br />t_decor['+a+'][1]='+t_decor[a][1];}
SetDiv(suivi,'info');
//return cpt;
}
else if(
xhr_object.readyState == 1) //données envoyées
{
SetDiv('Requete préparée','info');
suivi +='<br />Requete préparée pour ' + liste_ID;
SetDiv(suivi,'msg');
cpt="_1";
}
else if(
xhr_object.readyState == 2) //données envoyées
{
SetDiv('Requete reçue par le serveur','info');
suivi +='<br />Requete reçue par le serveur';
SetDiv(suivi,'msg');
cpt="_2";
}
else
//données en cours
{
SetDiv('Mise à jour des décors','info');
cpt=-2;
suivi +='<br />Requete en cours sur ' + liste_ID;
SetDiv(suivi,'msg');
}
//suivi +='<br />Fin onreadyStateChange()';
//SetDiv(suivi,'msg');
}
catch(
e)
{
alert("Une exception s'est produite : " + e.description);
}
}
xhr_object.send(null);
suivi +='<br />Envoi de la requete';
SetDiv(suivi,'msg');
}

function
show_decor()
{
var
suivi='<u>Données en T_decor:</u>';
suivi+='<br />Taille : '+t_decor.length;
for(
a in t_decor){suivi +='<br />t_decor['+a+'][0]='+t_decor[a][0]+' --- t_decor['+a+'][1]='+t_decor[a][1];}
SetDiv(suivi,'sortie');
}

je ne met pas les sources du fichiers retournant les données des décors demandés.. Testé, il marche au poil.

en résumé... je demande au serveur de me renvoyer les données de 3 décors de la carte. Je les recois, et je les met en mémoire dans deux tableaux: t_decor et t_decor_2 (le premier a un index croissant avec les demandes successives, le second a un index correspondant à l'ID du décor (je teste un peu les deux))

le but étant d'afficher la carte avec le moins de trasnfert cleint/serveur possible. Au déplacement du personnage, je récupère un nouveau "pattern" de carte, je le traite, et je réutilise les décors déjà demandés une fois... et je récupère ceux jamais demandés. Je fais pareil avec monstres, auteurs du chat, etc...
Ca a tjs bien fonctionné, jusqu'à un jour, où bouf, ca a déconné.
Depuis, impossible de récupérer ce fonctionnement.

J'ai donc fait ce code pour tester le comportement d'ajax. Ce que je remarque: dans la fonction ajax, les tableaux récupèrent bien les données, je peux meme les afficher. Par conter, une fois la boucle terminée, je me retrouve avec des trucs du genre 't_decor[ID][0] has no properties"

une boucle visant à afficher le contenu des tableaux fonctionne sans erreurs, mais m'affiche une taille=0=> donc aps de données.

Bref: où est mon erreur? la variable globale déclarée en début de script l'est-elle correctement? (j'ai l'impression qu'elle se vide une fois la fonction finie)
Y a-t-il une subtilité avec les fonctions ajax?
bref: need help!!!!!
une semaine que je butte sur ca Sad

PS:FireBug me donne bien un contenu aux variables t_decor(_2) (je vois les infos des décors demandés)


RE: Ajax et variables JS globales - Ruz - 27-09-2008

je viens de mettre ca sur serveur... prenez le compte test, et aller ici:
http://www.supraonline.be/Jeu/test_comportement.php

a noter qu'il me sort une exception JS undefined... suis bien avancé (EDIT: ok, mauvais fichier uploadé, c'est corrigé)


RE: Ajax et variables JS globales - arcanis - 27-09-2008

Intéressant, mais ...
Quelle est la fonction qui plante ? Et quel est le nom de la variable ?


RE: Ajax et variables JS globales - Ruz - 27-09-2008

aucune fonction ne plante de base, l'execution ici est complète sans erreurs.
par contre, une fois l'appel de load_decor(...) fini, je n'ai plus rien dans les deux tableaux qui m'intéressent: t_decor et t_decor_2

Question: Pourquoi ces tableaux sont-ils vide? (dans le sens, je ne peux accéder à aucune donnée, et leur longueur est annoncée = 0)


RE: Ajax et variables JS globales - Ruz - 27-09-2008

euh... attends, je vérifie!

... Bon... perso en ville, condition refusée... je l'ai sorti de la ville ^^
c'est bon maintenant.
Il semblerait que la variable soit bien là...
C'est l'accès à ses données qui pose problème, en fait, j'ai l'impression...

ma fonction show_decor(), en gros


RE: Ajax et variables JS globales - Ruz - 27-09-2008

tu t'es connecté avec le compte test, et tu as activé un perso avant d'aller sur la page?
bon, la variable existe donc bien... c'est moi qui n'arrive pas à y accéder...
par contre, j'ai trouvé un script de debuggage qui y accède, et m'affiche son contenu... (bouton rajouté : Debug t_decor)

Code PHP :
<?php 
function show_decor()
{
var
suivi='<u>Données en t_decor (hors fonction):</u>';
suivi+='<br />Taille : '+t_decor.length;
for
each(a in t_decor){suivi +='<br />t_decor['+a+'][0]='+a[0]+' --- t_decor['+a+'][1]='+t_decor[a][1];}
suivi +='<br /> Autre méthode :';
var
n=t_decor.length;
for(var
x=0; x<n;x++){suivi +='<br />t_decor['+x+'][0]='+t_decor[x][0]+' --- t_decor['+x+'][1]='+t_decor[x][1];}
SetDiv(suivi,'sortie');
}
Qu'est-ce qui n'est pas correct???

EDIT: ja rajopute la fonction de debug... si ca aide quelqu'un ^^
Code PHP :
<?php 
function debug(array)
{
if(
debug.caller!=debug) {
contenu = "DEBUT ARRAY \n";
}
var
indexParent = debug.arguments.length==2?debug.arguments[1]:"";
for(var
x=0;x<array.length;x++)
{
if(
IsArray(array[x])){debug(array[x],(indexParent+"["+x+"]"));}
else{
contenu += indexParent.replace(/./g,'.') + 'array' + indexParent + '[' + x + '] = ' + array[x] + "\n";}

if (!
indexParent) {
contenu += "FIN ARRAY \n";
alert(contenu);
}
}
}

function
IsArray(obj)
{
if (
obj.constructor.toString().indexOf("Array") == -1) return false;
else return
true;
}



RE: Ajax et variables JS globales - Ruz - 27-09-2008

initialiser, oui...
mais a tester, je préfère tester en condition la plus proche possible du cas final...

d'autre part, tu as tout le code nécessaire dans le premier message...
mais bon, vais tenter de te synthétiser le principal dans une page plus simple...


RE: Ajax et variables JS globales - Ruz - 27-09-2008

http://www.supraonline.be/Jeu/test_tres_simplifie.php

plus simple, ca va plus (meme la fonction de debug va meme plus)

a noter que si j'initialise le tableau, ca passe...
Donc, soit c'est ma fonction qui récupère les données de t_decor qui foire (qui est exactement la meme que dans la fonction), soit je ne rajoute pas les données correctement dans load_decor()

EDIT: au chargement, y a une requete qui se fait pour charger 3 décors


RE: Ajax et variables JS globales - Ruz - 27-09-2008

effectivement, si je rappelle ma fonction plus tard, ca passe...
merci ^^

Bon, comment puis-je bloquer la suite tant que l'appel ajax n'est pas fini?

si je passe en synchrone, ca marche pas... j'ai bien ma réponse, mais rien derrière pour remplir le tableau...
une solution à me suggérer?


RE: Ajax et variables JS globales - Ruz - 27-09-2008

hum... oui...

la fonction d'affichage doit se mettre en route quand j'ai 3 appels ajax distincts qui sont terminés (décors, monstres, actions possibles)

donc, dans mon cas, je dois lancer l'affichage si les 3 sont entièrement terminées...
mettre un switch à 1 quand une est finie... et je dois avoir 3 switchs à 1 pour autoriser le script d'affichage...

reste à faire patienter l'autre fonction pendant ce temps... hum... vais tester un truc du genre, voir ce que ca donne...
Yop!
avec un petit setTimeOut, ca aide déjà pas mal...

merci encore ^^