Bonjour, me voila face à un nouveau problème.

Ce que je veux

J'ai un espace de connexion en AJAX/PHP/HTML.

  • Quand je me connecte avec mes identifiants "admin" il me dit que je suis bien connecté, et me créer une $_SESSION['admin_id'] et eventuellement me redirige vers une autre page.

  • Quand je me connecte avec mes identifiants "membre" il me dit que je suis bien connecté, et me créer une $_SESSION['membre_id'] et eventuellement me redirige vers une autre page.

Ce que j'obtiens

  • Quand je me connecte avec mes bons identifiants "admin" il me dit mon message d'erreur "L'e-mail ou le mot de passe est incorrecte", mais ne m'affiche pas mon message de success et ne me créer pas de $_SESSION['admin_id']

  • Quand je me connecte avec mes bons identifiants "membre" il me dit mon message d'erreur "L'e-mail ou le mot de passe est incorrecte", mais m'affiche quand même le message de success, et me créer ma $_SESSION['membre_id']

  • Si je met juste la partie du code pour le SESSION membre id ou le SESSION admin id , alors là ça marche....

Je vais vous poster mon code PHP et AJAX, mais je pense que ça vient de l'identation de mes IF dans mon PHP, sauriez vous me dire ou svp ? je suis désesperé... Cordialement.

AJAX & PHP :

$(document).ready(function () {

    $(".connexion").submit(function () { // quand je clique sur le bouton ENVOYER je creer une variable

        var email = $("#email2").val(); // je creer un variable et je récupere sa valeur
        var pass = $("#pass2").val();

        $.ajax({

            type: 'POST',
            url: 'connexion-traitement.php',
            data: {email:email, pass:pass},
            success:function (donnees) {

                $('.return').html(donnees).slideDown();

                if(donnees == "success") {
                    location.reload();
                    $('#email2').val(email);
                    $('#pass2').val(pass);
                }
            }
        });
        return false;
    });
});
<?php
session_start();
include 'db/database.php';

    $email = htmlspecialchars($_POST['email']);
    $pass = sha1($_POST['pass']);

if(!empty($_POST['email']) || !empty($_POST['email']) != filter_var($email, FILTER_VALIDATE_EMAIL) AND !empty($_POST['pass'])) {

        $reqconnexion = $db->prepare('SELECT * FROM connexion WHERE email = ? AND pass = ? AND statut = "membre"');
        $reqconnexion->execute(array($email, $pass));
        $membreexist = $reqconnexion->rowCount();
        if($membreexist > 0) {
            $membreinfo = $reqconnexion->fetch();
            $_SESSION['membre_id'] = $membreinfo->id;
            $_SESSION['identifiant'] = $membreinfo->identifiant;
            $_SESSION['email'] = $membreinfo->email;
            $_SESSION['statut'] = $membreinfo->statut;
            echo "success";

            $reqconnexionadmin = $db->prepare('SELECT * FROM connexion WHERE email = ? AND pass = ? AND statut = "admin"');
            $reqconnexionadmin->execute(array($email, $pass));
            $adminexist = $reqconnexionadmin->rowCount();
            if($adminexist > 0) {
                $admininfo = $reqconnexionadmin->fetch();
                $_SESSION['admin_id'] = $admininfo->id;
                $_SESSION['identifiant'] = $admininfo->identifiant;
                $_SESSION['email'] = $admininfo->email;
                $_SESSION['statut'] = $admininfo->statut;
                echo "success";
            } else {
                echo "<div class='error'>L'e-mail ou le mot de passe est incorrecte</div>"; 
            }
        } else {
            echo "<div class='error'>L'e-mail ou le mot de passe est incorrecte</div>"; 
        }
} else {
    echo "<div class='error'>Tous les champs doivent être remplis</div>";
}

?>

21 réponses


Psylozoff
Réponse acceptée

Je pense que tu gagnerais à faire un peu d'algo et lire des ouvrages concernant le langage SQL et le langage PHP :-s
En fait, là t'as juste à récupérer le "statut" pour le couple "mail/pass"...

<?php
$req = $db->prepare("select statut from connexion where email=? and pass=?");
$req->execute(array($email, $pass));

if (!$req->rowCount()) //pas de ligne, donc couple "mail/pass" inexistant
else if ($req->fetch()->statut === "admin") //on a trouvé un admin
else //on a trouvé un membre...

il y a un blème dans ton test
empty renvoie un booléen
filter_var renvoie la variable épurée
toi tu compares les deux

if(  !empty($_POST['email'])  &&  filter_var($email, FILTER_VALIDATE_EMAIL) !== false AND !empty($_POST['pass'])) {

tu peux aussi utiliser filter_input( INPUT_POST, 'email', FILTER_VALIDATE_EMAIL)
qui renvoie false si c'est pas un email, null si 'email' n'existe pas et sinon le contenu de $_POST['email']

Bonjour merci de ta réponse, j'ai changé le if, mais le problème est toujours exactement le même ... :-/

Il y a un truc que je ne comprend pas
un user n'a qu'un seul statut , 'membre' ou 'admin'
si tu passes le test statut = 'membre' alors le test admin sera toujours faux ?

tu devrais plutot faire en sorte que ta requete ne filtre pas le statut
ensuite si ton fetch renvoie false, c'est que l'email et mdp sont faux (pas de ligne retournée)
sinon tu regardes le statut et tu traites en conséquence

Non mais le truc c'est que le problème ne vient pas de ce que je cherche ou non dans ma requète je pense, car ça marche niquel si je passe juste la recherche du compte membre comme ceci

if(  !empty($_POST['email'])  &&  filter_var($email, FILTER_VALIDATE_EMAIL) !== false AND !empty($_POST['pass'])) {
        $reqconnexion = $db->prepare('SELECT * FROM connexion WHERE email = ? AND pass = ? AND statut = "membre"');
        $reqconnexion->execute(array($email, $pass));
        $membreexist = $reqconnexion->rowCount();
        var_dump($membreexist);
        if($membreexist > 0) {
            echo "success";
            $membreinfo = $reqconnexion->fetch();
            $_SESSION['membre_id'] = $membreinfo->id;
            $_SESSION['identifiant'] = $membreinfo->identifiant;
            $_SESSION['email'] = $membreinfo->email;
            $_SESSION['statut'] = $membreinfo->statut;
        } else {
            echo "<div class='error'>L'e-mail ou le mot de passe est incorrecte</div>"; 
        }
} else {
    echo "<div class='error'>Tous les champs doivent être remplis</div>";
}

Par contre si je rajoute un if($adminexiste) avec le reste du code, et bien à partir de là ça ne marche plus..

Hello,

Je ne comprend pas bien l'organisation de ton code... pourquoi tu fait 2 requêtes SQL alors qu'une seule suffirait...

Au niveau de la première requête, plutôt que de faire "AND statut = 'membre'" fait plutôt "AND statut IN ('membre','admin')", avec ceci ta première requête devrait fonctionner aussi bien pour les membres que pour les admins.

Bonjour ,
merci de ta reponse
finalement jai trouvé entre temps comment faire après de multiples essais !
mais je vais quand même essayé ta méthode !  je ne savais pas qu'on pouvais faire comme ceci dans une seule requête !
merci !  je passe en resolu : )

Re bonjour Soundboy,
Tout dabord je te remet mon nouveau code qui marche.
Maintenant admettons que j'utilise ta méthode et que je retire une des deux requètes et que je remplace par ce que tu mas dis, dans le if($membreexist ==1) (par exemple) je remplace par quoi ? comment lui dire maintenant avec ta méthode que si il a le statut membre alors on continue, ou si il a le statut admin, alors on continue... je comprend pas trop ?

<?php
session_start();
include 'db/database.php';

    $email = htmlspecialchars($_POST['email']);
    $pass = sha1($_POST['pass']);

    if(!empty($_POST['email']) AND !empty($_POST['pass'])) {

        $req = $db->prepare("SELECT * FROM connexion WHERE email = ? AND pass = ? AND statut = 'membre'");
        $req->execute(array($email, $pass));
        $membreexist = $req->rowCount();
        $req2 = $db->prepare("SELECT * FROM connexion WHERE email = ? AND pass = ? AND statut = 'admin'");
        $req2->execute(array($email, $pass));
        $adminexist = $req2->rowCount();
        if($membreexist == 1) {
            echo "success";
            $membreinfo = $req->fetch();
            $_SESSION['membre_statut'] = $membreinfo->statut;
            $_SESSION['membre_id'] = $membreinfo->id;
            $_SESSION['membre_identifiant'] = $membreinfo->identifiant;
            $_SESSION['membre_email'] = $membreinfo->email;
            $_SESSION['flash']['success'] = "Vous êtes maintenant connecté.";

        } else if($adminexist == 1) {
            echo "success";
            $admininfo = $req2->fetch();
            $_SESSION['admin_statut'] = $admininfo->statut;
            $_SESSION['admin_id'] = $admininfo->id;
            $_SESSION['admin_identifiant'] = $admininfo->identifiant;
            $_SESSION['admin_email'] = $admininfo->email;
            $_SESSION['flash']['success'] = "Vous êtes maintenant connecté.";
        } else {
            echo "<div class='error'>E-mail ou mot de passe incorrecte</div>";
        }

    } else {
        echo "<div class='error'>Tous les champs sont obligatoires</div>";
    }

"comment lui dire maintenant avec ta méthode que si il a le statut membre alors on continue, ou si il a le statut admin, alors on continue... je comprend pas trop ?"
Ben tu fait un traitement en fonction de la valeur de "statut"

+1 Psylozoff, c'est pas mal non plus :-) !!

Psylozoff : olalala... en effet mais c'est carrement plus court et plus compréhensible .... je me coucherai moins bête ce soir merci beaucoup ça marche niquel !

code final:

$email = htmlspecialchars($_POST['email']);
$pass = sha1($_POST['pass']);

$req = $db->prepare("SELECT statut FROM connexion WHERE email=? AND pass=?");
$req->execute(array($email, $pass));

if(!empty($_POST['email']) AND !empty($_POST['pass'])) {

    if (!$req->rowCount()) { //pas de ligne, donc couple "mail/pass" inexistant
        echo "<div class='error'>E-mail ou mot de passe incorrecte</div>";
    }
    else if ($req->fetch()->statut === "admin") {
        echo "<div class='success'>Tu es maintenant admin</div>";
    } //on a trouvé un admin
    else {
        echo "<div class='success'>Tu es maintenant membre</div>";
    } //on a trouvé un membre...

} else {
        echo "<div class='error'>Tous les champs sont obligatoires</div>";
}

Mais du coup je me pose une question, ensuite pour le ELSEIF et le ELSE, donc si il est admin, ou si il est membre, je dois refaire une requète pour les deux pour pouvoir créer une session non ?

Genre là dans le ELSEIF et le ELSE, j'ai fais:

    else if ($req->fetch()->statut === "admin") {
            echo "success";
            $admin = $db->prepare("SELECT id FROM connexion WHERE email=? AND pass=?");
            $admin->execute(array($email, $pass));
            $admininfo = $admin->fetch();
            $_SESSION['admin_statut'] = $admininfo->id;
    } //on a trouvé un admin
    else {
        echo "success";
        $membre = $db->prepare("SELECT id FROM connexion WHERE email=? AND pass=?");
        $membre->execute(array($email, $pass));
        $membreinfo = $membre->fetch();
        $_SESSION['membre_statut'] = $membreinfo->id;
    } //on a trouvé un membre...

Dans mon exemple, j'ai fait au plus court, à l'essentiel! C'est justement pour ça que tu devrais potasser des bouquins sur le sujet ;-) Pour pouvoir adapter à tes besoins les solutions qu'on te donne :-p
Récupère tout ce dont tu as besoin dans la première requête... En spécifiant les champs ou en utilisant " * ", comme tu le faisais déja!
Si un bout de code significatif se retrouve à l'indetique à deux endroits différents, c'est que tu fais de la merde :-D
Il faut tâcher d'externaliser les traitements redondants dans des fonctions! Comme tu stipules juste le nom de ta fonction et les éventuels paramètres et tu allèges ton code qui s'en trouve plus lisible et maintenable!

Ah mais si tu as des références a me conseiller sur le sujet je veux bien... ! je demande que ça :)

Y'a beaucoup de lecture sur internet, des tutos en pagaille... On a pas forcément le temps de te servir de profs ;-)
En école d'informatique, la première chose que nous apprennent nos formateurs c'est : "Débrouille-toi! Apprends à apprendre tout seul, à trouver les infos par toi-même!" Avoir un prof c'est bien! Mais être son propre prof, c'est mieux :-D

Ah oui d'accord ;)
J'ai commencé le html/css il y a 1 an, puis PHP/SQL il y a 5 mois, avant ça aucune base rien, j'ai appris sur le tas, je ne connais forcement pas tout, mais j'arrive quand même pas mal à me débrouiller après de multiples essais, et à force de regarder des tutos partout, j'ai appris qu'il n'y a pas toujours qu'une solution pour une même chose... j'en ai bien vu la preuve pour cette chose... d'ailleur je me perd des fois et je ne sais pas quelle solution utiliser... ce que j'avais fait était bon au final pour cette histoire de recherche ADMIN/membre, ça marchais aussi, mais c'est sur que esthetiquement je préfère ta solution, et du coup j'imagine que c'est peut être moins lourd pour le site au final... je ne sais pas trop. ce qu'il me manque je pense, c'est comment faire pour que mon code général soit mieux optimisé, mais ça faudrait que je me penche sur la question, je ne sais pas si il y a des tutos sur ça ;)

Que veux-tu dire par "optimisé"?
En gros, dans la programmation il y a des règles de base! Par exemple, on ne réécrit jamais deux fois la même chose! On factorise autant que possible... Si deux bouts de code ont des différences mineures on essaye d'en faire une fonction qui prend en paramètre les parties variables!
Tu devrais étudier l'algorithmique ;-) C'est un excellent moyen de formater ton cerveau afin qu'il appréhende mieux les logiques qui sous-tendent l'éxecution binaire des processus informatiques :-p
http://pise.info/algo/index.htm

@Psylozoff +1 :D
Je plussoie :D
D'ailleurs, quand on regarde le code, y a intéret à suivre tes conseils :D

@plus
Pierre

Oui cest ca la refactorisation... javais déjà vu un tuto sur Grafikart a propos de ca... faudra que je me repenche la dessus ! mais du coup par rapport a ca , jai limpression que la refactorisation fera qu'il y aura moins de code mais plus de fichiers... je me trompe ? et si oui, il vaut mieux qu'il y ai plus de fichier plutot que de code ?  cest assez flou faudra que jaille voir le tuto ...

Pierrot :  oui oui je suis "debutant" jimagine bien que cest loin d'être parfait, je suis justement ici pour demander conseil......

Et ne néglige pas l'algo ;-) Mon lien te mènera vers le meilleur tuto que je connaisse actuellement...

Y'a pas de (re)factorisation, en fait ^^' Car, avant de coder on écrit sur du papier ou on dessine ce que l'on souhaite faire et on le code directement factorisé...
Moins il y a de code mieux c'est! Et pas besoin de faire des milliers de fichiers... Un fichier par module suffit! En gros, un fichier joue un rôle...
Y'a des langages/framework où un rôle correspond à un ensemble de fichiers réunis dans un "package" mais en php, un fichier par rôle, à moins d'avoir des fichiers de 30 kilomètres! Mais dans ces cas là c'est probablement que les rôles ont mal été définis...
Tu veux un exemple?

<?php
session_start();
include 'db/database.php';

//pourquoi instancier des variables si leur source n'est pas conforme?
if(empty($_POST['email']) or empty($_POST['pass'])) echo "<div class='error'>Tous les champs sont obligatoires</div>";
else {

    $email = htmlspecialchars($_POST['email']);
    $pass = sha1($_POST['pass']);

    $req = $db->prepare("select * from connexion where email=? and pass=?");
    $req->execute(array($email, $pass));

    if ($req->rowCount()) setSession($req->fetch());
    else echo "<div class='error'>E-mail ou mot de passe incorrecte</div>";
}

function setSession($memberInfo) {

    //On met true ou false dans isAdmin
    $_SESSION['isAdmin'] = $memberInfo->statut === "admin";
    $_SESSION['memberId'] = $memberInfo->id;
    $_SESSION['memberName'] = $memberInfo->identifiant;
    $_SESSION['memberMail'] = $memberInfo->email;
}   

Tu m'en voudras pas, j'ai changer les noms de tes variables de session ;-p On utilise l'anglais, en général, par convention...

Bonjour Psylozoff !
Oui biensur je vais aller lire tout ça , ça à l'air vraiment intéressant !
Bon j'ai essayé le code en factorisant, et ça à l'air de marcher niquel ! :)
Encore une petite question par rapport à cette nouvelle méthode de faire du coup, ou est ce que je met mon message de success ? , et par hasard, par rapport à mon AJAX qui est tout en haut du sujet, saurez tu pourquoi mon location.reload(); ne marche ? bon là c'est normal car il n'y a plus l'echo "success" dans mon PHP, mais déjà avant que je fasse la factorisation, il mettais bien mon echo success après validation du formulaire de connexion, mais ne me redige pas, et biensur que je ne peux pas utiliser mon header('location')....

Trouvé ! fallait juste rajouter

    if (!$req->rowCount());
    else echo "success";

:)
du coup le location.reload marche maintenant ! :)