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

jQuery Discussion :

Inscription d'un champ dans une db MySql


Sujet :

jQuery

  1. #1
    Nouveau membre du Club
    Inscription d'un champ dans une db MySql
    Bonjour,

    Voilà le topo. J'ai un petit script qui récupère le nom de l'utilisateur (champ playerName) ainsi que son score (scoreFinal). Quand on clique sur le bouton, il lance la fonction savePlayer() qui créé la requête Ajax vers le fichier playerSave.php, qui l'exécute.
    Je ne comprends pas là où ça bugue, qu'est-ce qui m'échappe ?

    code HTML :
    Code html :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    <div id='saveResult'>
    <input type='text' id='playerName' placeholder='Votre pseudo' pattern='[a-zA-Z0-9]+' maxlength='12'>
    <button onclick='savePlayer()'>OK</button>
    <div id='saveResultMsg'></div></div>


    script Javascript :
    Code :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
    function savePlayer() {
        var playerName = document.getElementById('playerName').value;
        var scoreFinal = Number(document.getElementById('scoreFinal').innerHTML);
        var data = {playerName: playerName, score: scoreFinal}; 
        $.ajax({ 
            type: 'POST',
            url: 'includes/playerSave.php', 
            data: data, 
            dataType: 'json',
            timeout: 3000,
            success: function(data) {
              $('#saveResultMsg').html('<div class="alert-success" style="font-size: small;">Merci</div>');                       
            },
            error: function() {
                $('#saveResultMsg').html('<div class="alert-danger" style="font-size: small;">Erreur</div>');
            }
        });
    }


    playerSave.php :
    Code php :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <?php
    include('db.class.php');
    $bdd = new db();
    if($_POST) {
    	$playerName = $_POST['playerName'];
    	$scoreFinal = $_POST['scoreFinal'];
    	$query = $bdd->execute('INSERT INTO OC_top (score, player) VALUES ('.$scoreFinal.', CURDATE(), "'.$playerName.'")'); 
    }
    ?>


    Pour info :
    - Les variables playerName et scoreFinal sont correctement récupérées au niveau de la fonction savePlayer()
    - La fonction s'exécute bien, mais affiche le message d'erreur ("Erreur").
    - Le chemin vers les 2 fichiers .php appelés sont les bons.
    - Le nom de la table OC_top et des champs score et player sont les bons.
    - Le fichier db.class renvoie à mes fonctions PDO dont celle-ci, qui fonctionne très bien ailleurs sur ma page.
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function execute($query) {
    		if (!$response = $this->conn->exec($query)) {
    			echo 'PDO::errorInfo():';
    		   echo '<br />';
    		   echo 'error SQL: '.$query;
    		   die();
    		}
    		return $response;
    	}

  2. #2
    Membre émérite
    Bonjour,

    D'après ce que je vois, ajax attend un retour de type "JSON" vu que tu as utilisé la propriété dataType:"json" dans les options. il faut donc que ton fichier playerSave.php renvoi quelque chose convertit en json.

    Et ce n'est pas tout, car tes requêtes ne sont pas sécurisées, il ne faut jamais passer les variables en dur dans les requêtes, solution => les requêtes préparées :
    Code php :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    $query ='INSERT INTO OC_top (score, player) VALUES (?, CURDATE(), ?)';
    $stmt = $bdd->prepare($query);
    $stmt->execute([$scoreFinal,$playerName]);
    $nbrInsert=$stmt->rowCount();
    if($nbrInsert>0){
         $retour["success"]="Insertion effectuée avec succès, nombre de ligne insérées :".$nbrInsert; 
    }else{
         $retour=['erreur']="Aucune insertion n'a été effectuée !";
    }
     
    echo json_encode($retour);


    Comme ça, tu peux exploiter la réponse php dans le success d'ajax comme suite :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    success:function(data){
       console.log("retour :",data);
       if(data.success){...}
       else if(data.erreur){...}
    }


    Pour le callback error, utilise responseText pour récupérer l'erreur :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    error:function(err){
       alert("Erreur ajax :", err.responseText);
    }

  3. #3
    Invité
    Invité(e)
    Bonjour,

    Je rajoute...

    1- un <button> est par défaut de type submit.
    Ici, il faut :
    Code HTML :Sélectionner tout -Visualiser dans une fenêtre à part
    <button type="button" onclick='savePlayer()'>OK</button>


    2- Tant qu'à utiliser jQuery, remplace :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    function savePlayer() {
        var playerName = document.getElementById('playerName').value;
        var scoreFinal = Number(document.getElementById('scoreFinal').innerHTML);

    par :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    function savePlayer() {
        var playerName = $('#playerName').val();
        var scoreFinal = Number($('#scoreFinal').html()); // ou mieux ici : .text()

  4. #4
    Nouveau membre du Club
    Merci ! En effet le code marche simplement en commentant la ligne
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    //dataType: 'json'
    , il s'agissait bien d'un problème de json.

    Maintenant je vais en effet me mettre à un tutoriel sur les requêtes préparées, avec lesquelles je ne suis pas du tout familier et qu'il faut que je connaisse...
    Une petite question sur ton code :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    $query ='INSERT INTO OC_top (score, player) VALUES (?, CURDATE(), ?)';
    $stmt = $bdd->prepare($query);
    $stmt->execute([$scoreFinal,$playerName]);

    on peut donc faire la commande execute en précisant seulement les 2 variables correspondant aux ?, dans l'ordre, et peu importe s'il y a entre elles d'autres champs modifés ? (ici CURDATE())
    PS : d'ailleurs j'avais oublié le champ date ici : OC_top (score, player) => OC_top (score, dateScore, player)

  5. #5
    Membre émérite
    Non, c'était un erreur de saisie, il faut ajouter la colonne de la date :
    Code php :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    $query="INSERT INTO OC_top (score,dateScore, player) VALUES (?, CURDATE(), ?)";


    Et l'ordre des "?" est important bien-sur.

  6. #6
    Nouveau membre du Club
    Ok dans la query il manquait la colonne, mais dans execute on ne précise que les variables ($stmt->execute([$scoreFinal,$playerName]) équivalents aux ?, on n'indique rien d'autre ? (ici par ex pour indiquer qu'il y a CURDATE() à insérer)

  7. #7
    Invité
    Invité(e)
    Bonjour,

    tu devrais LIRE la DOC...

  8. #8
    Nouveau membre du Club
    Bien sûr, j'ai même dit dans le post juste avant que c'est ce que j'allais faire. C'était juste une toute petite question avant de me lancer dans la doc, mais ok, ton commentaire est de bonne guerre

    Par contre, pour être sûr de bien comprendre l'intérêt des requêtes préparées dans mon cas précis, qu'est-ce qu'un utilisateur mal intentionné (ou juste maladroit) pourrait faire qui mettrait en cause l'intégrité de mon site/bdd ?

  9. #9
    Membre à l'essai
    Salut, tuto -> injection SQL

  10. #10
    Nouveau membre du Club
    Oui des tutos là-dessus j'en ai lu, mais ici je ne comprends toujours pas : il s'agit d'un champ input unique, en POST, avec une regexp qui contrôle (en PHP) qu'il ne doit s'agir que 15 caractères alphanumériques max. On peut tout de même y faire des injections sql ??

    Ce qui ne veut pas dire qu'il ne faut pas prendre la bonne habitude d'utiliser les requêtes préparées pour tout, hein, j'essaie juste de comprendre le vrai enjeu de sécurité dans ce cas précis.

  11. #11
    Invité
    Invité(e)
    Bonjour,

    Tu confonds "injection SQL" et "mauvaises données enregistrées".

    "injection SQL" : une requête correctement préparée suffit
    "mauvaises données enregistrées" : à toi de vérifier si ça correspond à ce que tu veux (validation email, regex,....)

    Puis, à l'affichage, on utilise htmlspecialchars().