Classe : gestion d'utilisateurs

Soyez le premier à donner votre avis sur cette source.

Vue 17 249 fois - Téléchargée 2 470 fois

Description

Bonjour à tous,

Tout d'abord je tiens à préciser que ce n'est pas la première, ni la dernière classe de gestion d'utilisateurs sur ce site mais je considère que celle ci est sans doute beaucoup plus flexible et adaptable à tous genre de situations.

C'est une classe (en fait ce sont plusieurs classes) de gestion d'utilisateurs (espace membre) écrite en PHP5. Elles sont entièrement objets (évidement puisque ce sont des classes...)

Ce qu'elle fait:
L'inscription des membres avec autant de champs que vous souhaitez. (Pas besoin de toucher au script pour ajouter un champ dans votre base)
La connexion des membres en mode parano (comparaison des user agent, ip et compagnie pour éviter le vol de session) ou en mode normal (session_id)
Vérification des données en temps réel (pas besoin de valider les données avant de les envoyer à la classe)
La liste des membres connectés en temps réel (J'ai opté pour des sessions SQL, on perds en perf, mais tellement plus flexible)
Création d'une clée pour redéfinir le mot de passe (et le redéfinir)
Mettre à jour un utilisateurs et ses informations
Un petit moteur de template light gèrant quelques trucs utiles
Quelques petits autres trucs

Ce qu'elle ne fait pas:
Tout le reste :P Comme j'ai dis le but était d'arriver avec un code réutilisable partout sans le retoucher ou très peu. Pas d'en faire un espace membre complet avec des milliers d'options.

Principes utilisés:
1. Les itérateurs (Merci à neigedhiver, sa source m'a bien aidé sur la compréhension des itérateurs)
2. Les méthodes magiques __get __set et __call (merci à php.net)
3. Les singletons (ici je remercis wikipedia)
4. Le moteur de template et l'utilisation des regex (Oui je sais, c'est lent)
5. Les exceptions (merci à malalam et ses sources)

Ce que la source comprends:
Une classe pour gestion des membres
Une classe pour la gestion de la base de données
Un petit moteur de template (très peu optimisé, je l'avou mais ce n'est pas la prioritée de la source)

Pourquoi je la poste ?
Pour avoir des avis sur des choses à améliorer, à refaire, ou simplement pour me faire dire que je suis totalement dans le champs et que j'ai rien compris à la programmation en php :) Avant de continuer à apprendre je veux être certain que je suis dans la bonne direction...

La source comprends une petite interface d'EXEMPLE (donc pas de gestion d'erreurs super poussée ou autre) ELLE N'EST PAS COMPLËTE. Je veux dire qu'elle ne montre pas toutes les possibilités de la classe, à vous de faire votre site... C'est pas un site tout fait, c'est une classe à adapter à votre site ! Donc il faut un minimum de connaissance en php hein...

Installation:
Il y a plusieurs variables de configuration dans le fichier conf/main.php ainsi qu'au début de la classe libs/users.class.php. Vous devez aussi importer le fichier importme.sql !

J'attends vos commentaires..

Source / Exemple :


<?php

//Exemple d'utilisation: Inscription d'un membre fichier inscription.php

include('./libs/core.php');

try {
	$t = new Core;
	$u = Core::Users();
	
	if (isset($_POST['username'])){
		$u->_username($_POST['username'], VALID_ALNUM);  // First way to store values with __call
		$u->SetValue('password', $_POST['password'], VALID_PASSWORD); // Second way to store values
		$u->SetValue('email', $_POST['email'], VALID_EMAIL);
		if (count($u->fields_errors) > 0) {
			echo count($u->fields_errors) . ' champs contiennent des valeurs invalides: <pre>';
			var_dump($u->fields_errors);
			echo '</pre>';
		} elseif ($u->Register('username,password,email')) {
			echo 'parfais';exit();
		}
	}
} catch (Exception $e) {
	echo 'Exception: '.$e->getMessage();
}
$t->display('inscription.phtml');
?>

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

codefalse
Messages postés
1127
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1 -
Yop :)
Etant donné que j'envisage de faire un système utilisateur pour mon framework, ta classe m'intéresse :)
J'ai zappé les parties Db et Template, pour aller droit au but.

Que serait un commentaire sans des remarques ? :p

Déjà, au niveau core, tu impose le moteur de template (dans __construct : new SimpleTPL), et si je veux pas le tiens ? :p
Tu devrais plutot prendre en paramètre de __construct une classe ayant une interface spécifique que tu spécifie (genre iTemplate) (__construct (iTemplate $tpl);) comme ca tu sais quelle fonction elle utilisera puisque c'est toi qui les aura définies dans ton interface, et tu permettra une plus grande souplesse pour le moteur de rendu. Tu devrais d'ailleur faire peut-etre la meme chose pour la classe db ? A voir.

A mon avis (mais ca n'engage que moi), faire le rendu dans le destructeur, c'est dangeureux car si tu as une erreur, tu n'aura aucun rendu :/

Ensuite tu définit les regex de validation directement dans la méthode setValue. Personnellement je suis contre, car ca t'oblige à modifier une classe user pour ajouter un systeme de validation. Tu modifie un truc pour ajouter une chose qui n'est pas en rapport.
Tu devrais faire une classe indépendante (à mon avis) :p

J'aime bien l'idée d'utiliser __call pour ajouter des propriétés, vraiment pas con ! :=)

Personnellement au lieu de faire des isTaken...., j'aurai fait une fonction générique verify, qui retourne une constance LOGIN_TAKEN, EMAIL_TAKEN, etc. Mais ca c'est juste pour donner un avis, ta méthode fonctionne parfaitement quand meme ;)

A mon avis, ta classe core n'a rien à faire là. Concrètement, elle fait quoi ?
D'apres ce que j'en ai compris, elle permet la relation avec ton moteur de template et instancie la classe user. Pourquoi ne pas mettre le singleton user dans la classe user, et définir une instance de ton moteur de template directement ?

dans user :

public static getInstance () {
if (!isset (self::$_oInstance) || !(self::$_oInstance instanceof self))
self::$_oInstance = new User ();

return self::$_oInstance;
}

Et dans tes pages, tu fait :

$t = new simpleTPL ('./templates');
$u = User::getInstance ();
if ($u->isConnected ())
echo "ok :)";
else
$t->display ('login.phtml');

(grossomodo :p)

Bon d'accord !! j'arrete ! :)
coucou747
Messages postés
12336
Date d'inscription
mardi 10 février 2004
Statut
Modérateur
Dernière intervention
30 juillet 2012
27 -
Source tres interessante, juste quelques petites remarques :
*tu commentes tes fonctions en doxygen, mais pas tes champs, c'est domage, parce-qu'en remplacant // par //!, tu peux ajouter de la doc.
*tu ne fais pas d'auto-loader de classes, ce qui te fait plein d'includes et multiplie les verifications comme : if (!class_exists ('User', true) ) {
*tu devrais mettre plus d'exceptions, la class Exception est normalement une base, on en fait des classes filles pour chaque type de cas, ca facilite l'utilisation du catch
codefalse
Messages postés
1127
Date d'inscription
mardi 8 janvier 2002
Statut
Modérateur
Dernière intervention
21 avril 2009
1 -
Tout à fait d'accord avec Coucou :)
Par ailleur je voulais ajouter un truc avant que j'ai omis :
Regarde du coté de Session_set_save_handler, peut-être connais-tu déjà ? En l'occurence pour ce genre de traitement, ca peut-être intéressant. (http://fr.php.net/manual/fr/function.session-set-save-handler.php)

Dans ma vision des choses (que je devrais faire prochainement vu que c'est dans la roadmap de mon framework :p), je verrai plus la gestion des utilisateurs dans un truc du genre
Une classe mere User (un peu comme la tienne dans les grandes lignes)
Une classe fille SessionUser, une autre classe fille DbUser, etc
Ces classes utiliseront session_set_save_handler pour définir là ou on enregistrera les données (de base, en fichier, en base de donnée, etc).
Il y aura aussi à coté une classe Authentication qui permet l'authentification de l'utilisateur, n'ayant besoin que du login et password et éventuellement des ACL...

Bonne continuation en tout cas :)
malalam
Messages postés
10844
Date d'inscription
lundi 24 février 2003
Statut
Modérateur
Dernière intervention
2 mars 2010
17 -
Hello,

bon à moi :-)
Je ne reviendrai pas sur le fait que ton bin's est intéressant.
Néanmoins, j'ai aussi quelques remarques et incompréhensions. Sur certains points, j'ai peut-être mal compris, ou pas tout vu (j'ai un peu de mal avec la nouvelle page permettant de voir les codes : c'est un peu petit à mon goût!).

Globalement, je trouve ta structure un peu bordélique. Ou je ne l'ai pas comprise, hein, c'est tout à fait possible.
Ta classe Core part d'une bonne idée, mais je la trouve sous exploitée. A mon sens, elle devrait être le véritable coeur de ton projet, et donc agencer le tout. Là, j'ai l'impression qu'elle fait la moitié du boulot.
La classe User : je ne comprends pas pourquoi tu fais appel au getInstance de ta classe DB pour chaque action. Tu passes par une méthode supplémentaire pour tout, alors que si tu l'instanciais dès le départ (vu que ta classe User a quasiment toujours besoin de cette classe dès qu'on l'instancie), tu gagnerais un peu. En sachant que les objets en php5 sont toujours des références, jamais des copies. Donc tu ne doublerais pas ton objet DB de cette manière.
Je ne comprends pas non plus la définition des constantes dans le constructeur. Pourquoi déclarer dans une classe des constantes globales ? Si tu en as besoin au global, sors les. Sinon, crée des constantes de classe.
Le __call() est rigolo, mais je ne vois pas où tu t'en sers. Tu passes directement par setValue(), ce qui me semble plus opportun en effet.
Tu aurais aussi ou te servir de l'extension filters, très intéressante.
J'ai aussi un peu de mal avec ton mIterator qui renvoie true ou false dans son constructeur ? Pourla méthode seek(), t'y es presque ;-)

Sinon c'est du bon travail! il y a des idées très intéressantes là-dedans.
cs_yoman64
Messages postés
593
Date d'inscription
samedi 19 janvier 2002
Statut
Membre
Dernière intervention
4 décembre 2008
-
Salut à tous,

Merci pour les commentaires, je ne connaissais pas session_set_save_handler, ça m'a l'air vachement intéressant et très pratique je vais voir comment j'pourrais adapter ça au code !

La classe core en fait était juste pour regrouper certaines choses et gêrer la construction (mais surtout la destruction) du moteur de template, donc elle est évidement plutot inutile.

Pour le getInstance de la classe Db c'est une bonne idée, ça va éviter des appels inutiles à la méthode sans arrêt :)

Les constantes dans le constructeur c'était juste parce qu'elle sont requise par la classe, elle ne sont pas requises si la classe est pas construite, mais c'est vrai que ça fait plus beau de les sortir.

Le __call je m'en sers pas dans les exemples (en fait si, une fois dans inscription.php: le code sur cette page), je voulais juste qu'il soit disponible parce que je trouvais l'idée intéressante :)

Comme j'ai dit le but de la source était surtout la classe users.class.php, le moteur de template était un test que je fesais, et du coup je me suis dit que ça serait intéressant de l'utiliser pour présenté un exemple de la source. Je vais peut être enlever le core.php suite aux remarques de Codefalse qui sont tout à fait judicieuse, il ne sert pas à grand chose si je rends le User singleton. Mais l'idée de faire une interface pour le template et éventullement le moteur de Db est tout à fait intéressante, ça va ajouter beaucoup à la flexibilité de la source !

Pour les exceptions je crois que tu as raison coucou747, je devrais ajouter une classe fille pour la gestion, mais je ne me sers pas des exceptions depuis très longtemps (enfin je les connais depuis bel lurette, mais c'est juste récement que j'ai vu leurs réel utilitée). Pour doxygen, je ne l'utilise pas. Moi je commente juste selon la syntaxe vu sur d'autres source de ce code lol, mais tu as raison je devrais aussi décrire les champs.

Ah ouais et le constructeur qui renvoit true ou false, c'était pour un test, j'ai oublier de l'enlever avant de poster pfff

Merci à tous, je vais bosser la dessus pour utiliser tous vos commentaires :) Décidément j'en apprends tous les jours ^^

PS: Codefalse: Si je ne génère plus le template avec le destructeur (je comprends ton point de vu, j'y avais même penser pendant un temps), ça veut dire que j'vais devoir ajouté une ligne pour faire le rendu à la fin de chacun de mes codes ? Ou ya p-e une méthode que je connais pas ?

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.