Requète préparée avec PDO

Résolu/Fermé
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 - 22 sept. 2014 à 09:27
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 - 27 oct. 2014 à 19:42
Bonjour,

Je souhaiterai convertir enfin je veux dire passer mes requètes traditionnelles en requète préparée avec PDO
Je n'arrive pas à mettre en place cette fonction, si quelqu'un pourrais me donner quelques petites explications.
Cette fonction marche bien avec ma connexion actuelle Mysql mais je vais changer la requète de connexion et passer en requète préparée avec PDO
Merci de votre gentillesse.
<?php
function user_exists($username) {
    $username = filtres($username);
    return (mysql_result(mysql_query("SELECT COUNT(id_adherent) FROM tb_adherent WHERE username = '$username'"), 0) == 1) ? true : false;
}
?>

37 réponses

labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
23 sept. 2014 à 08:53
Bonjour
Il y a lontemps que je galère pour faire un fichier de connexion avec toutes les sécurisations necessaires mais en vain.
Ma fonction session_start() est inclu je ne l'ai pas mise.
Merci vraiment pour ton aide
Voici mon fichier de connexion
<?php
//L'adresse IP du serveur sous lequel le script courant est en train d'être exécuté.
if ($_SERVER['SERVER_ADDR'] == '127.0.0.1'){
//données pour la connexion à la base de données local
$PARAM_hote        ='localhost';     	//nom du serveur mysql
$PARAM_nom_bdd     ='ma_base'; 	//le nom de la base de données
$PARAM_utilisateur ='root';          	//login
$PARAM_mot_passe   ='';              	//mot de passe pour se connecter

	try{
//connexion à la BDD (Création d'une instance de la classe PDO)
//On cré l'objet $bdd à l'aide de la commande new suivi du nom de la classe
    $bdd = new PDO('mysql:host=' . $PARAM_hote . ';dbname=' . $PARAM_nom_bdd, $PARAM_utilisateur, $PARAM_mot_passe);
    
    $bdd->exec("SET CHARACTER SET utf8");
    $bdd->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    $bdd->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
	}

	catch(Exception $e){
//sinon on affiche l'erreur
    echo 'Impossible de se connecter à la base de donnée</br>';
    echo 'Erreur : ' .  $e->getMessage() . '<br />';
    echo 'N° : ' .      $e->getCode();
	}
}
?>

Mon fichier de vérification
<?php
if (empty($_POST) === false) {	

        $username = Security::clean($_POST['username']);

        $password = Security::clean($_POST['password']); 
        $password = Security::hash($password);

	$sql = ('SELECT *
			FROM tb_adherent
			WHERE username=:username
			AND password=:password') or die(print_r($bdd->errorInfo()));
	$requete = $bdd->prepare($sql);

    //on execute la requète en lui transmettant la liste des paramètres
    $requete->execute(array(
							':username' => $username,
							':password' => $password
							));

    //on affiche les reponses de la requète dans un tableau
    $donnees = $requete->fetch();

    if (empty($username) === true || empty($password) === true) {
        $errors[] = 'Veuillez entrer le Login et le Mot de passe';
    } else if (user_exists($username) === false) {
        $errors[] = 'Le Login et / ou le Password n\'existe pas.';
    } else {      
        $login = login($username, $password);
        if ($login === false) {
            $errors[] = 'La combinaison Login/Mot de passe est incorrect';
        } else {
            $_SESSION['id_adherent'] 		= $login;
            header('Location: index.php');
            exit();
        }
    }
}
?>

Mes fonctions, par contre la fonction login en requète préparée et je ne sais pas si la fonction filtres fait doublon avec la fonction clean ?
<?php
//Méthode de hachage pour le password
class Security {
    const GRAIN = 'f?,j89-k0.;-!?lqjçs_di3%5a6_4jhfgh';

    public static function hash($donnees) {
        return sha1(md5($donnees) . self::GRAIN . sha1($donnees . self::GRAIN) . $donnees);
    }
    public static function clean($donnees) {
        return htmlspecialchars(trim($donnees));
    }
}

function filtres($donnees) {
    return htmlentities(strip_tags(mysql_real_escape_string($donnees)));
}

function user_exists($username) {
    $username = filtres($username);

    $req = $bdd->prepare('SELECT COUNT(*) FROM tb_adherent WHERE username = :user');
    $req->bindParam(':user', $username, PDO::PARAM_STR);
    $req->execute();
    $count = $req->fetchColumn();

    return ($count == 0) ? false : true;
}

function login($username, $password) {
    
    $username = filtres($username);
    
    return (mysql_result(mysql_query("SELECT COUNT(id_adherent) FROM tb_adherent WHERE username = '$username' AND password = '$password'"), 0) == 1) ? $id_adherent : false;
}
?>
2
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
22 sept. 2014 à 18:18
Salut,

 <?php
function user_exists($bd, $username) {
    $username = filtres($username);

    $req = $bd->prepare('SELECT COUNT(*) FROM tb_adherent WHERE username = :user');
    $req->bindParam(':user', $username, PDO::PARAM_STR);
    $req->execute();
    $count = $req->fetchColumn();

    return ($count == 0) ? false : true;
}
?>

0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
22 sept. 2014 à 19:55
Bonjour,
Merci pour ton aide, malheureusement j'ai quelques petites erreurs.

Warning: Missing argument 2 for user_exists(), called in C:
et
Fatal error: Call to a member function prepare() on a non-object in C

Tu peux s'il te plait me donner ton avis sur ses erreurs.
Je te remercie
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
22 sept. 2014 à 21:20
Et ben tout simplement, lorsque tu fais appel à ta fonction, tu dois lui fournir deux paramètres !
Le premier, c'est une instance d'une connexion de type PDO, par exemple :

$connect = null;
try {
  $dns = 'mysql:host=localhost;dbname=nomDeLaBaseDeDonnee';
  $user = 'root';
  $password = '';
  $connect = new PDO($dns, $user, $password);
}
catch(Exception $e) {
  echo 'Connection error : ' . $e->getMessage();
  die();
}

if(user_exists($connect, 'labourette')) echo "Ce nom d'utilisateur existe déjà.";
else echo "Ce nom d'utilisateur est parfait.";


Le deuxième paramètre, c'est le username que tu veux vérifier.
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
22 sept. 2014 à 22:56
Bonjour,
Maintenant j'ai juste cette erreur à résoudre si tu peux encore m'aider.
Merci.
Fatal error: Call to a member function prepare() on a non-object in C:
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
23 sept. 2014 à 00:00
Je peux voir tout le code, connexion, définition de la fonction, appel ... ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022 525
23 sept. 2014 à 09:29
Salut,

Ton fichier de connexion est-il bien inclus au début de ton fichier de vérification ?

Au passage, effectuer un htmlspecialchars (via Security::clean) et/ou un htmlentities (via la fonction filtres) sur des données à insérer en bdd n'est pas une bonne pratique, tu vas polluer ta base d'entité html inutilement.

Puisque désormais tu utilises les requêtes préparées pour insérer tes données, tu n'as besoin d'aucun filtrage supplémentaire contre les injections sql (la requête préparée convertie les caractères réservé en sql) : donc pas de htmlentities, ni htmlspecialchars, ni de strip_tags et encore moins mysql_real_escape_string avec PDO.

Tu devras utiliser htmlentities uniquement lorsque tu afficheras tes données dans une page html.

Bonne journée
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
Modifié par JooS le 23/09/2014 à 16:31
Tu dois te décidé, sois tu optes pour la POO, soit tu programmes de façon modulaire/fonctionnelle (vielle méthode).

Donc je te propose ceci, je ne l'ai même pas exécuté vu que je ne suis pas sur mon PC, donc à toi de tester, et apprends à interpréter les erreurs, c'est en anglais mais c'est de l'anglais basique ... en tout cas, si tu travailles en orienté objet de cette façon, et que tu respectes ses normes de programmation, ça peut te faire gagner des heures et des heures, et ça te fera une expérience pour "pourquoi pas" adopter un framework.

Fichier config.php
<?php
class Config {

    /* DATABASE CONFIGURATION */
    const HOTE = 'localhost';
    const DBNAME = 'ma_base';
    const USERNAME = 'root';
    const PASSWORD = '';

}


Fichier database.php
<?php
require_once 'config.php';

class Database extends PDO {

    public function __construct() {
        try {
            parent::__construct('mysql:host=' . Config::HOTE . ';dbname=' . Config::DBNAME, Config::USERNAME, Config::PASSWORD);
    
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
 }
 catch(Exception $e) {
            echo 'Impossible de se connecter à la base de donnée</br>';
            echo 'Erreur : ' .  $e->getMessage() . '<br />';
            echo 'N° : ' .      $e->getCode();
 }
    }

}


Fichier security.php
<?php
class Security {

    const GRAIN = 'f?,j89-k0.;-!?lqjçs_di3%5a6_4jhfgh';

    public static function hash($donnees) {
        return sha1(md5($donnees) . self::GRAIN . sha1($donnees . self::GRAIN) . $donnees);
    }

    public static function clean($donnees) {
        return trim($donnees);
    }

}


Fichier user.php
<?php
require_once 'database.php';

class User {

    /* DATABASE ATTRIBUTES */
    private $id;
    private $username;
    private $email;
    private $password;

    private $db;

    public function __construct($id = null) {
        $this->db = new Database();

        if(is_int($id)) {
            $this->load($id);
        }
    }

    private function load($id) {
        $req = $this->db->prepare('SELECT * FROM tb_adherent WHERE id = :id');
        $req->bindParam(':id', $id, PDO::PARAM_INT);
        $req->execute();
        $d = $req->fetch(PDO::FETCH_ASSOC);

        $this->setUserDatas($d);
    }

    public function setUsername($u) {
         $this->username = trim($u);
    }

    public function getUsername($u) {
         return $this->username;
    }

    public function setEmail($e) {
         $this->email = trim($e);
    }

    public function getEmail($u) {
         return $this->email;
    }

    public function setPassword($p) {
         $this->password = trim($p);
    }

    public function setUserDatas(array $d) {
        if(!empty($d)) {
            $this->id = $d['id'];
            $this->username = $d['username'];
            $this->email = $d['email'];
            $this->password = $d['password'];
        }
    }

    public static function get($username) {
        $req = $this->db->prepare('SELECT id FROM tb_adherent WHERE username = :u');
        $req->bindParam(':u', $username, PDO::PARAM_STR);
        $req->execute();

        return new self($req->fetchColumn());
    }

    public static function exists($username) {
        $username = trim($username);

        $req = $this->db->prepare('SELECT COUNT(*) FROM tb_adherent WHERE username = :user');
        $req->bindParam(':user', $username, PDO::PARAM_STR);
        $req->execute();
        $count = $req->fetchColumn();

        return ($count == 0) ? false : true;
    }

    public function login() {
        $req = $this->db->prepare('SELECT * FROM tb_adherent WHERE username = :u AND password = :p');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->bindParam(':p', $this->password, PDO::PARAM_STR);
        $req->execute();
        $d = $req->fetch(PDO::FETCH_ASSOC);
        
        $this->setUserDatas($d);

        return (!empty($d));
    }

    public function save() {
        $req = $this->db->prepare('INSERT INTO tb_adherent (username, email, password) VALUES (:u, :e, :p)');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->bindParam(':e', $this->email, PDO::PARAM_STR);
        $req->bindParam(':p', $this->password, PDO::PARAM_STR);
        $req->execute();

        $req = $this->db->prepare('SELECT id FROM tb_adherent WHERE username = :u');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->execute();

        $this->id = $req->fetchColumn();
    }

    public function update() {
        $req = $this->db->prepare('UPDATE tb_adherent SET username = :u, email = :e, password = :p WHERE id = :id');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->bindParam(':e', $this->email, PDO::PARAM_STR);
        $req->bindParam(':p', $this->password, PDO::PARAM_STR);
        $req->bindParam(':id', $this->id, PDO::PARAM_INT);
        $req->execute();
    }
}


Fichier login.php
<?php
if (empty($_POST) === false) { 

    $username = Security::clean($_POST['username']);
    $password = Security::clean($_POST['password']); 

    if(empty($username) || empty($password)) {
        $error = 'Veuillez entrer le Login et le Mot de passe';
    }
    else {
        $password = Security::hash($password);

        $user = new User();
        $user->setUsername($username);
        $user->setPassword($password);

        if($user->login()) {
            $_SESSION['adherent'] = serialize($user);
            header('Location: index.php');
            exit();
        }
        else {
            $error =  'La combinaison Login/Mot de passe est incorrect';
        }
    }
}


Fichier register.php
<?php
if (empty($_POST) === false) { 

    $username = Security::clean($_POST['username']);
    $email = Security::clean($_POST['email']);
    $password = Security::clean($_POST['password']);

    if(empty($username) || empty($email) || empty($password)) {
        $error = 'Veuillez entrer le Login, l\'email et le Mot de passe';
    }
    else {
        $password = Security::hash($password);

        $user = new User();
        $user->setUsername($username);
        $user->setEmail($email);
        $user->setPassword($password);

        $user->save();
    }
}


Autre exemples :
<?php
$user = new User(1);
$user1 = new User(345);

// Modifier le mot de passe
$newPass = Security::hash('un mot de passe');
$user->setPassword($pass);
$user->update();

if(User::exists('labourette')) {
    $user2 = User::get('labourette');
    echo $user2->getEmail();
}


Mettez en résolu quand c'est résolu ...
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
23 sept. 2014 à 20:51
Bonjour
C'est vraiment génial je te remercie, mais par contre il y a une erreurs.

Catchable fatal error: Argument 1 passed to User::setUserDatas() must be an array, boolean given, called in C

Merci de ton aide j'espère que je vais pouvoir y mettre en place, merci
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
23 sept. 2014 à 22:08
Ok, alors au lieu de trouver l'origine de l'erreur, je te montre comment on fait :

1 - Tu interprètes le message d'erreur en français ou sinon tu traduis à l'aide de "Google translate".
L'erreur en gros dit : "L'argument 1 qui est passé à la méthode setUserDatas de la classe User doit être un tableau, alors qu'en fait c'est un booléen qui est passé à la place."

2 - Une fois qu'on a compris ce qui déclenche l'erreur, alors on remonte jusqu'à la ligne concernée, on y trouve ceci :

$d = $req->fetch(PDO::FETCH_ASSOC);
$this->setUserDatas($d);

On remarque que le problème se trouve dans la variable "$d", car c'est cette variable qui est passé en tant que "Argument N°1" à la méthode setUserDatas, et qu'est ce que le message disait également, il disait que c'est un booléen qui a été passé a cette méthode au lieu d'un tableau.
Donc la variable "$d" contient un booléen.
Donc on doit comprendre ce qui fait en sorte qu'elle contient un booléen au lieu d'un tableau, alors c'est la ligne juste au dessus (fetch), donc lorsqu'on exécute "fetch" pour récupérer les résultats sous forme de tableau, celle ci me retourne un booléen à la place d'un tableau.
Alors qu'est ce qu'on fais, on va voir la documentation de la méthode fetch. (il suffit d'écrire "fetch pdo php" sur google) pour comprendre pourquoi elle retourne un booléen.

La documentation nous dit que c'est seulement en cas d'erreur que la méthode retourne "FALSE" (un booléen).

Maintenant je ne peux pas continuer vu que je ne sais pas exactement ce que tu as exécuté, qu'as tu essayé de faire pour que cette erreur ait apparu ?

PS : J'ai noté quelques erreur de contexte.
Fichier : user.php
<?php
require_once 'database.php';

class User {

    /* DATABASE ATTRIBUTES */
    private $id;
    private $username;
    private $email;
    private $password;

    private static $db;

    public function __construct($id = null) {
        self::init();

        if(is_int($id)) {
            $this->load($id);
        }
    }

    public function init() {
        if(self::$db == null) self::$db = new Database();
    }

    private function load($id) {
        $req = self::$db->prepare('SELECT * FROM tb_adherent WHERE id = :id');
        $req->bindParam(':id', $id, PDO::PARAM_INT);
        $req->execute();
        $d = $req->fetch(PDO::FETCH_ASSOC);

        $this->setUserDatas($d);
    }

    public function setUsername($u) {
         $this->username = trim($u);
    }

    public function getUsername($u) {
         return $this->username;
    }

    public function setEmail($e) {
         $this->email = trim($e);
    }

    public function getEmail($u) {
         return $this->email;
    }

    public function setPassword($p) {
         $this->password = trim($p);
    }

    public function setUserDatas(array $d) {
        if(!empty($d)) {
            $this->id = $d['id'];
            $this->username = $d['username'];
            $this->email = $d['email'];
            $this->password = $d['password'];
        }
    }

    public static function get($username) {
        self::init();

        $req = self::$db->prepare('SELECT id FROM tb_adherent WHERE username = :u');
        $req->bindParam(':u', $username, PDO::PARAM_STR);
        $req->execute();

        return new self($req->fetchColumn());
    }

    public static function exists($username) {
        self::init();

        $username = trim($username);

        $req = self::$db->prepare('SELECT COUNT(*) FROM tb_adherent WHERE username = :user');
        $req->bindParam(':user', $username, PDO::PARAM_STR);
        $req->execute();
        $count = $req->fetchColumn();

        return ($count == 0) ? false : true;
    }

    public function login() {
        $req = self::$db->prepare('SELECT * FROM tb_adherent WHERE username = :u AND password = :p');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->bindParam(':p', $this->password, PDO::PARAM_STR);
        $req->execute();
        $d = $req->fetch(PDO::FETCH_ASSOC);
        
        $this->setUserDatas($d);

        return (!empty($d));
    }

    public function save() {
        $req = self::$db->prepare('INSERT INTO tb_adherent (username, email, password) VALUES (:u, :e, :p)');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->bindParam(':e', $this->email, PDO::PARAM_STR);
        $req->bindParam(':p', $this->password, PDO::PARAM_STR);
        $req->execute();

        $req = self::$db->prepare('SELECT id FROM tb_adherent WHERE username = :u');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->execute();

        $this->id = $req->fetchColumn();
    }

    public function update() {
        $req = self::$db->prepare('UPDATE tb_adherent SET username = :u, email = :e, password = :p WHERE id = :id');
        $req->bindParam(':u', $this->username, PDO::PARAM_STR);
        $req->bindParam(':e', $this->email, PDO::PARAM_STR);
        $req->bindParam(':p', $this->password, PDO::PARAM_STR);
        $req->bindParam(':id', $this->id, PDO::PARAM_INT);
        $req->execute();
    }
}
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
24 sept. 2014 à 00:02
Bonjour

J'ai simplement envoyé le formulaire de connexion, l'erreur doit venir de la function login.
Merci
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
24 sept. 2014 à 10:46
Bon, commences par changer le mode de gestion des erreurs, "ERRMODE_EXCEPTION" au lieu de "ERRMODE_WARNING".

Et puis tu essayes de capturer l'erreur qui se produit si elle ne l'est pas déja,
Dans la méthode login :
try {
    $req = self::$db->prepare('SELECT * FROM tb_adherent WHERE username = :u AND password = :p');
    $req->bindParam(':u', $this->username, PDO::PARAM_STR);
    $req->bindParam(':p', $this->password, PDO::PARAM_STR);
    $req->execute();
    $d = $req->fetch(PDO::FETCH_ASSOC);
}
catch(Exception $e) {
    echo 'Erreur dans la méthode login : ' . $e->getMessage();
}
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
24 sept. 2014 à 15:16
Bonjour
Voici l'erreur retournée!
Fatal error: Access to undeclared static property: User::$db in......

je crois comprendre que db n'existe nul part dans la classe? en fait je ne sais pas.

Merci
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
26 sept. 2014 à 18:01
Bonjour,
Je suis désolé de te solliciter malheureusement je n'arrive pas à trouver mon erreur si tu peux m'aider encore.
Je te remercie.
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
Modifié par labourette le 28/09/2014 à 09:26
Bonjour
Je reviens vers toi, j'ai quelque peu modifié la class pour essayer de bien comprendre la programmation POO alors je souhaite dans un premier temps pouvoir me connecter avec un formulaire basique (login et password)
Dans ma BDD j'ai id_adherent, login et password.
En reprenant ta class et encore une fois comprendre ce que je fais j'ai créé une class Auth.
Peux tu me dire si je n'ai rien omis ou si je devrais ajouter quelque chose et pourquoi j'ai cette erreur.
Vraiment si tu peux m'aider ça serai génial que je puisse comprendre cette programmation par rapport à ce que j'ai fait jusqu'à présent avec mysql basique.
Encore un grand merci pour ton aide
Fichier auth.php

<?php
class Auth {
    private $id_adherent;
    private $login;
    private $password;
    
    private $bdd;
    
    public function __construct($id_adherent = null) {
        $this->bdd = new Database();
        
        //is_int -- Détermine si une variable est de type nombre entier
        if(is_int($id_adherent)) {
            $this->load($id_adherent);
        }
    }
    
    private function load($id_adherent) {
        $req = $this->bdd->prepare('SELECT * FROM tb_adherent WHERE id_adherent = :id_adherent');
        $req->bindParam(':id_adherent', $id_adherent, PDO::PARAM_INT);
        $req->execute();
        $donnees = $req->fetch(PDO::FETCH_ASSOC);

        $this->setUserData($donnees);
    }
    
    //trim -- Supprime les espaces (ou d'autres caractères) en début et fin de chaîne    
    public function setLogin($login) {
         $this->login = trim($login);
    }
    
    public function setPassword($password) {
         $this->password = trim($password);
    }
    
    public function getLogin($login) {
         return $this->login;
    }
    
    public function setUserData(array $donnees) {
        if(!empty($donnees)) {
            $this->id_adherent = $donnees['id_adherent'];          
            $this->login = $donnees['login'];
            $this->password = $donnees['password'];
        }
    }

    public function auth() {
        $req = $this->bdd->prepare('SELECT * FROM tb_adherent WHERE login = :login AND password = :password');
        $req->bindParam(':login', $this->login, PDO::PARAM_STR);
        $req->bindParam(':password', $this->password, PDO::PARAM_STR);
        $req->execute();
        $donnees = $req->fetch(PDO::FETCH_ASSOC);

        $this->setUserData($donnees);

        return (!empty($donnees));
    }
    
    public static function exists($login) {
        $login = trim($login);

        $req = $this->bdd->prepare('SELECT COUNT(*) FROM tb_adherent WHERE login = :user');
        $req->bindParam(':user', $login, PDO::PARAM_STR);
        $req->execute();
        $count = $req->fetchColumn();

        return ($count == 0) ? false : true;
    }
}

Fichier login.php
<?php
if (empty($_POST) === false) {
	
    $login = Security::clean($_POST['login']);
    $password = Security::clean($_POST['password']); 

	//si Login et Password sont vide
    if(empty($login) || empty($password)) {
        $error = 'Veuillez entrer le Login et le Mot de passe';
    } else {
        $password = Security::hash($password);

        $user = new Auth();
        $user->setLogin($login);
        $user->setPassword($password);

		//serialize -- Génère une représentation stockable d'une valeur
        if($user->auth()) {
            $_SESSION['id_adherent'] = serialize($user);
            header('Location: index.php');
            exit();
        } else {
            $error =  'Mauvais mot de passe...ou Mauvais login...Merci de recommencer.</br> Peut-être n\'êtes vous pas membre de la Clique ?</br>Dans ce cas désolé...';
        }
    }
}
?>

erreur
 Catchable fatal error: Argument 1 passed to Auth::setUserData() must be an array, boolean given, called in C
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
28 sept. 2014 à 14:04
Salut,

Désolé, je suis parti passé quelques journées à la plage.

Peux tu m'envoyé le code SQL de ta table, pour que je puisse déboguer chez moi.
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
28 sept. 2014 à 19:22
Bonjour
Non y a pas de soucis je comprends que tu es tes activités, c'est déjà sympa de pa part de prendre un peu de temps pour moi.
Voici ma table sql complète.
Merci
CREATE TABLE IF NOT EXISTS 'tb_adherent' (
  'id_adherent' int(11) NOT NULL AUTO_INCREMENT,
  'nom' varchar(45) DEFAULT NULL,
  'prenom' varchar(45) DEFAULT NULL,
  'email' varchar(45) DEFAULT NULL,
  'date_naissance' date DEFAULT '0000-00-00',
  'telephone_fixe' int(10) unsigned zerofill DEFAULT '0000000000',
  'telephone_mobile' int(10) unsigned zerofill DEFAULT '0000000000',
  'adresse' varchar(45) DEFAULT NULL,
  'lieu_dit' varchar(45) DEFAULT NULL,
  'code_postal' int(5) unsigned zerofill DEFAULT '00000',
  'ville' varchar(45) DEFAULT NULL,
  'actif' bit(1) DEFAULT NULL,
  'debut' year(4) DEFAULT '0000',
  'fin' year(4) DEFAULT '0000',
  'login' varchar(45) DEFAULT NULL,
  'password' varchar(255) DEFAULT NULL,
  PRIMARY KEY ('id_adherent')
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=87 ;
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
28 sept. 2014 à 19:23
Et voici mon formulaire de connexion
<form name="SeConnecter" id="SeConnecter" action="index.php?body=connexion_verif&type=accueil" method="post" enctype="multipart/form-data">
    <fieldset class="fieldset_connexion">
        <legend class="legend_connexion">Se connecter</legend>
		<center><b><p style="margin: 5px; padding: 5px;">Réservé aux membres</p></b></center>

			<label for="login">Login :</label>	 
			<center><input type="text" id="login" name="login" class="login" value="" tabindex="1"/></center> 
<br/>	
            <label for="motdepasse">Mot de passe :</label> 
            <center><input type="password" id="motdepasse" name="password" class="motdepasse" value="" tabindex="2"/></center> 
<br/>
			<input type="checkbox" name="remember"><span class="SeSouvenir">Se souvenir de moi</span>

			<center><input  src="image/envoyer.png" width="70%" type="image" name="connexion" class="connexion_form" border="0" Value="" align="middle"/></center>  
	</fieldset>
</form>
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
28 sept. 2014 à 20:06
j'ai oublié de te joindre le fichier security.php
<?php
class Security {

    const GRAIN = 'f?,j89-k0.;-!?lqjçs_di3%5a6_4jhfgh';

    public static function hash($donnees) {
        return sha1(md5($donnees) . self::GRAIN . sha1($donnees . self::GRAIN) . $donnees);
    }

    public static function clean($donnees) {
        return trim($donnees);
    }
}
?>
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
1 oct. 2014 à 20:44
Bonjour
Excuse moi de te déranger, j'aurai vraiment besoin de ton aide pour me résoudre mon problème de connexion, J'ai depuis plusieurs jours lu pas mal de tutos sur la programmation orienté objet j'ai vraiment envie de comprendre son fonctionnement.
Si tu peux essayer de m'expliquer cette erreur, en te remerciant vivement.

Catchable fatal error: Argument 1 passed to Auth::setUserData() must be an array, boolean given, called in
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
Modifié par JooS le 2/10/2014 à 00:55
Je t'ai envoyé un message privé il y a 2 ou 3 jours ou j'y ai corrigé toute les erreurs (car je ne sais pour quelle raison je n'arrivais pas à poster mon message dans ce topic).
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
Modifié par JooS le 2/10/2014 à 01:01
Explication de l'erreur :
Dans l'ancienne définition de la fonction(méthode) "setUserData", j'ai précisé à l'aide du mot clé "array" que le paramètre doit obligatoirement être un tableau.
Donc si on fournit autre chose qu'un tableau (comme dans ce cas un booléen), alors cette erreur apparaît.

Pour y remédier, soit on vérifie le type du paramètre(variable) avant de la fournir à la méthode.
Soit, on enlève le mot clé "array" (pour que la méthode accepte tout les types de données) et on vérifie le type du paramètre à l'intérieur de la méthode elle même.

Dans la correction que j'ai fait, j'ai opté pour la seconde solution.
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
2 oct. 2014 à 01:25
Bonjour
Excuse moi je n'ai pas trop l'habitude de regarder mes MP. Je te remercie beaucoup et je vais étudier, analyser et essayer de comprendre tout ça.
Merci
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
4 oct. 2014 à 20:32
Bonjour et vraiment un grand merci tout fonctionne à merveille. J'aurai s'il te plait quelques petits problèmes pour afficher le prénom du membre connecter.
Sur ma page index.php le prénom s'affiche bien
<?php
	if(!empty($_GET['action']) && $_GET['action'] == 'logout' && isset($_SESSION['id_adherent'])) {
		unset($_SESSION['id_adherent']);
		echo '<span class="DeconnexionReussie">Déconnexion réussie... </br>A bientôt '.$user->getPrenom().' !</br></br>';
		echo '<center>';
		echo '<a href="index.php?body=accueil&type=accueil">[Retour Formulaire]</a></span>';
		echo '</center>';
	}
?>

Par contre sur la page du formulaire lorsque je me déconnecte le prénom ne s'affiche pas, peux tu me dire où ce situe mon problème.
En te remerciant à nouveau
<?php
	if(!empty($_GET['action']) && $_GET['action'] == 'logout' && isset($_SESSION['id_adherent'])) {
		unset($_SESSION['id_adherent']);
		header('Location: index.php');
		echo '<span class="DeconnexionReussie">Déconnexion réussie... </br>A bientôt '.$user->getPrenom().' !</br></br>';
		echo '<center>';
		echo '<a href="index.php?body=accueil&type=accueil">[Retour Formulaire]</a></span>';
		echo '</center>';
	}
?>
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
5 oct. 2014 à 00:33
Bon, le nom de ta session est inapproprié dans ce cas, parce qu'elle ne contient plus l'id de l'utilisateur, mais elle contient l'objet user en entier (avec toute ses informations) !

Concernant ton problème !
Il faut que tu comprennes que les sessions ne peuvent pas contenir une variable dont la structure est complexe (pas linéaire), comme des objets par exemple (même les tableaux normalement, mais ça c'est un cas particulier) !
C'est pour ça qu'on utilise "serialize" avant d'enregistrer l'objet dans la session, or afin de convertir l'objet en une représentation linéaire (enregistrable dans la session) !
unserialize fait évidement le contraire, il convertit une représentation linéaire vers son origine (objet, tableau ...) !

1 - Donc, si tu veux accéder au prénom, il faut reconvertir la représentation qui se trouve dans la session vers son origine !
$user = unserialize($_SESSION['id_adherent']);

Après, on peux faire :
echo $user->getPrenom();

2 - Si tu supprimes la session, il n'y a plus de représentation, si il n'y a plus de représentation alors il n'y a plus d'objet user, si il n'y a plus d'objet alors on ne peux accéder au prénom de quelque chose qui n'existe plus !
Alors pense à enregistrer le prénom dans une variable temporaire avant de supprimer(unset) la session de l'utilisateur !

if(!empty($_GET['action']) && $_GET['action'] == 'logout' && isset($_SESSION['id_adherent'])) {
        $user = unserialize($_SESSION['id_adherent']);

        $pren = $user->getPrenom();

	unset($_SESSION['id_adherent']);
	unset($user);

	echo '<span class="DeconnexionReussie">Déconnexion réussie... </br>A bientôt '.$pren.' !</br></br>';
	echo '<center>';
	echo '<a href="index.php?body=accueil&type=accueil">[Retour Formulaire]</a></span>';
	echo '</center>';
}
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
5 oct. 2014 à 19:56
Bonjour
Tes explications sont très clair, très compréhensible beaucoup mieux que sur le net que j'ai pu trouver.
Encore vraiment un grand merci c'est beaucoup plus complexe que le codage traditionnel mais je crois qu'il sera à la sortie plus accessible.
Merci
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
Modifié par JooS le 5/10/2014 à 21:06
Difficile, non, différent peut être ... je pense même que c'est plus facile à apprendre, parce que la notion d'objet nous permet d'imaginer la chose dans la vraie vie !

Par exemple, certaines personnes ont du mal à faire la différence entre classe et objet(instance), dés qu'on leur donne l'exemple du "plan et les maisons", alors ils arrivent à mieux comprendre le principe, pourquoi, parce qu'ils ont imaginé un exemple réel, et on peux trouver des exemples dans tout ce qui nous entoure, parce qu'après tout, si on mets de coté la question de "vivant ou pas", alors tout peut être considéré comme étant un objet, d'ou la facilité de modéliser une solution à un problème réel via UML !

Mais comme tu l'as dis, même si c'est difficile pour certains, ça vaut la peine de perdre un peu de temps afin de l'apprendre, parce que tout sera plus compréhensible et facile à maintenir dans le temps.

PS : Le problème de session, ça c'est un problème "technique" qu'on a contourné avec une astuce, ça n'a rien avoir avec la POO, c'est relié à PHP.

Entre parenthèses, PHP à la base n'est pas un langage orienté objet, il a juste évolué, d'ailleurs ceux qui critiquent PHP prennent comme premier argument le fait qu' "il n'a pas de solide fondations en ce qui concerne la POO", contrairement à d'autre langages qui sont 100% orienté objet.
Cela ne fait pas de PHP un mauvais langage de programmation, c'est juste que tout les langages de programmations ont des défauts, et il n'y a pas de meilleur langage, c'est juste une question de besoins.

Je n'ai malheureusement pas travailler avec d'autres langages web, mais ça ne m'étonnerait pas que le problème de "session/données linéaire" soit inexistant ailleurs (Python, Ruby ...).

Voila, de rien, et bon courage.
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
6 oct. 2014 à 08:03
Bonjour,
Je me permet de te demander si tu peux encore me résoudre mon problème de COOKIE.
J'essaie de mettre en place le système de COOKIE mais en vain.
Le COOKIE s'affiche bien sur mon PC mais il faut quand même que je me reconnecte après la fermeture de mon navigateur.
Ca par contre je ne l'ai jamais mis en place sur mon site, j'ai déjà créé le COOKIE
Je te remercie
if(isset($_POST['remember'])){
setcookie('moncookie', ($_SESSION['id_adherent']) . sha1($user->getNom() . $user->getUsername() . $_SERVER['REMOTE_ADDR']), time() + 3600 * 24 * 3, '/', 'localhost', false, true);
}
0
JooS Messages postés 2468 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
6 oct. 2014 à 18:54
Ben c'est la même chose l'ami, c'est pareil que ce que j'ai dis plus haut !
Avant d'essayer d'accéder à l'objet, il faut le récupérer à partir de sa représentation linéaire, qui est enregistrée dans la session.

Par contre, tu ne peux travailler avec "sha", car c'est une fonction de hachage, c'est à dire qu'il n'y a pas de fonction qui fait l'inverse.
Donc tu dois chercher une fonction de cryptage/décryptage.

Pourquoi tu as besoin de décrypter, parce que lorsque l'utilisateur se connecte, la première chose que tu vérifies est l'existance d'une session, si ce n'est pas le cas, tu vérifies l'existence d'un cookie.
Si le cookie existe, tu dois récupérer sa valeur, la décrypter, puis connecter l'utilisateur grâce à la valeur décrypté (id, username ou email).

Tu dois également ajouter son mot de passé (haché) afin de vérifier l'identité de l'utilisateur.

if(isset($_POST['remember'])) {
    $user = unserialize($_SESSION['id_adherent']);
    $value = Security::crypt($user->getUsername()) . '_' . crypt($user->getPassword());

    setcookie('moncookie', $value, time() + 3600 * 24 * 3);
}


if(isset($_SESSION['id_adherent'])) {
    // Utilisateur déja connécté
    $user = unserialize($_SESSION['id_adherent']);
}
elseif(isset($_COOKIE['moncookie'])) {
    $values = trim($_COOKIE['moncookie']);
    $values = explode('_', $values);

    if(count(values) == 2) {
        $username = Security::decrypt($values[0]);
        $password = Security::decrypt($values[1]);

        $user_try = new User();
        $user_try->setUsername($username);
        $user_try->setPassword($password);

        if($user_try->login()) {
            $_SESSION['id_adherent'] = serialize($user_try);
            header('Location: index.php');
            exit();
        }
        else {
            // Les identifiants ne correspondent pas
        }
    }
    else {
        // Le cookie est invalide
    }
}


Voila, n'oublie pas de définit les méthodes "crypt" et "decrypt" dans la classe Security, et d'ajouter la méthode "getPassword" à la classe User.
0
labourette Messages postés 657 Date d'inscription dimanche 24 août 2008 Statut Membre Dernière intervention 24 juillet 2016 6
14 oct. 2014 à 19:52
Bonjour
Excuse moi de te déranger encore, mais vraiment impossible de mettre en place mon sytéme de COOKIE.
Peux tu encore m'aider, j'ain bien fait ce que tu m'a dit et j'ai trouvé sur le net les fonctions crypt et decrypt mais il y a quelque chose qui m'échappe.
Merci encore de ton coup de main.
0