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');
?>
18 avril 2008 à 10:03
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 ! :)
18 avril 2008 à 11:32
*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
18 avril 2008 à 19:40
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.
19 avril 2008 à 13:07
J'ai pas regardé en détails, mais j'ai bien aimé dans l'ensemble. La plupart des remarques que j'avais à faire ont déjà été faites, donc je vais pas en rajouter une couche.
Juste deux petits trucs :
@Malalam : pour la page de codes, tu peux regarder en plein écran... On y voit mieux, c'est moins étriqué.
@Codefalse & Yoman : Pour se passer de la dernière ligne qui génère l'affichage, on peut utiliser la directive de configuration auto_append_file dans un fichier .htaccess
On peut ainsi avoir un petit fichier qui va gérer la fin de l'affichage, fermer ce qu'il y a à fermer, enregistrer ce qu'il y a à enregistrer, tout ça.
Mais comme Codefalse, je préfère garder le contrôle sur ce que j'affiche. Donc en général, j'ai dans chaque script, une ligne pour l'affichage de l'entête de ma page (jusqu'à la balise body et le premier div du contenu de ma page), et un pour le pied de page (en général qui comprend, outre la fermeture du premier div ouvert, le copyright, les liens vers la charte, mentions CNIL, tout ça, et la fermeture du document html). Plus quelques lignes pour l'affichage du document en lui-même.
J'ai donc 2 lignes qui reviennent toujours : parce que des fois, je n'affiche rien via mon template (pas de html : redirection, image à la volée, etc).
19 avril 2008 à 13:21
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.