Page 1 sur 1

premier script en POO

Posté : 02 sept. 2009, 12:17
par albius
Bonjour,

En essayant de me mettre à la POO, j'ai commencé à consulter la documentation mais aussi un tutoriel trouvé sur un autre site. Il s'agit d'un système de login avec redirection écrit sur le même principe. Bien que je pense avoir compris la teneur du code, il en subsiste néanmoins une ou deux zones d'ombres. Un premier fichier de connexion à la base et une requête. Mais je ne suis pas sûr d'en avoir compris correctement la fin:
class Mysql {
	private $conn;
	//fonction servant à se connecter à la base.
	function __construct() {
		...
	}
	//Fonction servant à chercher le nom et password transmis par le user dans la table
	function verify_Username_and_Pass($un, $pwd) {
		//requête	
		$query = "SELECT *
				FROM users
				WHERE username = ? AND password = ?
				LIMIT 1";
		//Méthode type PDO		
		if($stmt = $this->conn->prepare($query)) {
			$stmt->bind_param('ss', $un, $pwd);
			$stmt->execute();
			
			if($stmt->fetch()) { //--> si $stmt récupère des données...
				$stmt->close(); //--> fermeture de $stmt, mais pourquoi ?
				return true; //--> je renvoie true...
			}
		}
	}
}
Dans un autre fichier, on créée un nouvel objet Mysql pour rediriger l'utilisateur (en fin, je crois)
class Membership {
	//fonction de validation 
	function validate_user($un, $pwd) {
		//instanciation de la classe mysql et création de l'objet '$mysql'
		$mysql = New Mysql();
		//Récupération de la réponse de la fonction verify_Username_and_Pass
		$ensure_credentials = $mysql->verify_Username_and_Pass($un, md5($pwd));
		//Si $ensure_credentials contient une réponse
		if($ensure_credentials) {
			$_SESSION['status'] = 'authorized';
			header("location: index.php");
		} else return "Please enter a correct username and password";
	}
Donc, si $ensure_credentials contient bien une réponse, donc true je suppose, je redirige l'utilisateur. C'est bien ça ?
merci,

Re: premier script en POO

Posté : 02 sept. 2009, 13:09
par v4gab0nd
Tu mélanges les objets.
La classe Mysql doit gérer l'entrée et la sortie de ta base de donnée. (qui pourrait être tout simplement PDO)
La classe Membership doit contenir la connexion de l'utilisateur et les infos de celui-ci.

Re: premier script en POO

Posté : 02 sept. 2009, 13:53
par Babounet
Dans la première classe:
$stmt->fetch() -> Récupère une ligne depuis un jeu de résultats associé à l'objet PDOStatement.
Si un résultat est récupéré, cela signifie que l'utisateur existe dans la base et que le mot de passe saisi est correct. Inutile donc de faire quoique ce soit d'autre, on ferme le statement et on retourne true.

Et pour la deuxième classe, c'est exactement ça.
$ensure_credentials contient la valeur de retour de la méthode $mysql->verify_Username_and_Pass($username, $passwd)

Si j'ai bien compris, ce sont 2 classes que tu as récupérées sur le net?
Je suis entièrement d'accord avec v4gab0nd, ces deux classes sont loin d'être parfaite sur bien des points!

Re: premier script en POO

Posté : 02 sept. 2009, 14:44
par albius
Merci pour vos réponses. Oui, c'est bien un script récupéré sur la toile, mais suffisant pour l'instant pour appréhender les principes de la POO.
Toutefois, pour rebondir sur vos propos, qu'aurait-il fallu faire pour que ce script soit meilleur ?
merci,

Re: premier script en POO

Posté : 02 sept. 2009, 14:58
par Babounet
Avec une question telle que celle-ci, tu risques d'avoir presque autant d'avis que de membres sur ce forum! ^^

Certains te diront de n'utiliser qu'une seule classe User, dans laquelle tu mettras toutes tes méthodes liées.
D'autres te soutiendrons qu'il est beaucoup plus propre de créer une classe qui se contentera d'accéder à la base de données et d'en utiliser une seconde pour faire les éventuels traitement.
Certains encore utiliseront l'une de ces deux solutions, mais en ajoutant des interfaces.

Je pense que c'est à toi de choisir ton niveau d'abstraction.
Quelque soit la solution choisie au final, le résultat est le même (ou presque).
Il est évident que tout mettre dans un seul fichier est totalement ridicule si ce dernier atteint des proportions trop importantes, de même qu'il est totalement inutile de créer 4 classes de 2 lignes là ou une seule ou deux auraient suffit.

Il serait, je pense, beaucoup plus formateur que tu te fasses ta propre opinion à ce sujet (ce qui n'empêche bien évidemment pas de s'inspirer des autres, au contraire!). Tu verras que la solution dépend bien souvent du projet.

Re: premier script en POO

Posté : 02 sept. 2009, 15:16
par FuZZyLine
Salut,
Merci pour vos réponses. Oui, c'est bien un script récupéré sur la toile, mais suffisant pour
l'instant pour appréhender les principes de la POO. Toutefois, pour rebondir sur vos propos,
qu'aurait-il fallu faire pour que ce script soit meilleur ?
merci,
Ne pas confondre POO et PDO. Surtout pas (que ca ne te vexe pas, c'est pas le propos)
suivant ton essai et ta demande... ET plus court qu'un long message:
<?php

   /**
    * Basé sur le principe du pattern Singleton
    */
    class MyClass
    {
      /**
       * Attribution d'un serveur par defaut
       *
       * Constante
       *
       */
       CONST BY_DEFAULT = "localhost";

      /**
       * variable unique, instance unique
       *
       * var instance
       */
       private static $_instance = NULL;

      /**
       * Nom du serveur
       *
       * var string
       */
       private $_serverName = "";

      /**
       * Nom du serveur
       *
       * var string
       */
       private $_dbName = "";

      /**
       * Nom de l'utilisateur
       *
       * var string
       */
       private $_login = "";

      /**
       * Mot de passe
       *
       * var string
       */
       private $_passwd = "";

      /**
       * Constructeur
       *
       * value  : none
       * return : none
       */
       private function __construct()
       {
       }

      /**
       * Fonction clonage mise en privée
       * ne sert qu'à empécher son utilisation
       *
       * value  : none
       * return : none
       */
       private function __clone()
       {
       }

      /**
       * Permet de récupérer l'instance de l'objet
       *
       * value  : none
       * return : var instance
       */
       public function getInstance()
       {
          return self::$_instance;
       }

      /**
       * Permet l'accés … l'instance donc initialisation de la class
       *
       * assigne la valeur $_serveur par défaut
       * Assigne si des arguments existent
       *
       * value  : none
       * return : boolean
       */
       public function init($keyName = false, $attrib = false)
       {
         /**
          * Test l'argument
          */
          if (!is_string($keyName) && $keyName !== false) die("Argument invalide !");

         /**
          * Si l'instance n'existe pas on la créé
          */
          if (!isset(self::$_instance))
          {
             self::$_instance = new self;

            /**
             * Serveur par défaut, ca fait gagner temps
             */
             self::$_instance -> _serverName = self::BY_DEFAULT;
          }
          $inst = self::$_instance;


          if ($keyName === false) return $inst;

         /**
          * Variable temporaire, impossible d'y couper
          */
          $key = "_".$keyName;

         /**
          * Si la clef correspond alors on y va
          */
          if (isset($inst -> $key))
          {
             $inst -> $key = $attrib;
             return $inst;
          }

         /**
          * La clef ne correspond pas, on quitte
          */
          die ("Clef introuvable, traitement impossible !");
       }

      /**
       * Te permet de récupérer la valeur de la variable passée en argument
       *
       * Stop le script si l'argument est invalide
       *
       * value  : var string, Nom de la variable … rechercher
       * return : var mixed
       */
       public function getValue($keyName = false)
       {
          if (!isset(self::$_instance)) self::$_instance = new self;

          $inst = self::$_instance;

          $key = "_".$keyName;

          if (isset($inst -> $key))
          {
             $inst -> $key = $attrib;
             return true;
          }
          echo "Clef introuvable !";
          return false;
       }
    }

   class EventClass
   {
      $db = MyClass::init();
      // .
      // .
      // .
   }
?>
C'est ainsi que beaucoup procède.
C'est pas une solution miracle. Ce n'est pas "forcément" la solution finale mais souvent utilisé.
C'est un classique. Même si j'y ai mis un peu de ma "sauce" ca reste facile à comprendre... 'fin je crois.

Avec ce type de class rien n'empèche de l'étendre etc... Après c'est juste toi qui vois ;)

J'espere que ca répond à ta demande.

@+ ;)

EDIT: Désolé pour les carctères bizaroîd, je développe sous Edit.com et le charset différent
EDIT: La majorité des caractères bizarîds remplacés

Re: premier script en POO

Posté : 02 sept. 2009, 16:00
par albius
Oulà! merci pour ton code FuZZyLine, mais je suis loin (très loin ) d'en être encore là... Et non, je ne me vexe pas. Je crois pouvoir faire la différence entre les deux... D'ailleurs, à ce propos, je vous soumets mon premier code écrit de cette manière (il s'appuie sur le précédent, mais rédigé avec PDO). je rencontre toutefois un premier problème : echo $_SESSION['nom']; n'affiche rien... Pourquoi ?
class login{
	//protection de la connection
	private $connect;
	private $nom;
	private $mdp;
	//
	function __construct(){
		define('USER', 'root');
		define('PASSWD', '');
		$this->connect = new PDO('mysql:host=localhost;dbname=', USER, PASSWD);
 		$this->connect->exec("SET CHARACTER SET utf8");
	}
	// requête pour chercher le nom et le password donné par l'utilisateur
	function verify_User_and_Pass($nom, $mdp){
		//requête
		$requete= $this->connect->prepare("SELECT nom FROM users WHERE nom = ? AND mdp = ? LIMIT 1");
		$requete->bindParam(1, $nom, PDO::PARAM_INT);
		$requete->bindParam(2, $mdp, PDO::PARAM_STR, 12);
		$requete->execute();
		if($result=$requete->fetch()){
			$_SESSION['nom'] = $result['nom'];
		}
 	}
}
Et dans l'autre fichier
session_start();
require_once 'classes/mysql.php';
$login = new login();
//
if($_POST && !empty($_POST['username']) && !empty($_POST['pwd'])) {
	$login->verify_User_and_Pass($_POST['username'], $_POST['pwd']);
	echo $_SESSION['nom']; //--> n'affiche rien ([quote]undefined Undefined index: nom[/quote])
}
Je le répète, c'est mon premier script rédigé de cette manière. Soyez indulgent s'il vous plaît... Ne tapez pas trop fort :lol:
merci,

Re: premier script en POO

Posté : 02 sept. 2009, 16:23
par Babounet
Visiblement, tu ne passes pas dans ton if:
if($result=$requete->fetch()){
  $_SESSION['nom'] = $result['nom'];
}
Je pense que le problème viens de cette ligne:
$requete->bindParam(1, $nom, PDO::PARAM_INT);
je ne pense pas que le login soit considéré comme un INT! :)

Un conseil, conserve le booléen de retour qui te permettra de savoir si l'utilisateur existe dans la base ou non.
Avec ta méthode, impossible de savoir si les identifiants renseignés sont correct sans tester la variable $_SESSION['nom']!

Tu pourras ainsi savoir très facilement si l'utilisateur est enregistré et le cas échéant récupérer son nom de cette manière:
if($login->verify_User_and_Pass($_POST['username'], $_POST['pwd'])) {
  echo $_SESSION['nom'];
} else {
  // Retour / Redirection / ...
}

Re: premier script en POO

Posté : 02 sept. 2009, 16:40
par FuZZyLine
Re,
Oulà! merci pour ton code FuZZyLine, mais je suis loin (très loin ) d'en être encore là...
Tu sais... J'en suis pas loin du tout début aussi, hein ;)

Je te conseille une lecture des patterns et de tous ses avantages.
(Julien Pauli a fait des docs dessus et je dois dire : chapeau)

En php il existe les SPL, la aussi tu devrais regarder.

Sinon, ici, tu trouveras moults infos, doc et tutos.

Essai de regarder (juste par curiosité) le Framework d'Hywan. Ca te donnera une
idée de la puissance de php ainsi que l'usage des objets et donc de ses formes d'applications.

Voili, voila, je crois avoir fait le tour,

@+ bon code ;)

Re: premier script en POO

Posté : 03 sept. 2009, 10:19
par albius
Rrrhhaaaaa!!! J'ai fini par trouver ce qui n'allait pas! C'était tout simplement ce foutu mot de passe qui était codé en md5!! #-o Tu m'étonnes que la requête restait lettre morte! C'est en regardant le même code mais écrit en procédural.
Par contre, ce qui m'étonnes, c'est que PDO ne me renvoyait aucune erreur. Pire encore, dans la batterie de tests que j'ai effectué, j'ai changé le nom d'un champ dans la requête et là également le même silence de la part de PDO. C'est normal ? Il me semble que mysql est nettement plus réactif que ça, non ?
merci,