Bonjour,

Je suis RSI, et dans le cadre de mon taf j'ai besoin de maintenir des vieux sites en php. Du coup je me suis lancé dans l'apprentissage du dev web.
Ayant de bonnes bases en HTML et CSS, je m'attaque au PHP. Ca fait quelques mois que je lis des tutos, regarde des vidéos, mais sans jamais m'y mettre.
Du coup, j'ai entendu parler de ce challenge et j'ai décidé de le relever.
Donc voici mes production

Jour [1/100]

J'ai voulu faire une jeu du juste prix. Pour travailler les conditions et boucles y a rien de mieux!

<?php
    /*
    Le juste prix: 
    On doit chercher un chiffre entre 1 et  100. 
    Si on est en dessous le résultat dit plus,
    Si on est au dessus le résultat dit moins.
    */
    $resultat = rand(1, 100);    
    $accord = strtolower(readline('Tu veux jouer avec moi au juste prix? (o / n)'));

        if($accord == 'o'){
            $proposition = readline('Veuillez saisir un nombre entre 1 et 100: ');
            while($accord == 'o'){
                if(is_numeric($proposition)){
                    if($proposition == $resultat){
                        echo "Bravo tu as trouvé. ";
                        $accord = strtolower(readline('Tu veux recommencer ? (o / n) '));
                        if($accord =='o'){
                            $resultat = rand(1, 100);
                            $proposition = readline('Veuillez saisir un nombre entre 1 et 100: ');
                        }
                        elseif($accord == 'n'){
                            echo "Merci d'avoir participer! A bientôt.";
                            break;
                        }
                        else{
                            echo "Je n'ai pas compris la commande! ";
                            $accord = strtolower(readline('Tu veux recommencer ? (o / n) '));
                        };
                    }
                    elseif($proposition > $resultat){
                        echo "Dommage c'est moins, retente ta chance. ";
                        $proposition = readline('Veuillez saisir un nombre entre 1 et 100: ');
                    }
                    else{
                        echo "Dommage c'est plus, retente ta chance. ";
                        $proposition = readline('Veuillez saisir un nombre entre 1 et 100: ');
                    };
                }
                else{
                    echo "Votre saisie est incorrecte. ";
                    $proposition = readline('Veuillez saisir un nombre entre 1 et 100:  ');
                };    
            };
        }
        elseif($accord == 'n'){
            echo "Dommage! On aurait pu s'ammuser.";
        }
        else{
            echo "Je n'ai pas compris la commande! ";
            $accord = strtolower(readline('Tu veux jouer avec moi au juste prix? (o / n)'));
        };    
?>

Ce que j'obtiens

https://scontent-cdt1-1.xx.fbcdn.net/v/t1.0-9/153465086_10158768037868267_894085705475973802_n.jpg?_nc_cat=110&ccb=3&_nc_sid=730e14&_nc_ohc=5b_vHT3b1jgAX_Ym8Af&_nc_ht=scontent-cdt1-1.xx&oh=ca98985ef6ddb1a9a1bbc756e7f7f3fe&oe=605B5312

Jour [2/100]

J'ai voulu faire une appli permettant à un prof de mettre des notes et remarque dans le dossier d'un élève!

<?php
    /*
    Note ton élève!
    Le but est qu'un professeur puisse noter un élèves et mettre des remarques, puisse récupérer des données (nom, note, moyenne, remarque)
    On travaillera les array, les boucles, les conditions et continue
    */
    $eleve = [
        'nom'=>'Saez',
        'prenom'=>'Damien',
        'classe'=>'T2',
        'notes'=>[13, 15, 8, 18, 11],
        'remarque'=>['Très bon élève', 'Bon devoir', 'C\'est un peu relâché.']
    ];
    $choix = readline("Bonjour, que souhaitez-vous faire? \n 
        1- Mettre une note \n
        2- Mettre une remarque \n
        3- Voir le nom de l'élève \n
        4- Voir les notes \n
        5- Voir la moyenne \n
        6- Voir les remarques \n
        q- Quitter le programme \n");
    while ($choix != 'q' OR $choix != 'Q'){  
        if ($choix === '1'){
            $note = (int)readline("Quelle note a eu $eleve[prenom] $eleve[nom]? ");
            if ($note <= '20' AND $note >='0'){
                $eleve['notes'][] = $note;
                $choixNote = strtolower(readline("Souhaitez-vous ajouter une nouvelle note? O - N \n"));
                if($choixNote === 'o'){
                    continue;
                }
                elseif ($choixNote === 'n') {
                    $choix = readline("Que souhaitez-vous faire? \n 
                            1- Mettre une note \n
                            2- Mettre une remarque \n
                            3- Voir le nom de l'élève \n
                            4- Voir les notes \n
                            5- Voir la moyenne \n
                            6- Voir les remarques \n
                            q- Quitter le programme \n");
                }
                else {
                    echo "Je n'ai pas compris votre choix. Souhaitez-vous ajouter une nouvelle note? O - N \n";
                };
            }
            else {
                echo "Note incorrecte. \n";
            };
        }
        elseif($choix === '2'){
            $remarque = readline("Quelle remarque souhaitez vous mettre à $eleve[prenom] $eleve[nom]?");
            $eleve['remarque'][] = $remarque;
            $choixRemarque = strtolower(readline("Souhaitez-vous ajouter une nouvelle note? O - N \n"));
            if($choixRemarque === 'o'){
                continue;
            }
            elseif ($choixRemarque === 'n') {
                $choix = readline("Que souhaitez-vous faire? \n 
                        1- Mettre une note \n
                        2- Mettre une remarque \n
                        3- Voir le nom de l'élève \n
                        4- Voir les notes \n
                        5- Voir la moyenne \n
                        6- Voir les remarques \n
                        q- Quitter le programme \n");
            }
            else {
                echo "Je n'ai pas compris votre choix. Souhaitez-vous ajouter une nouvelle note? O - N \n";
            };
        }
        elseif($choix === '3'){
            echo "Vous êtes sur le dossier de l'élève $eleve[prenom] $eleve[nom].\n";
            sleep (1);
            $choix = readline("Que souhaitez-vous faire? \n 
                        1- Mettre une note \n
                        2- Mettre une remarque \n
                        3- Voir le nom de l'élève \n
                        4- Voir les notes \n
                        5- Voir la moyenne \n
                        6- Voir les remarques \n
                        q- Quitter le programme \n");
        }
        elseif($choix === '4'){
            echo "Les notes de $eleve[prenom] $eleve[nom] sont: \n";
            foreach($eleve['notes'] as $listNote){
                echo "- $listNote \n";
            };
            $choix = readline("Que souhaitez-vous faire? \n 
                        1- Mettre une note \n
                        2- Mettre une remarque \n
                        3- Voir le nom de l'élève \n
                        4- Voir les notes \n
                        5- Voir la moyenne \n
                        6- Voir les remarques \n
                        q- Quitter le programme \n");
        }
        elseif($choix === '5'){
            $arraycount = count($eleve['notes']);
            $notesomme = array_sum($eleve['notes']);
            $moyenne = $notesomme / $arraycount;
            echo "L'élève $eleve[prenom] $eleve[nom] a $moyenne de moyenne.\n";
            $choix = readline("Que souhaitez-vous faire? \n 
                        1- Mettre une note \n
                        2- Mettre une remarque \n
                        3- Voir le nom de l'élève \n
                        4- Voir les notes \n
                        5- Voir la moyenne \n
                        6- Voir les remarques \n
                        q- Quitter le programme \n");
        }
        elseif($choix === '6'){
            echo "Voici les remarques concernant $eleve[prenom] $eleve[nom]: \n";
            foreach($eleve['remarque'] as $listRemarque){
                echo "- $listRemarque \n";
            };
            $choix = readline("Que souhaitez-vous faire? \n 
                        1- Mettre une note \n
                        2- Mettre une remarque \n
                        3- Voir le nom de l'élève \n
                        4- Voir les notes \n
                        5- Voir la moyenne \n
                        6- Voir les remarques \n
                        q- Quitter le programme \n");
        }
        elseif ($choix === 'q' OR $choix === 'Q') {
            break;
        }
        else {
            echo "Je n'ai pas compris votre choix \n";
            $choix = readline("Que souhaitez-vous faire? \n 
                        1- Mettre une note \n
                        2- Mettre une remarque \n
                        3- Voir le nom de l'élève \n
                        4- Voir les notes \n
                        5- Voir la moyenne \n
                        6- Voir les remarques \n
                        q- Quitter le programme \n");
        };
    };
?>

CE QUE J'OBTIENS

Ca fonctionne. C'est largement perfectible, mais je suis content du résultat

Jour [3/100]

J'ai voulu mettre en place un formulaire de login (avec vérification de l'existence dans la BDD) et de création de compte.

<?php
/*
Objectif créer un formulaire de connexion et de création de compte.
On travaille donc la connexion à la BDD, le SQL, la manipulation des $_POST
*/
/*
session_start();
*/
require ('bdd.php');
$reponse = $bdd->query('SELECT * FROM users');
$donnees = $reponse->fetch();
while ($donnees = $reponse->fetch()){
    echo 'Login: ' . $donnees['u_login'] . "<br/>";
    echo 'Password: ' . $donnees['u_password'] . "<br/>";
    echo "------------------ <br/>";
};

$reponse->closeCursor();

?>

<form action="login_post.php" method='post'>
    <p>
        <label for="login">identifiant</label>: <input type="text" name="login" placeholder="Identifiant" /><br/>
        <label for="password">Mot de passe</label>: <input type="text" name="password" placeholder="Mot de passe" /><br/>
        <input type="submit" value="Se connecter">
    </p>
</form>

<a href="creation.php">Créer un compte</a>

Le code de vérification

<?php

    require ('bdd.php');
/*
Compare $_post['login'] et ['password'] à la BDD users [u_login] et users [u_password]
Si c'est bon --> connected, sinon erreur --> login avec message d'erreur
*/
    $reponse = $bdd->query('SELECT * FROM users');
    while($donnees = $reponse->fetch()){
        if($_POST['login'] == $donnees['u_login'] AND $_POST['password'] == $donnes['u_password']){
            header ('Location: connected.php');
        }
        else{
            header ('Location: login.php');
        };
    };

    $reponse->closeCursor();
?>

CE QUE J'OBTIENS

Le formulaire de création fonctionne, mais le login n'arrive pas à vérifier la condition et me renvoie automatique sur login.php alors qu'il récupère correctement le $_POST et qu'il lit correctement la BDD. A creuser pour demain

35 réponses


Salut,

essai come ceci pour ton dernier cas:

    // Toujours utliser des requetes préparées lorsque tu reçois des infos d'un formulaire (injection SQL = piratage bdd)
  $findUser = $bdd->prepare("SELECT * FROM users WHERE login = ? AND password = ?";

  // On passe les parametres dans l'ordre des ? dans ta requête préparée
  $findUser->execute([$_POST['login'], $_POST['password']);
  // Ici on fait un fecth() car on attend qu'un seul résultat
  // fecth() = 1 resulat (pas de boucle)
  // fecthAll() = tous les résultats (boucle OK)
  $user = $findUser->fetch();
  $findUser->closeCursor();

    // Si la requete retroune un résultat alors c'est que le couple User vs Password à été trouvé
  if(!empty($user))
  {
      header ('Location: connected.php');
      // Toujours mettre un exit après une redirection
      exit;
  else{
      header ('Location: login.php');
      exit;
      };
  };

Je te rermercie pour ton aide. J'essaie de comprendre le lien entre le prepare, le execute et le fetch. J'ai testé ton code, il me balance une erreur sur le execute() où il attend 1 paramètre au lieu de deux et quand je mets un array en paramètre, j'ai une erreur sur le fetch ou il reçoit un booléen au lieu d'un objet.
Voici mon code:

$req = $bdd->prepare('SELECT * FROM users WHERE u_login = ? AND u_password = ?');
    $donnees = $req->execute(array($_POST['login'], $_POST['password']));
    $finduser = $donnees->fetch();
    $donnees->closeCursor();

    if(!empty($finduser)){
        header ('Location: connected.php');
    }
    else{
        echo "Vous n'êtes pas connecté";
        var_dump($_POST);
        echo $donnees['membre_valide'];   
    };

Alors,

Les requetes préparées sont là te protéger des injectiosn SQL.

Prepare permet d'analyser la requete et d'attendre des paramètres
execute => permet d'éxécuter la requete préparée en lui envoyant les paramètres à passer à la requete (retourne un boolean à la fin de l' éxécution)
fetch() => permet de retourner UN résultat dans un array unique contenant toutes les informations liée à la requete, dans ton cas tu n'attends qu'un seul résultat (1 ustilisateur)

fecthAll() => retourne un array avec un array pour toutes les valleurs retournées.

Essai avec ça et dis moi ce qu'il se passe stp.

  $req = $bdd->prepare('SELECT * FROM users WHERE u_login = :login AND u_password = :password');
  $donnees = $req->execute(array(':login' => $_POST['login'], ':password' => $_POST['password']));
  $finduser = $donnees->fetch(PDO::FETCH_OBJ);

  echo <pre>;
  var_dump(finduser);
  echo </pre>;
  die();

J'ai toujours la même erreur:

Uncaught Error: Call to a member function fetch() on bool

Ok, essayons autre chose.

Dans ton fichier bdd.php, juste apres le New PDO()

exemple $bdd = new PDO();
ajoute cette ligne afin d'avoir un détail des erreurs (à enlever lors du passage en prod)

$bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Toujours la même erreur sans aucun détail:

( ! ) Fatal error: Uncaught Error: Call to a member function fetch() on bool in E:\wamp64\www\login_post.php on line 10
( ! ) Error: Call to a member function fetch() on bool in E:\wamp64\www\login_post.php on line 10
Call Stack

Time Memory Function Location

1 0.0005 412040 {main}( ) ...\login_post.php:0

Je précise s'il le fallait que je suis sous WAMP / MariaDB(port:3307)

Il doit y avoir un problème avec ta requete SQL.
execute te renvoie un False donc Fecth() ne parche pas d'où l'érreur.

dans ta requete 'u_login' correspond bien au nom de la colonne dans ta base de données ?

Effectivement quand je regarde la doc sur le fetch ou le execute, j'ai beau tourné la chose dans tous les sens, j'obtiens toujours la même erreur. Avec bindValue ou sans, peu importe la méthode j'obtiens ce problème.
Et quand je regarde ma BDD j'ai bien la structure:

1   id Primaire int(11)         Non Aucun(e)        AUTO_INCREMENT  Modifier Modifier   Supprimer Supprimer 

Plus Plus
2 name varchar(255) utf8_general_ci Non Aucun(e) Modifier Modifier Supprimer Supprimer
Plus Plus
3 last_name varchar(255) utf8_general_ci Non Aucun(e) Modifier Modifier Supprimer Supprimer
Plus Plus
4 u_login varchar(45) utf8_general_ci Non Aucun(e) Modifier Modifier Supprimer Supprimer
Plus Plus
5 u_password varchar(255) utf8_general_ci Non Aucun(e) Modifier Modifier Supprimer Supprimer
Plus Plus
6 email

A savoir que j'ai modifié login en u_login et password en u_password pensant que le bug venait de ça. Mais apparemment, non. :-(

attend ton password est en clair ou il est haché dans ta base ( ex avec md5) ? au qu'elle cas il faut le spécifier dans la requête sql.

sinon essaie la requête directement dans phpmyadmin voir si elle fonctionne

il est en clair, j'en suis pas encore à la partie sécurisation. Quand j'execute la requête il me met une erreur de syntaxe. En mettant des quotes sur les marqueurs, la requête fonctionne.
Sauf que lorsque je mets les quote dans le code j'ai une Parse error:

( ! ) Parse error: syntax error, unexpected ':', expecting ')' in E:\wamp64\www\connexion_post.php on line 29

Après avoir fait un test avant le fetch, j'ai un retour qui est toujours à 1 que le LOGIN/MDP soit dans la BDD ou pas

Le retour "true" signifie que la requete s'exécute correctement

essai avec fetchAll() à la place de fecth() pour voir

Bon je pense que j'ai un bug. Ma requête retourne un 1, donc elle est bonne, et le fetch() comme le fetchAll() me retourne une erreur. Sur StackOverFlow ils disent que l'erreur vient du fait que la requête renvoie un false et donc un booléen. Je le ne sais pas si c'est le execute qui merde ou le fetch...Mais bon je passerai pas 1 milliard de temps dessus je dois avancer dans mon apprentissage...Je vais chercher une solution alternative ou bidouiller un truc.
Je te remercie pour l'aide et le temps accorder.

Je n'ai pas regardé plus que cela ton code du coup, et je vois que tu n'as pas envie de passé trop de temps.
Mais il me semble que t'es "==" sont fausse, essaie avec "===" soit 3 égales.

J'utilise "!=" ou "==="

Voilà pourquoi les différences https://www.php.net/manual/fr/language.operators.comparison.php

Merci pour le conseil Jessy Brs.
En changeant WHERE par VALUES, je n'ai plus l'erreur sur le fetch().
Mais j'ai une erreur sans explication.
Voici le nouveau code:

$req = $bdd->prepare('SELECT * FROM users VALUES (:p_login, :p_password)');
$donnees = $req->execute(array('p_login' => $_POST['login'], 'p_password' => $_POST['password']));
$finduser = $donnees->fetch();

echo "<pre>";
var_dump($finduser);
echo "</pre>";
die();

Voici l'erreur que j'obtiens: (la ligne 9 correspond à celle du execute)


( ! ) Fatal error: in E:\wamp64\www\login_post.php on line 9
( ! ) PDOException: in E:\wamp64\www\login_post.php on line 9
Call Stack
#   Time    Memory  Function    Location
1   0.0003  412040  {main}( )   ...\login_post.php:0
2   0.0010  460856  execute ( ) ...\login_post.php:9

Et en faisant un TRY CATCH, j'ai cette erreur:


Erreur: SQLSTATE[42000]: Syntax error or access violation: 1064 Erreur de syntaxe pr�s de 'VALUES ('toto', 'toto')' � la ligne 1

Le top serait de voir clairement l'erreur. pour cela l'ajouter de puis le serveur utilisé (wamp surement)

Sinon Value n'est utilisé que pour insérer ou modifier ta base de donnée.
Toi tu souhaites récupérer et vérifier pour te connecter.

Donc

$req = $this->getBdd()->prepare('SELECT * FROM users WHERE login= ?);
$req->execute(array(
$_POST['login']
));
$data = $req ->fetch(PDO::FETCH_ASSOC);

là je lui demande, sélectionne mon tous les champs, depuis ma table users, le login correspondant à $_POST['login']

Ensuite dans ton php classique tu fais une vérification classique

Si ($_POST['password'] != user.password) {
erreur mot de pass incorrect
}

// je me connecte.

Voilà un exemple

C'est là que ça coince, quand je fais un SELECT FROM WHERE, j'ai une erreur sur le fetch() alors même que la requête est valide et me renvoie 1 et non false.

Sur ce code j'ai un écran blanc:


$req = $bdd->prepare("SELECT * FROM users WHERE :u_login AND :u_password");
    $req->execute(array(':u_login' => $_POST['login'], ':u_password' => $_POST['password']));
    $finduser= $req->fetch();

    print_r ($finduser);

Bonsoir,
Je reprends juste sur l'erreur actuelle.
A mon avis, tu ne te connectes pas à la bonne BDD (par défaut le port est 3306 pour mysql) or toi tu es sur mariadb

new PDO ("mysql:host=localhost;port=3307;dbname.........", "","", array(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION));

Pour la suite, le mdp en clair dans la bdd, ce n'est pas bon

Là ta requete n'est pas correcte.

en gros tu demande:

        SELECT * FROM users WHERE admin AND admin;

Donc sans préciser les colonnes où vérifier les conditions

As-tu regardé que PDO soit actif dans WAMP ?

sinon essai de nous coller le code d'initialisation de $bdd stp.

    $bdd = new \PDO('mysql:dbname='nomBDD.';charset=utf8; host='localhost', 'loginBDD' , 'passBDD', array(
                \PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",
                \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_OBJ,
            ));

Quand tu fais un requete Where :u_login AND :u_password
Tu lui dis quand login et mot de passe.

D'accord et ?
Il veut quand login = ça et password = ça

Donc

Where :u_login = [$_POST['login']] AND :u_password = $_POST['password']

ce qui donne :

$req = $bdd->prepare("SELECT * FROM users WHERE :u_login = [$_POST['login']] AND :u_password = $_POST['password'];

Allelujah, j'ai une vrai percé, merci bidule. Effectivement sur le dernier code j'avais oublié la comparaison du coup avec le code:

try{

    $u_log = $_POST['login'];
    $u_pass = $_POST['password'];

    $req = $bdd->prepare("SELECT * FROM users WHERE u_login = :u_login AND u_password = :u_password");
    $req->execute(array('u_login' => $_POST['login'], 'u_password' => $_POST['password']));
    $finduser= $req->fetch();

}catch(PDOException $pdoe){
    die ('Erreur: ' . $pdoe->getMessage());
}catch(Exception $e){
    die ('Erreur: ' . $e->getMessage());
};

echo "<pre>";
var_dump($finduser);
echo "</pre>";
die();

J'obtiens:


E:\wamp64\www\login_post.php:33:
array (size=12)
  'id' => string '2' (length=1)
  0 => string '2' (length=1)
  'first_name' => string 'toto' (length=4)
  1 => string 'toto' (length=4)
  'last_name' => string 'toto' (length=4)
  2 => string 'toto' (length=4)
  'u_login' => string 'toto' (length=4)
  3 => string 'toto' (length=4)
  'u_password' => string 'toto' (length=4)
  4 => string 'toto' (length=4)
  'email' => string 'toto' (length=4)
  5 => string 'toto' (length=4)

Cool, du coup avec ça, ce sera plus pratique à manipuler

    $req->fetch(PDO::FETCH_OBJ);

Bidule, en mettant PDO::FETCH_OBJ me retourne une erreur. En gros de ce que j'ai compris de l'erreur vient de ce thread https://stackoverflow.com/questions/6815520/cannot-use-object-of-type-stdclass-as-array

Donc en enlevant le PDO::FETCH_OBJ tout fonctionne......

Un grand merci à vous tous.

La suite de mon aventure, demain! ;-)

Challenge 100DaysOfCode jour [4/100]

L'apprentissage est dur, mais c'est trop cool quand tu réduis le temps de débogage sur des concepts que tu maîtrises pas encore.
Aujourd'hui j'ai mis un peu moins de 2h pour faire ce que j'ai fait en une journée complète hier en intégrant de nouveaux concept pour moi.

Voici ma production du jour

Un simple module de connection en intégrant les functions, les tableaux, les appels de function utilisateur et comprendre la portée des variables. J'ai encore un peu de mal à définir quand appeler un REQUIRE, quand un REQUIRE_ONCE, quand un INCLUDE ...

<?php
    /*
    L'objectif est de créer un système de notation d'élève pour les professeurs
    Il faut:
    Un système de connexion
    Un accès BDD / lecture BDD / écriture BDD
    Un système de stats
    Un système de récupération de list
    On travaillera les fonctions, le code PHP/HTML plus poussé
    */

    /*

    Système de connexion:
    Vérifier si l'utilisateur est déjà connecté
    1. pas de $_post = forumlaire
    2. $_POST function de log
    3. $_POST de password érroné, message d'erreur avec nouveau form
    */
    require 'pdo.php';
    if (!isset($_POST['login']) AND !isset($_POST['password'])){
    ?>
            <form action="" method='post'>
            <p>
                <label for="login">identifiant</label>: <input type="text" name="login" placeholder=" Identifiant" /><br/>
                <label for="password">Mot de passe</label>: <input type="text" name="password" placeholder="Mot de passe" /><br/>
                <input type="submit" value="Se connecter">
            </p>
            </form>
    <?php
        }else{
            require 'login.php';
            $user = [$_POST['login'], $_POST['password']];
            $user_log= logmein($user);
            if(in_array(true, $user_log)){
                echo "Bravo vous êtes connecté";
            }else{
    ?>
                <p style='color: red'> Identifiant ou mot de passe incorrect</p>
                <form action="" method='post'>
                    <p>
                        <label for="login">identifiant</label>: <input type="text" name="login" placeholder=" Identifiant" /><br/>
                        <label for="password">Mot de passe</label>: <input type="text" name="password" placeholder="Mot de passe" /><br/>
                        <input type="submit" value="Se connecter">
                    </p>
                </form>
    <?php
            };
        };
?>
Et voici la fonction qui est la même qu'hier, mais adapté au concept de fonction
<?php
function logmein (array $user) :array {
    require 'pdo.php';
    $u_log = $user[0];
    $u_pass = $user[1];
    $req = $bdd->prepare("SELECT * FROM users WHERE u_login = :u_login AND u_password = :u_password");
    $req->execute(array('u_login' => $user[0], 'u_password' => $user[1]));
    $finduser= $req->fetch();

    if($finduser['u_login'] === $u_log & $finduser['u_password'] === $u_pass){
        return [true, $finduser['u_password']];
    }
    else{
        return [false, null];
    };
    $finduser->closeCursor();
};

Merci encore une fois pour votre aide hier, ça m'a encore plus motivé.

A demain pour la suite

Bonsoir

Je vais éssayer d'être le plus simple.

Include vs require

Les deux permettent la même chose, inserer un fichier afin de décomposer ton code et éviter la duplication de code.

L'exemple le plus simple étant le fichier de la connexion de la base de données.

La différence entre les deux alors ?
Lorsque tu utilises INCLUDE si ton fichier n'est pas trouvé et bien ton script continue temps bien que mal , par exemple si tu utilises include pour ajouter une barre de navigation et que le fichier n'est pas trouvé ta page sera fonctionnelle.

Alors avec REQUIRE, ton script s'arrete et génère une erreur car comme son nom l'indique le fichier est requit.

maintenant le _ONCE ? dans l'absolu si tu faire un include (ou un require) plusieurs fois du même fichier ex: ta barre de navigation ce qui peux arriver lorsque tu inclus un fichier dans lequel tu as AUSSI inclus le fichier barre de navigation et bien tu verras que ta barre de navigation apparatrait plusieurs fois.

Donc le _ONCE rend cette duplication impossible => REQUIRE_ONCE => insere OBLIGATOIREMENT le fichier et UNE seule fois quelque soit le nombre de fois que je te le demande.

Sinon ta fonction est bien mais comme tu le dis affinable:

Apres ta requete SQL tu fais un IF afin de comparer si le login de la bdd et le login de ton formualire sont egaux et bien cela ne sert à rien (idem pour le mot de passe).
Pourquoi ? Simplement par ce que cette comapraison tu l'as déjà fait dans ta requete SQL.

Dans ta requete, tu demandes de trouver LE compte ayant pour login envoyé dans le formulaire ET le mot de passe envoyé par le formulaire.

Donc si dans le formualire le login est bon ET le mot de passe est faux alors ta requete ne renvoie RIEN !!! c'est le couple login et password qui est recherché, donc si l'un ou l'autre n'est pas bon impossible de trouver quelque chose.

<?php
function logmein (array $user) :array {
    require 'pdo.php';
    $u_log = $user[0];
    $u_pass = $user[1];
    $req = $bdd->prepare("SELECT * FROM users WHERE u_login = :u_login AND u_password = :u_password");
    $req->execute(array('u_login' => $user[0], 'u_password' => $user[1]));
    $finduser= $req->fetch();

     // ici nul besoin de faire cette comparaison, juste vérifier que ta requete n'est pas vide
    if(!empty($finduser)){ 
    // A tester si cela ne serai pas suffisant : if(!$finduser){ 
        return [true, $finduser['u_password']];
    }
    else{
        return [false, null];
    };
    $finduser->closeCursor();
};

Bon courage pour la suite ;) et bonne nuit

Challenge 100DaysOfCode jour [5/100]

Les choses avancent tranquillement. Ca prend du temps, mais je comprends de plus en plus, et surtout j'arrive à débogger mes problèmes. J'ai encore beaucoup de chose à apprendre et à améliorer, mais les bases s'améliorent. Je suis surtout content d'avoir compris le fonctionnement et la logique des fonctions utilisateurs et de la porté des variables.

Ce que je veux faire

Je cherche à faire un backoffice sur lequel un prof pour créer un élève, ajouter des notes ou remarques et faire des recherches sur des éléments de la BDD.

Voici le code du backoffice

<?php
    /*
    Il faut que je puisse
    Créer un élève
    consulter un élément
    Ajouter un élément
    */
    ?>
    <h1>Bienvenue sur le site de gestion des élèves</h1>
    <br/>
    <br/>
    <?php
    if(!isset($_POST['create']) AND !isset($_POST['add_element']) AND !isset($_POST['search_element'])){
        require 'form.php';
    }elseif(isset($_POST['create'])){
        header('Location: createform.php');
        exit;
    }elseif(isset($_POST['add_element'])){
        require 'form.php';
        echo "vous voulez ajouter un élément";
    }elseif(isset($_POST['search_element'])){
        require 'form.php';
        echo "vous voulez consulter un élément";
    };

Voici le code du formulaire de création des élèves

<?php

    require 'form.php';
    if(!isset($_POST['first_name']) AND !isset($_POST['last_name']) AND !isset($_POST['s_class'])){
        ?>     
        <form action="" method='post'>
        <label for="first_name">Prénom</label><input type="text" name="first_name" placeholder="Prénom" /><br/>
        <label for="last_name">Nom</label><input type="text" name="last_name" placeholder="Nom" /></break>
        <label for="s_class">Classe</label><input type="text" name="s_class" placeholder="Classe" /></break>
        <input type="submit" name="btn_create" value="Créer" />
        </form>
        <?php 
    }else{
        require 'createstudent.php';
        $student = [$_POST['first_name'], $_POST['last_name'], $_POST['s_class']];
        $createstudent = createStudent($student);
        if($createstudent === true){
            echo "Vous avez créer l'élève $student[0] $student[1]";
        }else{
            echo "vous n'avez rien créer";
        };
    };

Voici le code de la fonction

<?php

    function createStudent(array $student) :bool{
        require 'pdo.php';

        $req = $bdd->prepare('INSERT INTO students(first_name, last_name, s_class) VALUES (:first_name, :last_name, :s_class)');
        $req->execute(array(
            'first_name' => $student[0], 
            'last_name' => $student[1], 
            's_class' => $student[2]));
        return true;

    };

Je suis content des progrès que je fais. Même si je suis très loin de tout maîtriser, c'est quand même cool! Et merci @bidule pour les infos sur REQUIRE ...

Bomjoiur
cette facons d'ecrire va tes creer de probleme unitile


<?php
    /*
    Il faut que je puisse
    Créer un élève
    consulter un élément
    Ajouter un élément
    */
    ?>
    <h1>Bienvenue sur le site de gestion des élèves</h1>
    <br/>
    <br/>
    <?php
    if(!isset($_POST['create']) AND !isset($_POST['add_element']) AND !isset($_POST['search_element'])){
        require 'form.php';
    }elseif(isset($_POST['create'])){
        header('Location: createform.php');
        exit;
    }elseif(isset($_POST['add_element'])){
        require 'form.php';
        echo "vous voulez ajouter un élément";
    }elseif(isset($_POST['search_element'])){
        require 'form.php';
        echo "vous voulez consulter un élément";
    }; ```

En effet fais juste de menu simple

 <a heref="XXX.php">  XXXX </a>
 <a heref="YYYY.php"> YYYY </a>
 <a heref="ZZZZ.php"> ZZZZ </a>

A la long tu pourrais venir mètre les conditions d'accès selon les rôles (Admin, Secrétaire, Comptable) ;
evite trop coute pour rendre aps lourd...

Balisse class

<label for="s_class">Classe</label><input type="text" name="s_class" placeholder="Classe" /></break>

Sa pourrais être intéressent si le donner classe provienne de la basse données que laisser libre choix au gens d’écrire la classe.
C.-à-d.
Avoir un select qui récupère les classes qui sont dans la basse des donnée près enregistrer par admin

Par Exempele :

<label for="pet-select">choisir votre classe :</label>
<select name="classe" >
    <option value="">--choisir votre classs--</option>
<?php foreach($classe AS $class): ?>
    <option value="<?= $class[‘idc’]  ?>"><?= $class[‘nom_class’]?></option>
<?php endforeach ?>
</select>

POUR L'INSSERTION , comme vous utiliser le tableau ....

<?PHP
 function createStudent(array $student) :bool{
        require 'pdo.php';
        $data = [
            'first_name' => $student[0], 
            'last_name' => $student[1], 
            's_class' => $student[2]));
        ];
        $sql = "INSERT INTO students (first_name, last_name, s_class) VALUES (:first_name, :last_name, :s_class";
        $stmt= $bdd->prepare($sql);
        $stmt->execute($data);
           return true;
    }

Enfin mon amies quand un sujet est résolu pointe-le en résolue ouvre une autre terminale pour une nouvelle question

Bonjour,

Merci pour ces bons conseils. Le but n'est pas nécessairement de poster mes problème de code, mais plus de partager mon apprentissage à travers ce challenge 100DaysOfCode. Si ça dérange la manière dont je le présente je comprends tout à fait et je clôturerai sans problème.
Concernant tes retours, ils sont intéressant. Comme je suis en plein apprentissage je travaille un max les sujets afin de les comprendre et de les maîtriser. En ce moment c'est les conditions et les fonctions. Mais t'inquiète pas que lorsque j'arriverai au chapitre sur les rôles que j'utiliserai une structure basique avec menu HTML et HREF sans problème. Mais j'en suis pas encore là.
Enfin sur la fonction de création, je ne comprends pas pourquoi tu rajoutes des variables. N'est-il pas plus efficace et lisible de faire la fonction sur 2 lignes que de passer par une multitude de variable qui peuvent perdre au deboggage?

Cdlt