[php5] package users - gestion utilisateurs - les iterateurs en php

Soyez le premier à donner votre avis sur cette source.

Vue 12 406 fois - Téléchargée 1 260 fois

Description

Bon, toujours dans ma croisade pour faire découvrir la SPL, voici un nouveau package.
C'est une gestion utilisateur basique.
Je fournis une classe db basique, avec juste ce dont j'ai besoin. VOus pouvez utiliser la votre, mais attention, certaines méthodes doivent être implémentées, avec ces noms (sinon, cherchez leur utilisation dans la classe oUser et modifiez les appels) :
fetch_assoc ()
query ()
insert_id
C'est tout :-)

Le package gère ceci :
identification d'un utilisateur
création d'un utilisateur
récupération d'un utilisateur
modification d'un utilisateur

Le tout, évidemment, avec gestion des sessions.

je montre 2 exemples:
test.php fait un tour sur les possibilités d'itération, essentiellement.
exemple.php montre une page de formulaire d'identification, avec création à la volée si un utilisateur n'existe pas, identification s'il existe et possibilité de modifier son nom, et gestion d'erreur si il se plante d'identification.

Le tout est basé sur un fichier de configuration XML.
Ce fichier se présente obligatoirement ainsi :
sous la racine, un noeud USER et un noeud SESSION
Dans USER, un noeud ID obligatoire, idem pour SESSION.
Les autres noeuds sous USER et SESSION sont à votre préférence!
Les sous noeuds pour chaque propriétés :
BDD_NAME est le nom du champ dans votre table.
TYPE est son type (en fait, string ou int)
Ca, c'est obligatoire.
Ensuite : IDENT indique que ce champ est utilisé pour l'identification.
MANDATORY indique qu'il est obligatoire pour la création d'un utilisateur (s'il manque, la création renverra une erreur)
DEDOUBLE indique qu'on dédoublonne la table sur ce (ou ces) champ. Exemple, un mec entre un email et un mot de passe; vous dédoublonnez sur l'email : si le couple email/password existe, ok, le mec est identifié. Sinon, si email existe, le mec s'est planté de mot de passe (c'est là le dédoublonnage). Sinon, ben il n'existe pas.

Vous pouvez ajouter autant de champs que vous voulez, pour peu que vous les ayez dans votre table utilisateur, évidemment... : adresse, code postal, ville, etc...
Idem pour la session.

La table créée pour les 2 fichiers exemples :
sous mysql
nom base de donnée : bdd_test
nom table : users
champs :
user_id (int) autoincrement
user_email (varchar)
user_pwd (varchar)
user_nom (varchar)

à vous de la créer.
Voili :-)

Source / Exemple :


<?php
/**

  • oUser package
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20061124
  • /
if (!class_exists ('RecursiveArrayIterator')) { // PHP5 < 5.1 /**
  • class RecursiveArrayIterator
  • @author php.net
  • implementation for PHP5 < 5.1
  • /
class RecursiveArrayIterator extends ArrayIterator implements RecursiveIterator { private $ref; function hasChildren () { return is_array ($this -> current ()); } function getChildren () { if ($this -> current () instanceof self) { return $this -> current (); } if (empty ($this -> ref)) { $this -> ref = new ReflectionClass ($this); } return $this -> ref -> newInstance ($this -> current ()); } } } /**
  • class oUserException extends Exception
  • personalized Exception class for this package
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20061124
  • /
class oUserException extends Exception { const ERROR_GEN_NOT_SETABLE = '{__PROP__} is not a setable property'; const ERROR_GEN_NOT_GETABLE = '{__PROP__} is not a getable property'; const ERROR_USER_PROP_NOT_EXISTS = '{__PROP__} property does not exist'; const ERROR_USER_PROP_HAS_NO_VALUE = '{__PROP__} property has no value'; const ERROR_USER_XML_KEY_NOT_COMPLETE = '{__KEY__} has no children'; const ERROR_USER_XML_FILE_NOT_EXISTS = '{__FILE__} has not been found'; const ERROR_USER_XML_LOADING_FAILED = 'Failed to load {__FILE__}'; const ERROR_USER_CHECKIDENT_BAD_VALUES_COUNT = 'Values given in arguments and Authentication fields do not match'; const ERROR_USER_MANDATORY_FIELD_MISSING = 'The mandatory field {__FIELD__} is missing'; const ERROR_USER_ID_NOT_INTEGER = 'User ID must be an integer'; public function __construct($sMsg, $iCode = 0) { parent::__construct($sMsg, $iCode); } } /**
  • class myFilter extends FilterIterator
  • filter Iterator class dedicated to oUser class
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20061124
  • /
class myFilter extends FilterIterator { /**
  • private oIt
  • Iterator object
  • @var Iterator
  • /
private $oIt = null; /**
  • private mFilter
  • main filter
  • @var string
  • /
private $mFilter = null; /**
  • public function __construct
  • constructor
*
  • @param (RecursiveIteratorIterator) oIt
  • @param (string) mFilter
  • /
public function __construct (RecursiveIteratorIterator $oIt, $mFilter = null) { parent::__construct ($oIt); $this -> oIt = $oIt; $this -> mFilter = $mFilter; } /**
  • public function accept
*
  • @return (boolean)
  • /
public function accept () { if (!is_null ($this -> mFilter)) { if ($this -> oIt -> key () === $this -> mFilter && $this -> oIt -> getDepth () === 0) { return true; } if ($this -> oIt -> key () === $this -> mFilter && $this -> oIt -> getDepth () === 1) { return true; } if ($this -> oIt -> getDepth () > 0 && $this -> oIt -> getSubIterator (0) -> key () === $this -> mFilter) { return true; } return false; } return true; } } /**
  • abstract class abstractUser
  • abstraction class defining oUser
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20061124
  • /
abstract class abstractUser { /**
  • protected aCanBeGet
  • array of properties that can be get
  • @var array
  • /
protected $aCanBeGet = array ( 'FILTER', 'SUBFILTER', 'ITMODE' ); /**
  • protected aCanBeSet
  • array of properties that can be set
  • @var array
  • /
protected $aCanBeSet = array ( 'FILTER', 'SUBFILTER', 'ITMODE' ); /**
  • protected cItMode
  • RecursiveIteratorIterator mode
  • @var RecursiveIteratorIterator constant
  • /
protected $cItMode = true; /**
  • protected mFilter
  • main filter
  • @var string
  • /
protected $mFilter = null; /**
  • protected aProps
  • array of properties
  • @var array
  • /
protected $aProps = array (); /**
  • public oSession
  • oSession object
  • @var oSession
  • /
public $oSession = null; /**
  • protected oXml
  • simpleXML object
  • @var simpleXML
  • /
protected $oXml = null; /**
  • public function __construct
  • constructor
  • @param (string) $fXml : xml config filename
  • /
public function __construct ($fXml) { if (!file_exists ($fXml)) { throw new oUserException (str_replace ('{__FILE__}', $fXml, oUserException::ERROR_USER_XML_FILE_NOT_EXISTS)); } if (!($this -> oXml = @simplexml_load_file ($fXml)) instanceof SimpleXMLElement) { throw new oUserException (str_replace ('{__FILE__}', $fXml, oUserException::ERROR_USER_XML_LOADING_FAILED)); } $this -> oSession = new oSession ($this -> oXml); $this -> aPropsFill (); } /**
  • private function aPropsFill
  • fills the array of properties aProps from oXml
  • /
private function aPropsFill () { foreach ($this -> oXml -> USER -> children () as $oNode) { $aTmp = array (); foreach ($oNode -> children() as $oChild) { $aTmp[(string)dom_import_simplexml($oChild) -> tagName] = (string)$oChild['value']; } if (empty ($aTmp)) { throw new oUserException (str_replace ('{__KEY__}', (string)dom_import_simplexml($oNode) -> tagName, self::ERROR_XML_KEY_NOT_COMPLETE)); } $this -> aProps[(string)dom_import_simplexml($oNode) -> tagName] = $aTmp; } } /**
  • public function __get
  • getter
  • @param (string) sProp
  • @return sProp value
  • /
public function __get ($sProp) { if (!in_array ($sProp, $this -> aCanBeGet) && !array_key_exists ($sProp, $this -> aProps)) { throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_GETABLE)); } switch ($sProp) { case 'FILTER' : return $this -> mFilter; break; case 'SUBFILTER' : return $this -> mSubFilter; break; case 'ITMODE' : return $this -> cItMode; break; default : if (!isset ($this -> aProps[$sProp])) { throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_USER_NOT_EXISTS)); } if (!is_null ($this -> mFilter)) { if (isset ($this -> aProps[$sProp][$this -> mFilter])) { return $this -> aProps[$sProp][$this -> mFilter]; } } if (!isset ($this -> aProps[$sProp]['VALUE'])) { //throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_USER_PROP_HAS_NO_VALUE)); return null; } return $this -> aProps[$sProp]['VALUE']; break; } } /**
  • public function __set
  • setter
  • @param (string) sProp
  • @param (mixed) mVal
  • @return void
  • /
public function __set ($sProp, $mVal) { if (!array_key_exists ($sProp, $this -> aProps) && !in_array ($sProp, $this -> aCanBeSet)) { throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_SETABLE)); } switch ($sProp) { case 'FILTER' : $this -> mFilter = $mVal; break; case 'ITMODE' : $this -> cItMode = $mVal; break; default : $this -> aProps[$sProp]['VALUE'] = $mVal; break; } } /**
  • public function getProps
  • get the aProps array of properties
  • @return RecursiveIteratorIterator or myFilter Iterator
  • /
public function getProps () { if (!is_null ($this -> mFilter)) { if (is_string ($this -> mFilter)) { return new myFilter (new RecursiveIteratorIterator (new RecursiveArrayIterator ($this -> aProps), $this -> cItMode), $this -> mFilter); } } return new RecursiveIteratorIterator (new RecursiveArrayIterator ($this -> aProps), $this -> cItMode); } /**
  • abstract public function checkIdent
  • check if a user exists in the database, given IDENT fields in the xml config file
  • @param (string) sTable : users DB table name
  • @param (array) aValues : array of fields to be checked, each key being the key of the config file, and the value being the input value
  • /
abstract public function checkIdent ($sTable, $aValues); /**
  • abstract public function createUser
  • create a user if values are correct
  • @param (string) sTable : users db table name
  • @param (array) aValues : array of fields to be created, each key being the key of the config file, and the value being the input value
  • /
abstract public function createUser ($sTable, $aValues); /**
  • abstract public function getUser
  • get a user from DB
  • @param (mixed) iUserId : existing user ID in the DB
  • @param (string) sTable : users db table name
  • @param (boolean) bSession : true if get values must fill the session (if config file defines these fields for the session), false if not
  • /
abstract public function getUser ($iUserId, $sTable, $bSession = true); /**
  • abstract public function modUser
  • modify a user in DB
  • @param (mixed) iUserId : existing user ID in the DB
  • @param (string) sTable : users db table name
  • @param (array) aValues : array of fields to be modified, each key being the key of the config file, and the value being the input value
  • @param (boolean) bSession : true if get values must fill the session (if config file defines these fields for the session), false if not
  • /
abstract public function modUser ($iUserId, $sTable, $aValues, $bSession = true); } /**
  • class oSession
  • session class
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20061124
*
  • see abstractUser for info about the methods and properties of this class, same definitions apply here
  • /
class oSession { private $aProps = array (); private $oXml; public function __construct (simpleXMLElement $oXml) { $sSessionId = session_id (); if (empty ($sSessionId)) { session_start (); } $this -> oXml = $oXml; $this -> aPropsFill (); } private function aPropsFill () { foreach ($this -> oXml -> SESSION -> children () as $oNode) { $this -> aProps[(string)dom_import_simplexml($oNode) -> tagName] = null; } } public function __get ($sProp) { if (!array_key_exists ($sProp, $this -> aProps)) { throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_SETABLE)); } return $this -> aProps[$sProp]; } public function __set ($sProp, $mVal) { if (!array_key_exists ($sProp, $this -> aProps)) { throw new oUserException (str_replace ('{__PROP__}', $sProp, oUserException::ERROR_GEN_NOT_GETABLE)); } $this -> aProps[$sProp] = $mVal; $_SESSION['USER'][$sProp] = $mVal; } public function __isset ($sProp) { if (!array_key_exists ($sProp, $this -> aProps)) { return false; } return true; } } /**
  • class oUser extends abstractUser
  • user class
  • @author Johan Barbier <johan.barbier@gmail.com>
  • @version 20061124
*
  • see abstractUser for info about the methods and properties of this class, same definitions apply here
  • /
class oUser extends abstractUser { private $oDB; public function __construct ($sXml, $oDB) { parent::__construct ($sXml); $this -> oDB = $oDB; } public function checkIdent ($sTable, $aValues) { $sTmp = $this -> mFilter; $this -> mFilter = 'IDENT'; $aProps = $this -> getProps (); foreach ($aProps as $sV) { $sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key (); $sCurrentDbName = $this -> aProps [$sKeyName]['BDD_NAME']; if (empty ($aValues[$sKeyName])) { throw new oUserException (oUserException::ERROR_USER_CHECKIDENT_BAD_VALUES_COUNT); } if ($this -> aProps[$sKeyName]['TYPE'] === 'string') { if (isset ($this -> aProps[$sKeyName]['DEDOUBLE'])) { $aDedoub[] = $sCurrentDbName.' = \''.$aValues[$sKeyName].'\''; } $aIdent[] = $sCurrentDbName.' = \''.$aValues[$sKeyName].'\''; } else { if (isset ($this -> aProps[$sKeyName]['DEDOUBLE'])) { $aDedoub[] = $sCurrentDbName.' = '.$aValues[$sKeyName]; } $aIdent[] = $sCurrentDbName.' = '.$aValues[$sKeyName]; } } $this -> mFilter = $sTmp; if (count ($aValues) !== count ($aIdent)) { throw new oUserException (oUserException::ERROR_USER_CHECKIDENT_BAD_VALUES_COUNT); } $sWhereClause = implode (' AND ', $aIdent); $sQuery = 'SELECT '.$this -> aProps['ID']['BDD_NAME'].' FROM '.$sTable.' WHERE '.$sWhereClause; $this -> oDB -> query ($sQuery); $aRes = $this -> oDB -> fetch_assoc (); if (!empty ($aRes[$this -> aProps['ID']['BDD_NAME']])) { $this -> oSession -> ID = $aRes[$this -> aProps['ID']['BDD_NAME']]; return true; } else { if (!empty ($aDedoub)) { $sWhereDedoubClause = implode (' AND ', $aDedoub); $sQuery = 'SELECT '.$this -> aProps['ID']['BDD_NAME'].' FROM '.$sTable.' WHERE '.$sWhereDedoubClause; $this -> oDB -> query ($sQuery); $aRes = $this -> oDB -> fetch_assoc (); if (!empty ($aRes[$this -> aProps['ID']['BDD_NAME']])) { return -1; } } return false; } } public function createUser ($sTable, $aValues) { $sTmp = $this -> mFilter; $this -> mFilter = 'MANDATORY'; $aProps = $this -> getProps (); foreach ($aProps as $sK => $sV) { $sMandatory = $aProps -> getInnerIterator () -> getSubIterator (0) -> key (); if (empty ($aValues[$sMandatory])) { throw new oUserException (str_replace ('{__FIELD__}', $sMandatory, oUserException::ERROR_USER_MANDATORY_FIELD_MISSING)); } } $this -> mFilter = 'BDD_NAME'; $aProps = $this -> getProps (); foreach ($aProps as $sV) { $sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key (); if (!empty ($aValues[$sKeyName])) { $aFields[] = $sV; if ($this -> aProps [$aProps -> getInnerIterator () -> getSubIterator (0) -> key ()]['TYPE'] === 'string') { $aVals[] = '\''.$aValues[$sKeyName].'\''; } else { $aVals[] = $aValues[$sKeyName]; } } } $this -> mFilter = $sTmp; $sFields = implode (',', $aFields); $sVals = implode (',', $aVals); $sQuery = 'INSERT INTO '.$sTable.' ('.$sFields.') VALUES ('.$sVals.')' ; if ($this -> oDB -> query ($sQuery)) { $this -> oSession -> ID = $this -> oDB -> insert_id (); return true; } return false; } public function getUser ($iUserId, $sTable, $bSession = true) { $sTmp = $this -> mFilter; $this -> mFilter = 'BDD_NAME'; $aProps = $this -> getProps (); foreach ($aProps as $sV) { $aFields[] = $sV; } $sFields = implode (',', $aFields); $sQuery = 'SELECT '.$sFields.' FROM '.$sTable.' WHERE '.$this -> aProps['ID']['BDD_NAME'].' = '.$iUserId; $this -> oDB -> query ($sQuery); $aRes = $this -> oDB -> fetch_assoc (); if (empty ($aRes)) { return false; } foreach ($aProps as $sV) { $sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key (); $this -> aProps[$sKeyName]['VALUE'] = $aRes[$sV]; // PHP5 < 5.1 if (true === $bSession && true === $this -> oSession -> __isset ($sKeyName)) { $this -> oSession -> $sKeyName = $aRes[$sV]; } /*PHP5 >= 5.1 if (true === $bSession && true === isset ($this -> oSession -> $sKeyName)) { $this -> oSession -> $sKeyName = $aRes[$sV]; }
  • /
} $this -> mFilter = $sTmp; return true; } public function modUser ($iUserId, $sTable, $aValues, $bSession = true) { $sTmp = $this -> mFilter; $this -> mFilter = 'BDD_NAME'; $aProps = $this -> getProps (); foreach ($aProps as $sV) { $sKeyName = $aProps -> getInnerIterator () -> getSubIterator (0) -> key (); if (!empty ($aValues[$sKeyName])) { if ($this -> aProps [$aProps -> getInnerIterator () -> getSubIterator (0) -> key ()]['TYPE'] === 'string') { $aVals[] = $sV.'= \''.$aValues[$sKeyName].'\''; } else { $aVals[] = $sV.'='.$aValues[$sKeyName]; } // PHP5 < 5.1 if (true === $bSession && true === $this -> oSession -> __isset ($sKeyName)) { $this -> oSession -> $sKeyName = $aValues[$sKeyName]; } } } $this -> mFilter = $sTmp; if (empty ($aVals)) { return false; } $sVals = implode (',', $aVals); $sQuery = 'UPDATE '.$sTable.' SET '.$sVals.' WHERE '.$this -> aProps['ID']['BDD_NAME'].' = '.$iUserId; if ($this -> oDB -> query ($sQuery)) { return true; } return false; } } ?>

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
1
Date d'inscription
vendredi 28 janvier 2011
Statut
Membre
Dernière intervention
29 janvier 2011

Merci bcp pour ce code !
Messages postés
151
Date d'inscription
samedi 1 novembre 2003
Statut
Membre
Dernière intervention
30 juillet 2018

Hello

Dans le cadre d'un projet, j'utilise ton script. Mais j'ai un probleme assez enervant: j'utilise des tableaux pour la config et non du xml ( en fait un fichier YAML convertit en array ).
J'ai structuré mon tableau pour coller au xml d'exemple :

Array
(
[USER] => Array
(
[ID] => Array
(
[BDD_NAME] => id
[TYPE] => int
)

[EMAIL] => Array
(
[BDD_NAME] => email
[TYPE] => string
[MANDATORY] =>
[IDENT] =>
[DEDOUBLE] =>
)

[PASSWORD] => Array
(
[BDD_NAME] => password
[TYPE] => string
[MANDATORY] =>
[IDENT] =>
)

[NOM] => Array
(
[BDD_NAME] => login
[TYPE] => string
)

)

[SESSION] => Array
(
[0] => ID
[1] => EMAIL
)

Mais je m'arrive pas a modifier le script pour utiliser un tableau et non un xml .....
Pourrais-tu m'aider ?
Merci
Messages postés
68
Date d'inscription
vendredi 27 juillet 2007
Statut
Membre
Dernière intervention
31 janvier 2009

j'aime bien
Messages postés
4
Date d'inscription
jeudi 8 septembre 2005
Statut
Membre
Dernière intervention
21 juillet 2007

Hum... si on pousse un peu plus loin, même avec cette modif on peux pas mettre de chaine vide dans la bdd, si on a un tel besoin il faut alors carrément virer le if ^^
Messages postés
4
Date d'inscription
jeudi 8 septembre 2005
Statut
Membre
Dernière intervention
21 juillet 2007

Salut, bravo pour cette class et merci malalam de nous faire découvrir la puissance des itérateurs.
J'ai trouvé un petit défaut, lors de la creation/modification d'un utilisateur le script teste si la chaine qu'on lui fournie n'est pas vide avec un !empty(), et comme le 0 est considéré comme vide, ça ne les prend pas en compte, ce qui peut etre assez gênant dans certains cas...

Si d'autres ont rencontré le même problème voici la modif pour que ça fonctionne, ligne 456 et 513 remplacer :
if (!empty ($aValues[$sKeyName]))
par :
if ($aValues[$sKeyName] != '')
Afficher les 16 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.