Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Membre actif Avatar de Zebulon777
    Homme Profil pro
    Informaticien
    Inscrit en
    février 2005
    Messages
    1 135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : février 2005
    Messages : 1 135
    Points : 234
    Points
    234

    Par défaut Récupérer une valeur à partir d'une requête SQL

    Bonjour à tous,

    J'ai un problème tout bête que je n'arrive pas à résoudre depuis une demi-journée.

    Je fais une requête SQL qui me renvoie une seule valeur que je voudrai pouvoir utiliser dans le reste du script.

    Le petit PHP :
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    <?php
    	header('Content-Type: application/json; charset=UTF-8');
     
    	 $svname = "...";
    	 $usname = "...";
    	 $passwd = "...";
    	 $dbname = "...";
     
    	$dbconn = mysqli_connect($svname, $usname, $passwd, $dbname)
    		or die("Connexion impossible : " . mysqli_connect_error());
     
    	$query = "SELECT min(year(ST_DATE_MOUV)) FROM stattot ORDER BY ST_DATE_MOUV";
    	$result = mysqli_query($dbconn, $query)
    		or die("Échec de la requête : " . mysqli_error($dbconn));
    	$AnneeStattot = mysqli_fetch_all($result);
    	mysqli_free_result($result);
     
    	echo json_encode(array($AnneeStattot));
     
    	mysqli_close($dbconn);
    ?>

    Le code :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    $(document).ready(function () {
    ...
    ...
    ...
    // récupération de la plus vieille année disponible dans la table
    	var WAN = 0;
    	deferred = $.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php");
    	// Retour du serveur (traitement des données JSON)
    	deferred.done(function (jsonData) {
    		if (jsonData[0].length > 0) {
    			WAN = parseInt(jsonData[0][0]); // Ici WAN contient bien une année.
    		}
    	});
    			
    	var WAnneeDeb = WAN; // Ici il est à 0 !!!
    	i = WAnneeDeb;
    	while (i <= yy) {
    		$('#Liste_Annee').append($('<option>', {
    			value: i,
    			text: i
    		}));
    		i = i + 1;
    	};
    	var WAnnee = $('#Liste_Annee').val(yy); // Sélection de l'année en cours.
    	
    	//	dayInit=$('#Liste_Annee').val()+"0101"; // Indispensable pour la compatibilité
    	dayInit = $('#Liste_Annee').val();
    
    ...
    ...
    ...

    Je suis certain que ce doit être une grosse bêtise, mais j'ai trop la tête dans le guidon et je ne la trouve pas.

    Merci d'avance pour votre aide.
    Zeb'...

  2. #2
    Modératrice
    Avatar de Celira
    Femme Profil pro
    Développeuse PHP/Java
    Inscrit en
    avril 2007
    Messages
    8 004
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Développeuse PHP/Java
    Secteur : Industrie

    Informations forums :
    Inscription : avril 2007
    Messages : 8 004
    Points : 16 159
    Points
    16 159

    Par défaut

    C'est un problème de concept, plus qu'un problème de code (et davantage JS que PHP, donc ce message va déménager vers le forum JS )

    L'idée principale d'un appel AJAX, c'est qu'il est Asynchrone. Autrement dit, on lance l'appel et on continue le reste du script sans attendre la réponse. La réponse est traitée à part, lorsqu'elle arrive, par un code séparé.

    En l’occurrence, le code qui traite la réponse dans la fonction qui se trouve dans deferred.done(). Ce code, et donc l'affectation de WAN, sera effectué à l'arrivée de la réponse. Par contre le reste du code est exécuté tout de suite sans attendre la réponse.
    En résumé :
    1. tu lances l'appel,
    2. tu utilises WAN,
    3. la réponse arrive,
    4. tu affectes WAN

    Il faut donc que tu déplaces le code qui utilise WAN à l'intérieur de la fonction de traitement de la réponse.
    Modératrice PHP
    Aucun navigateur ne propose d'extension boule-de-cristal : postez votre code et vos messages d'erreurs. (Rappel : "ça ne marche pas" n'est pas un message d'erreur)
    Cherchez un peu avant poser votre question : Cours et Tutoriels PHP - FAQ PHP - PDO une soupe et au lit !.

    Affichez votre code en couleurs : [CODE=php][/CODE] (bouton # de l'éditeur) et [C=php][/C]

  3. #3
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    13 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 13 661
    Points : 27 688
    Points
    27 688

    Par défaut

    Bonjour,

    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	$query = "SELECT MIN(YEAR(ST_DATE_MOUV)) AS min_year FROM stattot ORDER BY ST_DATE_MOUV";
    	$result = mysqli_query($dbconn, $query)
    		or die("Échec de la requête : " . mysqli_error($dbconn));
    	$row = mysqli_fetch_assoc($result); // ou mysqli_stmt_fetch()
    	$AnneeStattot = $row['min_year'];

    N.B. Je connais mal mysqli_, mais il faudrait que tu regardes la doc de plus près : mysqli_ Interface procédurale et orientée objet

    ... et contrairement à Celira, je n'ai regardé QUE le code PHP...
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images

  4. #4
    Membre actif Avatar de Zebulon777
    Homme Profil pro
    Informaticien
    Inscrit en
    février 2005
    Messages
    1 135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : février 2005
    Messages : 1 135
    Points : 234
    Points
    234

    Par défaut

    Merci pour vos réponses et de vous pencher sur mon souci.

    @Celira : j'y avais bien pensé, mais le souci, c'est derrière plus rien ne fonctionne ! arf !
    Alors que si je n'utilise pas WAN, mais que j'affecte directement WAnneeDeb = 2014, là tout fonctionne !
    Je comprends bien ce que tu m'expliques, mais je suis paumé quand à trouver une solution, sans tout casser.
    Il n'y aurait pas moyen de passer WAN pour que ce soit utilisable dans la suite du code ?


    @jreaux62 : merci, j'ai été voir, mais ça na solutionne pas mon problème ou alors je n'ai pas compris...
    Zeb'...

  5. #5
    Rédacteur/Modérateur
    Avatar de jreaux62
    Homme Profil pro
    Webdesigner
    Inscrit en
    août 2008
    Messages
    13 661
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Webdesigner
    Secteur : Arts - Culture

    Informations forums :
    Inscription : août 2008
    Messages : 13 661
    Points : 27 688
    Points
    27 688

    Par défaut

    Je n'avais regardé QUE le code PHP...
    Mon code est une façon plus "conventionnelle" de récupérer UNE SEULE valeur.
    Conserve le tien (sinon, il y aurait d'autres modif. à faire)

    ... mais le souci est en JavaScript (comme l'a bien vu Celira) :

    Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	var WAN = 0;
    	deferred = $.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php");
    ...
    	deferred.done(function (jsonData) {
    ...
    			WAN = parseInt(jsonData[0][0]);
    ...
    	});
     
    	var WAnneeDeb = WAN;
    1- $.get, comme tout appel Ajax, est ASYNCHRONE.

    2- Quand tu affectes var WAnneeDeb = WAN;, WAN = 0 car la réponse de $.get n'est pas encore arrivée.


    La solution est effectivement de REVOIR la logique de ton code.
    "Si tu suis le chemin qui s'appelle « plus tard », tu arriveras à la place qui s'appelle « jamais »."
    François Camille Prévot (1910-1996), instituteur puis Directeur d'école et... mon grand-père.
    "Pose ta question, tu seras idiot une seconde. Ne la pose pas, tu seras idiot toute ta vie."
    Albert Einstein (1879-1955).
    Mes tutos DVP
    Gestion-Affichage de Nouvelles
    Affichage en tableau HTML
    Fonctions de redimensionnement d'images

  6. #6
    Membre actif Avatar de Zebulon777
    Homme Profil pro
    Informaticien
    Inscrit en
    février 2005
    Messages
    1 135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : février 2005
    Messages : 1 135
    Points : 234
    Points
    234

    Par défaut

    Ok, je pense avoir compris.

    Ca va être une question bête, je le sens : Il n'y a pas un moyen pour passer en synchrone le temps de récupérer la valeur ?

    Mais sinon, si j'ai bien compris, il faut que je fasse rentrer tout mon code DANS la fonction deffered.done ?
    Zeb'...

  7. #7
    Membre chevronné
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    mars 2005
    Messages
    1 227
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : mars 2005
    Messages : 1 227
    Points : 2 002
    Points
    2 002

    Par défaut

    C'est pas forcément une bonne idée pour l'expérience utilisateur
    Mais si tu tiens vraiment à rendre le processus synchrone.


    Code jQuery : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var WAN = 0;
    $.ajaxSetup({ async: false });
    try {
        $.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php")
                .done(function (jsonData) {
                          WAN = parseInt(jsonData[0][0]);
                });
    }
    finally {
        $.ajaxSetup({ async: true });
    }

  8. #8
    Membre actif Avatar de Zebulon777
    Homme Profil pro
    Informaticien
    Inscrit en
    février 2005
    Messages
    1 135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : février 2005
    Messages : 1 135
    Points : 234
    Points
    234

    Par défaut

    Super, ça fonctionne impec.
    Pour que ça serve au plus grand nombre, voici ce que j'ai fait :
    Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    $(document).ready(function () {
     
    	var day = new Date();
    	day.setDate(day.getDate() - 1); // On sélectionne le jour précédent
    	var mm = ((day.getMonth() + 1) < 10) ? '0' + (day.getMonth() + 1) : (day.getMonth() + 1);
    	var dd = (day.getDate() < 10) ? '0' + day.getDate() : day.getDate();
    	var yy = day.getFullYear();
    	var dayInit = yy + mm + dd;
     
    	var WAnnee = $('#Liste_Annee').val(yy); // Sélection de l'année en cours.
     
    // récupération de la plus vieille année disponible dans la table
    	var WAN = 0;
    //	deferred = $.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php");
     
    // Permet de passer en synchrone pour récupérer l'année la plus petite.
    	$.ajaxSetup({ async: false });
    	try {
    		$.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php")
    				.done(function (jsonData) {
    						  WAN = parseInt(jsonData[0][0]);
    				});
    	}
    	finally {
    		$.ajaxSetup({ async: true });
    	}
    // FIN SYNCHRONE
     
    	var WAnneeDeb = WAN;
    	i = WAnneeDeb;
    	while (i <= yy) {
    		$('#Liste_Annee').append($('<option>', {
    			value: i,
    			text: i
    		}));
    		i = i + 1;
    	};
    	var WAnnee = $('#Liste_Annee').val(yy); // Sélection de l'année en cours.
     
    console.log("WAnnee2="+WAnnee);	
     
    	//	dayInit=$('#Liste_Annee').val()+"0101"; // Indispensable pour la compatibilité
    	dayInit = $('#Liste_Annee').val();

    Par contre, je veux bien de plus amples explications pour ce qui concerne l'expérience utilisateur ?
    Zeb'...

  9. #9
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    janvier 2011
    Messages
    13 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : janvier 2011
    Messages : 13 068
    Points : 31 408
    Points
    31 408

    Par défaut

    Bonjour,
    tu as le chic pour choisir la meilleur solution qui est la pire

    Structure ton code cela t'éviteras bien des problèmes de lisibilité, par exemple minimum
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function getData() {
      $.getJSON("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php", function(jsonData) {
        // appel de la fonction gérant le graphe
        afficherGraphe(jsonData);
      });
    }
     
    function afficherGraphe(data) {
      // le code de ta fonction
    }

  10. #10
    Membre actif Avatar de Zebulon777
    Homme Profil pro
    Informaticien
    Inscrit en
    février 2005
    Messages
    1 135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : février 2005
    Messages : 1 135
    Points : 234
    Points
    234

    Par défaut

    Ha revoila mon non fumeur préféré

    Oui, tu as raison, mais je vais au plus facile, c'est vrai, car je manque de temps.

    Ta solution correspond bien à ce que j'avais compris (je crois), il faut que j'imbrique les fonctions concernées, ce que je mettrai en place dés que possible.

    En tout cas, c'est toujours un plaisir d'apprendre comme ça, grâce à vous tous.
    Zeb'...

  11. #11
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    janvier 2011
    Messages
    13 068
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : janvier 2011
    Messages : 13 068
    Points : 31 408
    Points
    31 408

    Par défaut

    ..., mais je vais au plus facile, c'est vrai, car je manque de temps.
    Permet moi d'en douter

  12. #12
    Membre actif Avatar de Zebulon777
    Homme Profil pro
    Informaticien
    Inscrit en
    février 2005
    Messages
    1 135
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Informaticien

    Informations forums :
    Inscription : février 2005
    Messages : 1 135
    Points : 234
    Points
    234

    Par défaut

    Rhooo, tu chipotes

    Mais si, si, l'astuce de Popo fonctionne nickel ou alors, je n'ai pas encore découvert et retours de bâton ?
    Zeb'...

  13. #13
    Expert confirmé Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    juin 2010
    Messages
    2 632
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : juin 2010
    Messages : 2 632
    Points : 5 509
    Points
    5 509

    Par défaut

    Citation Envoyé par Zebulon777 Voir le message
    l'astuce de Popo fonctionne nickel ou alors, je n'ai pas encore découvert et retours de bâton ?
    Comme popo l’a dit, ça diminue la qualité de l’expérience utilisateur. Si le client a une mauvaise connexion, le gel de l’interface sera perceptible, et dans le pire des cas, le navigateur est inutilisable pendant plusieurs secondes. Ça fait un effet très désagréable.

    On pourrait se dire qu’après tout, c’est pas si grave, mais il y a pire :
    • Les requêtes synchrones sont dépréciées et émettent des avertissements dans la console ;
    • Certaines des nouvelles fonctionnalités ajax ne supportent pas le mode synchrone, par exemple la propriété responseType.


    Autrement dit, l’ajax synchrone n’est pas future-proof. Tu as peut-être l’impression de gagner du temps aujourd’hui, mais pour toi ou la personne qui devra maintenir le code, c’est du travail en plus, donc de la dette technique.

    Avec la syntaxe ES2017, tu peux utiliser l’instruction await pour « linéariser » le traitement de la réponse ajax, comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    $(document).ready(async function () {
     
      ...
     
      // requête asynchrone
      // l’instruction await dit au script « d’attendre » l’arrivée de la réponse
      let jsonData = await $.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php");
      WAN = parseInt(jsonData[0][0]);
     
      ...
     
    });
    Quelques remarques sur ton code PHP :
    Attention à toujours déclarer l’encodage de connexion avec mysqli_set_charset pour éviter les mauvaises surprises.

    mysqli_fetch_all renvoie toujours un tableau de tableaux (chaque sous-tableau représentant une ligne de résultat). En l’occurence, tu ne veux qu’une seule ligne de résultat, donc tu peux utiliser mysql_fetch_assoc comme l’a indiqué jreaux62, ou même mysqli_fetch_row qui, dans le cas présent, est plus simple.

    Dans ta requête SQL, tu n’as pas besoin de faire ORDER BY car tu récupères toujours un seul résultat. Si tu es obsédé par l’optimisation, tu peux toujours mettre un ORDER BY NULL à la place, mais je ne crois pas que ça change grand chose.

    Tu passes un tableau à json_encode, ce qui te rajoute encore un niveau de tableaux. Ce dernier tableau est inutile, tu peux simplement le supprimer.
    En fait, tu peux carrément envoyer l’année « nue » sans la formater en json.

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    header('Content-Type: text/plain; charset=utf-8');
     
    $svname = '...';
    $usname = '...';
    $passwd = '...';
    $dbname = '...';
     
    $dbconn = mysqli_connect($svname, $usname, $passwd, $dbname)
        or die('Connexion impossible : ' . mysqli_connect_error());
     
    mysqli_set_charset($dbconn, 'utf8mb4');
     
    $query = 'SELECT min(year(ST_DATE_MOUV)) FROM stattot';
    $result = mysqli_query($dbconn, $query)
        or die('Échec de la requête : ' . mysqli_error($dbconn));
     
    $row = mysqli_fetch_row($result);
    mysqli_free_result($result);
    $AnneeStattot = $row[0];
     
    echo $AnneeStattot;
     
    mysqli_close($dbconn);

    ET côté client :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    let textData = await $.get("./scripts/PHP/TraficJournalier_PLTF_PlusVielleAnnee.php");
    WAN = parseInt(textData);

    Mais comme mysqli peut aussi envoyer des erreurs, tu dois gérer ce cas en vérifiant si la conversion en nombre a réussi :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if (Number.isNaN(WAN)) {
      // erreur mysqli
      alert(textData);
    }
    else {
      // on continue normalement le script
     
      ...
     
    }
    La FAQ JavaScript – Les cours JavaScript
    Un article du MDN n’a pas de version française ? Je peux peut-être le traduire, envoyez-moi un MP

    La touche F12 : l’outil indispensable à tout développeur JavaScript !

Discussions similaires

  1. Réponses: 19
    Dernier message: 19/03/2018, 10h05
  2. Récupérer une valeur à partir d'une liste select
    Par xymagic dans le forum PHP & MySQL
    Réponses: 11
    Dernier message: 15/11/2011, 12h22
  3. ecrire à partir d'une macro sous excel une valeur dans une base sql server
    Par Guena5635 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 17/04/2008, 09h53
  4. Réponses: 10
    Dernier message: 01/12/2006, 00h06
  5. Réponses: 3
    Dernier message: 22/01/2005, 23h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo