code de forgot.php "<?php require 'includes/includes.php';
if(!empty($_SESSION['user'])){
  header('Location:profil.php');
} 
?>

<?php

if(!empty($_POST))
{
    $post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
    extract($post);

    $errors = [];

    if(empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)){
      array_push($errors, 'Cette email est invalide.');
    }
    else{
      $req = $Db->prepare('SELECT * FROM users WHERE email=:email');
      $req->bindValue(':email', $email, PDO::PARAM_STR);
      $req->execute();

       if(!$req){
        array_push($errors, 'Cet email ne correspond à aucun membre du site.');
      }
      else{
        $user = $req->fetch();
      }

      if(empty($errors))
      {
        $token = uniqid();

        $req = $db->prepare('INSERT INTO password_resets (email, token, created_at) VALUES (:email, :token, NOW())');
        $req->bindValue(':email', $email, PDO::PARAM_STR);
        $req->bindValue(':token', $token, PDO::PARAM_STR);
        $req->execute();

        $link = 'Bonjour, veuillez cliquer sur <a href="https://membres.test/reset.php?token='.$token.'">ce lien</a> pour réinitialiser votre mote de passe.';

        // Create the Transport
        $transport = (new Swift_SmtpTransport('smtp.mailtrap.io', 465))
          ->setUsername('fae489573327ac')
          ->setPassword('eed3d4ab64b373')
        ;

        // Create the Mailer using your created Transport
        $mailer = new Swift_Mailer($transport);

        // Create a message
        $message = (new Swift_Message('Mot de passe oublié'))
          ->setFrom(['lcorrefabien@gmail.com' => 'John Doe'])
          ->setTo([$email => $user->name])
          ->addPart($link, 'text/html');
          ;

        // Send the message
        $result = $mailer->send($message);

        if($result){
          $success = 'Un email vous a été envoyé avec des instructions.';
          unset($email);
        }
      }
    }
}

?>

  <?php 
$titrepage="Mot de passe oublié || Ndameyong - L'Ecole des Langues Camerounaises" ;
require 'includes/header.php'; 
?>

    <?php include('messages.php');?>

    <form action="forgot.php" method="post">
      <div class="form-group">
        <label for="email">Email</label>
        <input type="email" name="email" class="form-control" placeholder="Email" value="<?= $email ?? '';?>">
      </div>
      <button type="submit" class="btn btn-primary">Envoyer</button>
    </form>
    <br>

    <p><a href="login.php">Je m'en souviens en fait.</a></p>

<?php require 'includes/footer2.php'; ?>"  

code Db.php

"<?php

/**

  • Gestion de la base de données
    */
    class Db{

    private $host=HOST;
    private $name=DBNAME;
    private $user=USER;
    private $pass=PWD;

    private $connexion;

    function __construct($host=null,$name=null,$user=null,$pass=null){

    if($host != null){
        $this->host = $host;
        $this->name = $name;
        $this->user = $user;
        $this->pass = $pass;
    }
    
    try{
    
        $this->connexion = new PDO('mysql:host='.$this->host.';dbname='.$this->name,
            $this->user,$this->pass,array(
                1002 =>'SET NAMES UTF8',
                PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING
    
                ));
        $this->connexion->exec('SET NAMES utf8');

    //PDO::MYSQL_ATTR_INIT_COMMAND
    }catch (PDOException $e){
    //echo 'Erreur : Impossible de se connecter à la BD !';die();
    echo $e->getMessage();
    }

    }

    / requete /

    public function query($sql , $data=array()){
    $req = $this->connexion->prepare($sql);
    $req->execute($data);
    return $req->fetchAll(PDO::FETCH_OBJ);
    }

    public function tquery($sql , $data=array()){
    $req = $this->connexion->prepare($sql);
    $req->execute($data);
    return $req->fetchAll(PDO::FETCH_ASSOC);
    }

    public function insert($sql , $data=array()){
    $req = $this->connexion->prepare($sql);
    $nb=$req->execute($data);
    return $nb;
    }

    public function exec($sql , $data=array()){
    try{
    $req = $this->connexion->prepare($sql);
    $req->execute($data);
    return $req->rowCount(); // Retourne le nombre de lignes impactées par la reuqête
    }catch(Exception $e){
    echo 'Erreur : ' . $e->getMessage(); // en cas d'erreur dans la requête !
    }
    }

    public function deleteuser($id){
    $sql = 'DELETE FROM users WHERE id=:id';
    $data = [':id'=>$id];
    return $DB->exec($sql , $data) ;
    }

    public function uniqueEmail($email){
    $req = $this->connexion->prepare('SELECT count(*) as nbre from users WHERE email=:email limit 1');
    $req->execute(array('email'=>$email));

    $reponse = $req->fetchAll(PDO::FETCH_ASSOC);
    return $reponse[0]['nbre'];

    }

}

"

Ce que je veux

permettre à un utilisateur de retrouver son mot de passe via un système de récupération par email

Ce que j'obtiens

Notice: Undefined variable: Db in C:\wamp\www\ndameyong\forgot.php on line 23
Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\wamp\www\ndameyong\forgot.php on line 23
Error: Call to a member function prepare() on null in C:\wamp\www\ndameyong\forgot.php on line 23

6 réponses


Bonjour,

La FATAL ERROR est une conséquence directe de la NOTICE ERROR.

Tu demande à php d'exécuter une méthode à partir d'un objet qui n'en ai pas un puisque la variable n'existe pas.

Il faut donc tracer l'instanciation de cet objet... peut être dans le fichier includes.php du coup ?

Et comme indiqué dans un precedent poste... la casse compte.

Sur une ligne tu as:

$req = $Db->prepare('SELECT * FROM users WHERE email=:email');

Et sur une autre tu as:

$req = $db->prepare('INSERT INTO password_resets (email, token, created_at) VALUES (:email, :token, NOW())');

Y'a $Db ou $db sui est mal écrit :p

Au fait tu a mal placé tes balises backtiks ton post est difficile à lire, faut pas utiliser des quotes mais des triples backtiks comme ça:

    ` ` `
     $a = $b;
     ` ` `

mais sans les espaces entre les backtiks x)

Bonjour,

Le prepare doit être appelé sur un objet PDO qui n'est pas instancié.

Je vois que tu as créé une classe Db qui n'est pas appelée et que tu tente de faire un prepare sans avoir instancié l'objet.
Soit tu instancies l'objet Pdo, soit tu instancie un objet de ta classe Db en faisant $db = new Db(...); et ensuite tu appelle la méthode query de ta classe.
Un petit conseil, essaie d'être constant dans le nommage, j'ai vu $db, $Db dans ton forgot.php. De plus, dans ta classe Db, tu n'as pas besoin d'appeler $DB (qui n'existe pas) mais $this->connexion (l'objet Pdo que tu as instancié dans le constructeur).

Bonjour à tous,
merci pour vos réponses j'ai en fait repérer l'erreur sur la variable, il fallait écrire $DB et non $Db ou $db.
Cependant je comprends pas très bien comprend instancie une nouvelle classe. Dans mon fichier Db.php
j'ai une class Db que j'utilise je pensais que celle-ci allait me servir pour tous les besoins.
je vous laisse ce code afain que vous jetiez un coup d'oeil

Db.php " <?php

/**

  • Gestion de la base de données
    */
    class Db{

    private $host=HOST;
    private $name=DBNAME;
    private $user=USER;
    private $pass=PWD;

    private $connexion;

    function __construct($host=null,$name=null,$user=null,$pass=null){

    if($host != null){
        $this->host = $host;
        $this->name = $name;
        $this->user = $user;
        $this->pass = $pass;
    }
    
    try{
    
        $this->connexion = new PDO('mysql:host='.$this->host.';dbname='.$this->name,
            $this->user,$this->pass,array(
                1002 =>'SET NAMES UTF8',
                PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING
    
                ));
        $this->connexion->exec('SET NAMES utf8');

    //PDO::MYSQL_ATTR_INIT_COMMAND
    }catch (PDOException $e){
    //echo 'Erreur : Impossible de se connecter à la BD !';die();
    echo $e->getMessage();
    }

    }

    / requete /

    public function query($sql , $data=array()){
    $req = $this->connexion->prepare($sql);
    $req->execute($data);
    return $req->fetchAll(PDO::FETCH_OBJ);
    }

    public function tquery($sql , $data=array()){
    $req = $this->connexion->prepare($sql);
    $req->execute($data);
    return $req->fetchAll(PDO::FETCH_ASSOC);
    }

    public function insert($sql , $data=array()){
    $req = $this->connexion->prepare($sql);
    $nb=$req->execute($data);
    return $nb;
    }

    public function exec($sql , $data=array()){
    try{
    $req = $this->connexion->prepare($sql);
    $req->execute($data);
    return $req->rowCount(); // Retourne le nombre de lignes impactées par la reuqête
    }catch(Exception $e){
    echo 'Erreur : ' . $e->getMessage(); // en cas d'erreur dans la requête !
    }
    }

    public function deleteuser($id){
    $sql = 'DELETE FROM users WHERE id=:id';
    $data = [':id'=>$id];
    return $DB->exec($sql , $data) ;
    }

    public function uniqueEmail($email){
    $req = $this->connexion->prepare('SELECT count(*) as nbre from users WHERE email=:email limit 1');
    $req->execute(array('email'=>$email));

    $reponse = $req->fetchAll(PDO::FETCH_ASSOC);
    return $reponse[0]['nbre'];

    }

}

"

forgot.php "<?php require 'includes/includes.php';
if(!empty($_SESSION['user'])){
header('Location:profil.php');
}
?>

<?php

if(!empty($_POST))
{
$post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
extract($post);

$errors = [];

if(empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)){
  array_push($errors, 'Cette email est invalide.');
}
else{
  $req = $DB->prepare('SELECT * FROM users WHERE email=:email');
  $req->bindValue(':email', $email, PDO::PARAM_STR);
  $req->execute();

   if(!$req){
    array_push($errors, 'Cet email ne correspond à aucun membre du site.');
  }
  else{
    $user = $req->fetch();
  }

  if(empty($errors))
  {
    $token = uniqid();

    $req = $DB->prepare('INSERT INTO password_resets (email, token, created_at) VALUES (:email, :token, NOW())');
    $req->bindValue(':email', $email, PDO::PARAM_STR);
    $req->bindValue(':token', $token, PDO::PARAM_STR);
    $req->execute();

    $link = 'Bonjour, veuillez cliquer sur <a href="https://membres.test/reset.php?token='.$token.'">ce lien</a> pour réinitialiser votre mote de passe.';

    // Create the Transport
    $transport = (new Swift_SmtpTransport('smtp.mailtrap.io', 465))
      ->setUsername('fae489573327ac')
      ->setPassword('eed3d4ab64b373')
    ;

    // Create the Mailer using your created Transport
    $mailer = new Swift_Mailer($transport);

    // Create a message
    $message = (new Swift_Message('Mot de passe oublié'))
      ->setFrom(['lcorrefabien@gmail.com' => 'John Doe'])
      ->setTo([$email => $user->name])
      ->addPart($link, 'text/html');
      ;

    // Send the message
    $result = $mailer->send($message);

    if($result){
      $success = 'Un email vous a été envoyé avec des instructions.';
      unset($email);
    }
  }
}

}

?>

<?php
$titrepage="Mot de passe oublié || Ndameyong - L'Ecole des Langues Camerounaises" ;
require 'includes/header.php';
?>

<?php include('messages.php');?>

<form action="forgot.php" method="post">
  <div class="form-group">
    <label for="email">Email</label>
    <input type="email" name="email" class="form-control" placeholder="Email" value="<?= $email ?? '';?>">
  </div>
  <button type="submit" class="btn btn-primary">Envoyer</button>
</form>
<br>

<p><a href="login.php">Je m'en souviens en fait.</a></p>

<?php require 'includes/footer2.php'; ?> "

Merci

Juste je post le code en propre parce que c'est pas lisible xD et après je vais vérifier :p

Db.php

<?php

    /**
    Gestion de la base de données
    */
    class Db{

    private $host=HOST;
    private $name=DBNAME;
    private $user=USER;
    private $pass=PWD;

    private $connexion;

    function __construct($host=null,$name=null,$user=null,$pass=null){

        if($host != null){
            $this->host = $host;
            $this->name = $name;
            $this->user = $user;
            $this->pass = $pass;
        }

        try{

            $this->connexion = new PDO('mysql:host='.$this->host.';dbname='.$this->name,
            $this->user,$this->pass,array(
                1002 =>'SET NAMES UTF8',
                PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING

                ));
            $this->connexion->exec('SET NAMES utf8');

            //PDO::MYSQL_ATTR_INIT_COMMAND
    } catch (PDOException $e){
        //echo 'Erreur : Impossible de se connecter à la BD !';die();
        echo $e->getMessage();
    }

    }

    / requete /

    public function query($sql , $data=array()){
        $req = $this->connexion->prepare($sql);
        $req->execute($data);
        return $req->fetchAll(PDO::FETCH_OBJ);
    }

    public function tquery($sql , $data=array()){
        $req = $this->connexion->prepare($sql);
        $req->execute($data);
        return $req->fetchAll(PDO::FETCH_ASSOC);
    }

    public function insert($sql , $data=array()){
        $req = $this->connexion->prepare($sql);
        $nb=$req->execute($data);
        return $nb;
    }

    public function exec($sql , $data=array()){
        try {
            $req = $this->connexion->prepare($sql);
            $req->execute($data);
            return $req->rowCount(); // Retourne le nombre de lignes impactées par la reuqête
        } catch(Exception $e) {
            echo 'Erreur : ' . $e->getMessage(); // en cas d'erreur dans la requête !
        }
    }

    public function deleteuser($id){
        $sql = 'DELETE FROM users WHERE id=:id';
        $data = [':id'=>$id];
        return $DB->exec($sql , $data) ;
    }

    public function uniqueEmail($email){
        $req = $this->connexion->prepare('SELECT count(*) as nbre from users WHERE email=:email limit 1');
        $req->execute(array('email'=>$email));

        $reponse = $req->fetchAll(PDO::FETCH_ASSOC);
        return $reponse[0]['nbre'];
    }
}

forgot.php

<?php require 'includes/includes.php';
  if(!empty($_SESSION['user'])){
    header('Location:profil.php');
  }

  if(!empty($_POST)){
    $post = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
    extract($post);

    $errors = [];

    if(empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)){
      array_push($errors, 'Cette email est invalide.');
    } else {
        $req = $DB->prepare('SELECT * FROM users WHERE email=:email');
        $req->bindValue(':email', $email, PDO::PARAM_STR);
        $req->execute();

        if(!$req){
            array_push($errors, 'Cet email ne correspond à aucun membre du site.');
        } else {
            $user = $req->fetch();
        }

        if(empty($errors)){
            $token = uniqid();

            $req = $DB->prepare('INSERT INTO password_resets (email, token, created_at) VALUES (:email, :token, NOW())');
            $req->bindValue(':email', $email, PDO::PARAM_STR);
            $req->bindValue(':token', $token, PDO::PARAM_STR);
            $req->execute();

            $link = 'Bonjour, veuillez cliquer sur <a href="https://membres.test/reset.php?token='.$token.'">ce lien</a> pour réinitialiser votre mote de passe.';

            // Create the Transport
            $transport = (new Swift_SmtpTransport('smtp.mailtrap.io', 465))
                ->setUsername('fae489573327ac')
                ->setPassword('eed3d4ab64b373');

            // Create the Mailer using your created Transport
            $mailer = new Swift_Mailer($transport);

            // Create a message
            $message = (new Swift_Message('Mot de passe oublié'))
                ->setFrom(['lcorrefabien@gmail.com' => 'John Doe'])
                ->setTo([$email => $user->name])
                ->addPart($link, 'text/html');
            ;

            // Send the message
            $result = $mailer->send($message);

            if($result){
                $success = 'Un email vous a été envoyé avec des instructions.';
                unset($email);
            }
        }
    }}

    $titrepage="Mot de passe oublié || Ndameyong - L'Ecole des Langues Camerounaises" ;
    require 'includes/header.php';

    include('messages.php');
?>

  <form action="forgot.php" method="post">
    <div class="form-group">
      <label for="email">Email</label>
      <input type="email" name="email" class="form-control" placeholder="Email" value="<?= $email ?? '';?>">
    </div>
    <button type="submit" class="btn btn-primary">Envoyer</button>
  </form>
  <br>

  <p><a href="login.php">Je m'en souviens en fait.</a></p>

  <?php require 'includes/footer2.php'; ?>

Alors deja dans la class DB:

  • / requete / ça va planter ton code, soit tu mets // requete soit tu mets /* requete */

Ensuite dans ton forgot:
-Il y'a un endroit où tu mets deux fois ;, ça va planter le code:

$message = (new Swift_Message('Mot de passe oublié'))
                ->setFrom(['lcorrefabien@gmail.com' => 'John Doe'])
                ->setTo([$email => $user->name])
                ->addPart($link, 'text/html');
            ;

-A la fin de la partie php, tu mets un } en trop :o

Ensuite tu mets $DB->prepare, alors avant ça il faut l'instancier, et pour instancier une classe, c'est tout simple:

Bon on ne va pas te faire l'autoload on fera simple avec un require x)

Tout en haut de ton fichier tu mets:

require('./Db.php') // Avec le vrai chemin vers le fichier Db
$DB = new Db('ton_host','le_nom_de_ta_db','ton_user_surement_root','ton_pass');

Et mainteannt tu peux utiliser la variable $DB vu que tu l'a instancié :p
Pour instancier une classe, il faut récupérer le fichier, et faire un new de la classe dans le fichier importé

Ah et aussi j'ai profité pour virer les fermetures et réouvertures directes de balises php, c'est pas une bonne pratique x)
Si tu as fait ça pour spliter ton code, c'est qu'il fallait spliter dans des fichier diférents, mais jamais spliter dans le même fichier c'est une base x)