Sahid Ferdjaoui Blog - Funraill Foundation Bienvenue, Log in - thème 2007 RC1

Powered by OpenSource Softwares

Outil de déboggage colaborative
reduire

Récuperer ses contacts MSN, Gmail, Yahoo avec PHP

le 4 décembre 2007 par sahid

Classe PHP pour vos contacts MSN, Gmail Yahoo…

Pour les besoins d’un projet au boulot, j’ai du faire quelques recherches afin de trouver comment récupérer les contacts des boites msn, yahoo, gmail, et autres… le problème est que sur le net on trouve de nombreux Web service proposant ces fonctionnalités mais tres peu de librairies libres …

Apres de multiples recherches je suis tombé sur plusieurs classes intéressantes, et j’ai donc pensé les rassembler pour en faire un petit paquetage simple d’emploi

Présentation de la classe Contacts

En utilisant le pattern decorator et une petite factory je suis arrivé à faire en sorte de simplifier un maximum son utilisation

Un exemple du decorator avec Gmail

  1. class GmailDecorator
  2. {
  3.   private $_instance;
  4.   private $_user;
  5.   private $_pass;
  6.  
  7.   public function __construct ($user, $pass)
  8.   {
  9.     require (‘libs/importGmail.class.php’);
  10.     $this->_instance = new GMailer;
  11.     $this->_user = $user;
  12.     $this->_pass = $pass;
  13.   }
  14.  
  15.   public function getContacts ()
  16.   {
  17.     $result = array ();
  18.     if (!is_object ($this->_instance))
  19.       throw new Exception (“Aucune instance GMailer”);
  20.     $this->_instance->setLoginInfo ($this->_user, $this->_pass, “+1GMT”);
  21.     if ($this->_instance->connect ())
  22.       {
  23.         $this->_instance->fetchBox (GM_CONTACT, ‘all’, );
  24.         $snapshot = $this->_instance->getSnapshot (GM_CONTACT);
  25.         $this->_instance->disconnect ();
  26.         $i = 0;
  27.         if (isset ($snapshot->contacts))
  28.           foreach ($snapshot->contacts as $contact)
  29.             {
  30.               $result[$i][‘name’] = $contact[‘name’];
  31.               $result[$i][‘email’] = $contact[‘email’];
  32.               $i++;
  33.             }
  34.         return $result;
  35.       }
  36.     else
  37.       throw new Exception (‘Impossible de se connecter’);
  38.   }
  39. }
  40.  
  41. class YahooDecorator {}
  42. class MSNDecorator {}
  43. # etc …
  44.  

Ensuite la Factory s’occupe de nous retourner l’objet en fonction du type qu’on lui passe en paramètre

  1. class Contacts
  2. {
  3.   public static $arr_type = array (‘Gmail’, ‘MSN’, ‘Yahoo’, ‘Lycos’, ‘AOL’);
  4.  
  5.   public static function factory ($user, $pass, $type)
  6.   {
  7.     if (in_array ($type, self::$arr_type))
  8.       {
  9.         $class = “{$type}Decorator”;
  10.         return new $class ($user, $pass);
  11.       }
  12.     else throw new Exception (‘Invalide type, utilisez : ‘.implode (“, “, self::$arr_type));
  13.   }
  14. }

Etat du paquetage Contacts (MAJ : 27/08/08)

   Gmail Retourne un tableau vide
   Yahoo! Teste réussi avec @yahoo.fr
   AOL Teste réussi avec @aol.com
   Lycos Teste réussi avec @lycos.com
   MSN Teste réussi avec @hotmail.fr @hotmail.com

NOTE : Gmail, AOL, Yahoo, et Lycos, n’ont pas besoin du suffixe @host.com

Un petit exemple

reduire

Support des espaces de noms en PHP

le 27 novembre 2007 par sahid

PHP 5.3, NameSpaces

Voila une très bonne chose, j’en avais déjà entendu parlé mais il me semblait que c’était pour la version 6 de PHP, toujours est il que c’était véritablement un manque pour les développeurs PHP.

Donc à partir de la version 5.3 on devrait retrouver le support des espaces de noms pour les fonctions, les classes, ainsi que les constantes. l’interet est assez important pour un langage comme le PHP et son nombre incroyable de bibliothèques.

Vous pouvez jeter un oeil sur la partie de la doc qui traite de se sujet
http://fr.php.net/manual/fr/language.namespaces.php

Via l’utilisation d’accesseurs

  1. <?php
  2.     require ‘MyProject/Db/Connection.php’;
  3.     use MyProject::DB;
  4.     use MyProject::DB::Connection as DbConnection;
  5.    
  6.     $x = new MyProject::DB::Connection();
  7.     $y = new DB::connection();
  8.     $z = new DbConnection();
  9.     DB::connect();
  10. ?>

Définition dans tout le script

  1. <?php
  2.     namespace A::B::C;
  3.  
  4.  /* This function is A::B::C::fopen */
  5.     function fopen() {
  6.          /* … */
  7.          $f = ::fopen(); // call global fopen
  8.          return $f;
  9.     }
  10. ?>
reduire

Hebergement pour développeurs

le 24 novembre 2007 par sahid

HostingRails.com, le meilleur hebergeur GNU/Linux

En debut d’apres-midi le blog était légèrement indisponible, j’etais en train de le migrer sur mon nouvel hebergeur, j’en ai profité pour passer à la version 2.3 de wordpress.

Un billet publicitaire …mais il le faut !

En pleine recherche pour trouver un nouvel hebergeur, ayant un peu trop de problemes avec 1and1 et leur “jemenfoustisme” envers leurs clients, je suis tombé sur HostingRails.com, et vraiment ils offrent le meilleur rapport qualité/prix que je n’ai jamais vu.

J’avais envie de trouver un hebergement qui offre accès à une base de données PostgreSQL ainsi que SSH sans avoir à passer par un serveur dedié ou semi-dedié, un peu trop couteux pour mes besoins.

La petite histoire …

Si j’ai bien compris cette offre d’hebergement est issue de deux developpeurs passionnés de Ruby qui ont eu envie d’offrir un hebergement mutualisé de haute qualité afin de promouvoir Ruby On Rails

Les developpeurs d’autres languages de programmation ne seront pas en reste car l’offre propose Python, PHP, Perl, en plus de Ruby, ainsi que les serveurs Apache2 et LightHTTP (plus d’infos…), ainsi qu’un accès SVN…

Merci à l’Euro fort … :)

Le truc pas mal si vous decidez d’opter pour cette offre, est le taux de change de l’euro qui est bien plus fort que celui du dollar… et mon hebergement de 2 années pour un peu moins de 70$ m’est revenu à environ 47euros !.

reduire

Un Singleton multi instances…

le 22 septembre 2007 par sahid

Modifier le fonctionnement de son Singleton

Je reviens sur le pattern Singleton, car actuellement je travaille sur un projet perso et celui-ci m’a posé un probleme…
Dans mon cas précis, je me sers du Singleton pour gerer une classe de Log. On pourrait penser que le Singleton se prete parfaitement a ce type de fonctionnalité, seulement je me suis retrouvé face à un probleme qui est en fait une des grandes forces du Singleton, l’initialisation unique …

Je m’explique, dans mon cas j’ai besoin de pouvoir travailler avec de multiples fichiers log, si le nom du fichier est passé en parametre du constructeur, je ne pourrais travailler qu’avec celui-ci, et pour ecrire sur un nouveau fichier je devrais passer par un accesseur qui modifierait l’attribut…, ou encore je devrais passer à ma methode permettant l’ecriture du log, le nom du fichier…

  1. <?php
  2. // via le constructeur
  3. $o = Log::singleton (‘file.log’);
  4. $o->log (“Une chaine inscrite dans le fichier ‘file.log’”);
  5. $o->setFileLog (‘file2.log’);
  6. $o->log (“Une chaine inscrite dans le fichier ‘file2.log’”);
  7.  
  8. // via la methode log
  9. $o = Log::singleton ();
  10. $o->log (‘file.log’, “Une chaine inscrite dans le fichier ‘file.log’”);
  11. ?>

Ces deux methodes ne me plaisent pas particulierement, pour résoudre le probleme l’idée est de modifier le Singleton pour qu’il enregistre non pas une, mais de multiples instances de notre classe.

  1. $o = Log::singleton (‘key_file’, ‘file.log’);
  2. $o->log (“une chaine… dans ‘file.log’”);
  3.  
  4. $o = Log::singleton (‘key_file2′, ‘file2.log’);
  5. $o->log (“une chaine… dans ‘file2.log’”);

Donc si l’instance de la classe n’est pas déjà créée, il en crée une nouvelle,l’enregistre dans un tableau et la retourne, si celle-ci est dejà créée il la retourne simplement.

  1. class SingletonMulti
  2. {
  3.   /**
  4.    * array with all instances
  5.    */
  6.   private static $_instances = array ();
  7.  
  8.   /**
  9.    * all arguments …
  10.    */
  11.   private $args;
  12.  
  13.   public static singleton ($key, $args = “null”)
  14.   {
  15.     if (!array_key_exists ($key, self::$_instances))
  16.       self::$_instances[$key] = new SinletonMulti ($args);
  17.     return self::$_instances[$key];
  18.   }
  19.  
  20.   private __construct ($args)
  21.   {
  22.     $this->args = $args;
  23.   }   
  24. }

On sort peut être un peu du principe du Singleton, néanmoins l’esprit et les avantages y sont toujours (;

reduire

HTTPRequest, Gestion des requêtes en PHP

le 12 août 2007 par sahid

Une classe PHP5 pour gérer les requêtes passées à notre application

Une classe outil qui peut être réutilisée et complétée pour gérer les requêtes POST et GET passées à votre application.

Fonctionnement de la classe HttpRequest

La classe est assez simple et plutÃŽt utile, elle est complÚtement réutilisable (cela me fait penser que PHP6 et l’arrivée des espaces de nom (namespaces) sera une trÚs bonne nouvelle pour la communauté PHP. Car le manque de cette fonctionnalité commence réellement à se faire sentir avec les multiples classes et frameworks qui voient le jour !), utilisée via un frontController elle permet d’intercepter les requêtes passées à l’application sous toutes ses couches et les nettoie en fonction du type à retourner.

Exemple d’utilisation

  1. <?php
  2.          $request = new HttpRequest;
  3.  
  4.          # RécupÚre la valeur d’un "module" alphabétique
  5.    $module = $request->getAlpha (‘module’);
  6.  
  7.    # RécupÚre les valeurs d’un formulaire
  8.          $nom = $request->getAlpha (‘nom’); // alphabétique
  9.          $mdp = $request->getAlnum (‘mdp’); // alphanumérique
  10.          $mnt = $request->getFloat (‘mnt’); // flottantes (ex : un montant)
  11.         
  12.          $usr_id = $request->getInt (‘usr_id’); // entier
  13.  
  14.          # RécupÚre les valeurs, sans les échapper (__get)
  15.          $mix = $request->mixedParam ();
  16. // HttpResquest, Gestion des requêtes en PHP
  17.    # Ajoute un nouveau paramÚtre (__set)
  18.    $request->newParam = “Hello World”;  
  19. ?>

A voir…

Au niveau du constructeur de la classe, j’utilise un array_merge pour récupérer les tableaux GET et POST, mais peut être que placer un paramÚtre au constructeur permettrait une meilleure souplesse de la classe.

  1. <?php
  2. class HttpRequest_2 {
  3.          private $_request;
  4.  
  5.          public function __construct ($array) {
  6.            $this->_request = $array;
  7.    }
  8.    // …
  9. }

Ainsi on peut choisir quels sont les types de variable qu’on souhaite récupérer…

  1. <?php
  2. # POST
  3. $request = new HttpRequest ($_POST);
  4.  
  5. # GET
  6. $request = new HttpRequest ($_GET);
  7.  
  8. # POST et GET
  9. $request = new HttpRequest (array_merge ($_POST, $_GET));
  10.  
  11. # POST, GET, COOKIE
  12. $request = new HttpRequest ($_REQUEST);
  13.  
  14. # ou toute autre variante …
  15. ?>

La classe HttpRequest complete

  1. <?php
  2.  
  3.         /**
  4.          * Ferdjaoui Sahid <sahid@funraill.org>
  5.          * http://sahid.funraill.org
  6.          *
  7.          * @copyright Copyright (c) 2007 Ferdjaoui Sahid
  8.          */
  9.  
  10. /**
  11. * HttpRequest, Gestion des requêtes passées à l’application
  12. *
  13. * @category HTTP
  14. * @package  HttpRequest
  15. */
  16. class HttpRequest
  17. {
  18.         private $_request;
  19.  
  20.         /**
  21.          */
  22.         public function __construct ()
  23.         {
  24.                 $this->_request = array_merge ($_POST, $_GET);
  25.         }
  26.  
  27.         /**
  28.          * Retourne la valeur d’un paramÚtre passé à l’appli
  29.          *
  30.          * @param mixed $key
  31.          * @return mixed
  32.          */
  33.         public function get ($key)
  34.         {
  35.                 return array_key_exists ($key, $this->_request)
  36.                         ? $this->_request[$key] : false;
  37.         }
  38.  
  39.         /**
  40.          * Ajoute un nouveau paramÚtre
  41.          *
  42.          * @param mixed $key
  43.          * @param mixed $val
  44.          */
  45.         public function set ($key, $val)
  46.         {
  47.                 $this->_request[$key] = $val;
  48.         }
  49.  
  50.         /**
  51.          * Mapping des méthodes get et set via l’utilisation de __get et __set
  52.          */
  53.         public function __get ($key) { return $this->get ($key); }
  54.         public function __set ($key, $val) { $this->set ($key, $val); }
  55.  
  56.         /**
  57.          * Retourne une chaîne de caractÚres alphabétiques
  58.          *
  59.          * @param mixed $key
  60.          * @return string
  61.          */
  62.         public function getAlpha ($key)
  63.         {
  64.                 return preg_replace (‘/[^[:alpha:]]/’, , $this->get ($key));
  65.         }
  66.  
  67.         /**
  68.          * Retourne une chaîne de caractÚres alphanumériques
  69.          *
  70.          * @param mixed $key
  71.          * @return string
  72.          */
  73.         public function getAlnum ($key)
  74.         {
  75.                 return preg_replace (‘/[^[:alnum:]]/’, , $this->get ($key));
  76.         }
  77.  
  78.         /**
  79.          * Retourne et convertit une chaîne en nombre à virgule flottante
  80.          *
  81.          * @param mixed $key
  82.          * @return integer
  83.          */
  84.         public function getInt ($key)
  85.         {
  86.                 return intval ($this->get ($key));
  87.         }
  88.  
  89.         /**
  90.          * Retourne une valeur à virgule flottante
  91.          *
  92.          * @param mixed $key
  93.          * @return float
  94.          */
  95.         public function getFloat ($key)
  96.         {
  97.                 return floatval ($this->get ($key));
  98.         }
  99.  
  100.         /**
  101.          * Retourne le nom du dossier qui contient le fichier ou dossier
  102.          *
  103.          * @param mixed $key
  104.          * @return mixed
  105.          */
  106.         public function getDir ($key)
  107.         {
  108.                 return dirname ($this->get ($key));
  109.         }
  110.  
  111.         /**
  112.          * Retourne le chemin canonique absolu
  113.          *
  114.          * @param mixed $key
  115.          * @return mixed
  116.          */
  117.         public function getPath ($key)
  118.         {
  119.                 return realpath ($this->get ($key));
  120.         }
  121.  
  122.         /**
  123.          * Retourne le tableur Requête
  124.          */
  125.         public function getRequest () { return $this->_request; }
  126. }
reduire

Gestion des utilisateurs en PHP5 via l’utilisation de patterns

le 18 juillet 2007 par sahid

Concepts objets pour gérer ses utilisateurs via Singleton et Factory PHP

Ca faisait un petit moment que je ne rédigeais plus trop d’articles sur PHP, il est vrai que Python me prend pas mal de temps ces jours-ci, alors j’ai décidé de sortir mon Apache et ma DB préférée du sommeil pour voir un peu comment gérer dans une application ses utilisateurs. Bon comme d’habitude, je préviens, tout ça est le mix dans mon cerveau de nombreuses documentations ainsi que d’expériences personnelles, donc il se peut que la méthode que je vais présenter comprenne des erreurs et peut sans doute être améliorée.

Pour moi la grande force de PHP5 est sa partie objet, qui même si elle n’est pas encore parfaite, nous permet de travailler avec de nombreux design patterns (motif de conception) plutÃŽt intéressants. Dans un précédent article j’ai essayé de démontrer l’utilité des registres pour la conservation
et le transfert d’objet dans toutes les couches d’une application, ce soir je vais présenter le bien connu Singleton ainsi que l’excellente Factory.

Gestion des utilisateurs

Dans notre application, un utilisateur enregistré pourra soit être administrateur soit être invité. Un invité est un utilisateur de base, il a le droit en lecteur seul. Un administrateur lui, a le droit de lecture, écriture, modification. L’application va donc se découper en deux parties, la premiÚre sera la gestion des utilisateurs via le pattern Factory, la seconde sera la gestion de la base de donnée via le pattern Singleton.

Concept du Singleton

Le Singleton, est un des motifs de conception les plus connus, et un des plus pratiques. Il a sa place dans toutes sortes de classes. Il permet d’instancier une seule fois la classe ainsi dans toutes les couches de notre application on retrouvera la même instance. Pour ça, il utilise un constructeur privé qui sera appelé par une méthode public souvent nommée par convention “getInstance” celle-ci va mettre en attribut l’instance retournée par le constructeur, ainsi au nouvel appel de “getInstance” si notre objet a déjà été créée il le retourne, sinon il le créée. Le principe est assez simple ou plutÃŽt ingénieux ! seulement j’explique pas trÚs bien (; …un bout de code devrait nous éclairer.

  1. class unSingleton
  2. {
  3.   private static $_instance;
  4.   public static getInstance ()
  5.   {
  6.     if (is_null (self::$_instance)) {
  7.       self::$_instance = new unSingleton ();
  8.     }
  9.   }
  10.   private function __construct () {}

Concept de la Factory

Donc la Factory …ce pattern sert d’intermédiaire, son but est de retourner à notre application un objet du type qu’on souhaite. Pour ça, on lui passe en paramÚtre un ou plusieurs arguments, et via la définition de classe “modÚle” elle retournera l’objet adéquat. Cette fois-ci je vais plutÃŽt vous rediriger ver wikipedia, car ce pattern demande un peu plus de code, et on va l’utiliser pour gérer les utilisateurs.

Table utilisateur

Voila la table chargée de stocker les utilisateurs en base de données

  1. CREATE TABLE users (
  2.   id serial,
  3.   username varchar (40),
  4.   password varchar (40),
  5.   usrlevel bool,
  6. PRIMARY KEY (id)
  7. );

Les utilisateurs

Pour la gestion des utilisateurs, nous allons donc utiliser une Factory, dans un premier temps on définit la classe abstraite qui servira de modÚle aux autres classes, qui dériverons d’elle.

La classe User

  1. /**
  2. * ModÚle Utilisateur
  3. */
  4. abstract class User
  5. {
  6.         private $_username;
  7.         private $_password;
  8.         private $_usrlevel;
  9.        
  10.         public function __construct ($usr, $pwd, $lvl)
  11.         {
  12.                 $this->_username = $usr;
  13.                $this->_password = $pwd;
  14.                 $this->_usrlevel = $lvl;
  15.         }
  16.  
  17.         public function canRead () { return true; }
  18.         public function canWrite () { return false; }
  19.         public function canModify () { return false; }
  20.  
  21.         public function getUsername () { return $this->_username; }
  22.         public function getPassword () { return $this->_password; }
  23.         public function getUsrlevel () { return $this->_usrlevel; }
  24. }

Maintenant ses dérivés

  1. /**
  2. * Invité
  3. */
  4. class GuestUser extends User {}
  5.  
  6. /**
  7. * Administrateur
  8. */
  9. class AdminUser extends User
  10. {
  11.         public function canRead () { return true; }
  12.         public function canWrite () { return true; }
  13.         public function canModify () { return true; }
  14. }

Nous disposons maintenant de tous les éléments nécessaires pour créer notre Factory.

  1. /**
  2. * Retourne un objet de type User
  3. * en fonction de son niveau
  4. */
  5. class UserFactory
  6. {
  7.         public static function getUserFactory ($usr, $pwd, $lvl)
  8.         {
  9.                 if ($lvl == 0)
  10.                         return new AdminUser ($usr, $pwd, $lvl);
  11.                 if ($lvl == 1)
  12.                         return new GuestUser ($usr, $pwd, $lvl);
  13.         }
  14. }

Donc, en fonction d’un identifiant, d’un mot de passe ainsi que d’un niveau d’autorisation, notre Factory nous retournera un objet GuestUser, ou un objet AdminUser.

Nous allons à présent définir notre classe qui fera l’intéraction avec la base de données en utilisant le pattern Singleton. Celle-ci devra être capable d’enregistrer un utilisateur, ainsi que de retourner un utilisateur déjà enregistré. Pour l’enregistrement nous utiliserons la méthode “addUser” qui demandera en paramÚtre un objet de type User, ensuite pour la restauration d’un utilisateur, nous utiliserons la méthode “getUser” qui demandera en paramÚtre un identifiant ainsi qu’un mot de passe, celle-ci retournera grâce à notre Factory un objet de type User, soit Admin soit Invité.

  1. /**
  2. * Gestion des utilisateurs avec la db
  3. */
  4. class UserAuthSingleton
  5. {
  6.         private static $_instance;
  7.        
  8.         private $_dbh;
  9.         private $_tbl;
  10.        
  11.         /**
  12.          * Retourne une l’instance de la classe */
  13.         public static function getInstance ()
  14.         {
  15.                 if (is_null (self::$_instance)) {
  16.                         self::$_instance = new UserAuthSingleton ();
  17.                 }
  18.                 return self::$_instance;
  19.         }
  20.  
  21.         /**
  22.          * Constructeur. */
  23.         private function __construct ()
  24.         {
  25.                 $this->_dbh = new PDO (‘pgsql:host=localhost;dbname=users_db’, ’sahid’, ‘test’);
  26.                 $this->_dbh->setAttribute (PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  27.                 $this->_tbl = “users”;
  28.         }
  29.  
  30.         /**
  31.          * Ajoute un utilisateur. */
  32.         public function addUser (User $u)
  33.         {
  34.                 if ($this->userExist ($u->getUsername ())) {
  35.                                 throw new Exception (“Le nom d’utilisateur exist déjà “);
  36.                 }
  37.                 else {
  38.                         $sql =
  39.                                insert into {$this->_tbl} (username, password, usrlevel)
  40.                                values (:usr, :pwd, :lvl);”;
  41.  
  42.                         $stmt = $this->_dbh->prepare ($sql);
  43.                         $stmt->execute (array (“:usr” => $u->getUsername (),
  44.                                                           “:pwd” => $u->getPassword (),
  45.                                                           “:lvl” => $u->getUsrlevel ()));
  46.                 }
  47.         }
  48.  
  49.         /**
  50.          * Retourne un utilisateur. */
  51.         public function getUser ($usr, $pwd)
  52.         {
  53.                 $sql =
  54.                         select username, password, usrlevel
  55.                         from {$this->_tbl}
  56.                         where username = :usr and password = :pwd;”;
  57.  
  58.                         $stmt = $this->_dbh->prepare ($sql);
  59.                         $stmt->bindParam (“:usr”, $usr);
  60.                         $stmt->bindParam (“:pwd”, sha1 ($pwd));
  61.                         $stmt->execute ();
  62.  
  63.                 // Retourne un objet User en fonction du level
  64.                 if ($stmt->rowCount () == 1) {
  65.                         $row = $stmt->fetchAll ();
  66.                         $user = UserFactory::getUser ($row[0][‘username’],
  67.                                                                     $row[0][‘password’],
  68.                                                                     $row[0][‘usrlevel’]);
  69.                         return $user;
  70.                 }
  71.                 else
  72.                         return false;
  73.         }
  74.  
  75.         public function userExist ($usr)
  76.         {
  77.                 $sql =
  78.                         select username, password
  79.                         from {$this->_tbl}
  80.                         where username = :usr”;
  81.  
  82.                 $stmt = $this->_dbh->prepare ($sql);
  83.                 $stmt->bindParam (“:usr”, $usr);
  84.                 $stmt->execute ();
  85.  
  86.                 if ($stmt->rowCount () > 0)
  87.                         return true;
  88.                 else
  89.                         return false;
  90.         }
  91. }

Testons tout ça

Création d’un nouvel utilisateur

  1. $user = UserFactory::getUserFactory (“sahid”, sha1 (“foobar”), 0);
  2.  
  3. try {
  4.         UserAuthSingleton::getInstance ()->addUser ($user);
  5. }
  6. catch (Exception $e) {
  7.         echo $e->getMessage ();
  8. }

Récupération d’un utilisateur

  1. $user = UserAuthSingleton::getInstance ()->getUser (“sahid”, “foobar”);
  2. if ($user instanceof AdminUser)
  3.   echo $user->getUsername ().“est admin !”;
  4. if ($user instanceof GuestUser)
  5.   echo $user->getUsername ().“est invité !”;

En conclusion…

Voila comment peuvent être géré des utilisateurs avec un concept objet bien sur il peut y avoir bien plus de niveaux d’autorisation pour nos utilisateurs, et ceux-ci peuvent disposer de bien plus de propriétés, ensuite cette implémentation peut etre sans doute améliorée, le plus important étant la séparation des données.

reduire

Pattern, Service Locator ou Registry en PHP

le 19 mars 2007 par sahid

Le modÚle de conception Service Locator / Registry mis en situation dans un MVC

Introduction

Le Service Locator, est un pattern permettant la sauvegarde et la restitution d’objets, pour cela, il utilise un tableau par lequel il garde en memoire les objets. Dans une application utilisant le motif MVC, l’utilisation de registre apparait comme une bonne methode sachant que l’application est centrée sur un seul fichier, “index.php”.

Avant d’expliquer comment le mettre en oeuvre, on va d’abord le mettre en situation dans un cas concret.
Notre application est concue sur un modele MVC et tourne autour du fichier index.php.

Aborescence de notre application :

  • /app/controllers
  • /app/models
  • /app/views
  • /index.php

index.php

  1. <?php
  2. // charge le MVC
  3. require_once (“app/MVC.php”);
  4. // pattern Service Locator
  5. require_once (“app/ServiceLocator.php”);
  6.  
  7. try {
  8.         // Initialise le FC
  9.         $fc = new FrontController (“/app/controllers/”);
  10.        
  11.         // Initialisation du modele i18n
  12.         require_once (“/app/models/I18n.php”);
  13.         $i18n = new I18n (“fr_FR”, “i18n/”);
  14.        
  15.         // Sauvegarde du modele en registre
  16.         ServiceLocator::register (“i18n”, $i18n); //!\
  17.        
  18.         // Demarre l’appli
  19.         $fc->dispatch (new HttpRequest (), new View (“/app/views/”));
  20. } catch (Exception $e) {
  21.         echo $e->getMessage ();
  22.         die ();
  23. }
  24. ?>

On peut s’apercevoir que dans le fichier index.php on crée l’instance de notre modele I18n. Ensuite par l’intermediaire de ServiceLocator, on le place en registre.

Le controlleur : IndexAction.php

  1. <?php
  2. class IndexAction extends Controller
  3. {
  4.         public function doAction (HttpRequest $request, View $view) {
  5.                 try
  6.                 {
  7.                         // Recupere l’objet i18n enregistre en registre (:
  8.                         $i18n = ServiceLocator::registry (“i18n”);      //!\
  9.                        
  10.                         $i18n->setLangue (“en_US”);
  11.                         $view->bonjour = $i18n->__(‘bonjour_le_monde’);
  12.                         echo $view->render (“default.tpl.php”);
  13.                        
  14.                 } catch (Exception $e) {
  15.                         echo $e->getMessage ();
  16.                         die ();
  17.                 }
  18.         }
  19. }
  20. ?>

Maintenant on récupere notre objet afin de l’utiliser dans notre controlleur IndexAction.php. On remarque que notre application dispose d’une seule occurence I18n pouvant etre utilisée dans tout les controlleurs.

La classe Service Locator

Rien de compliqué dans cette classe, on se sert simplement de methodes et attributs statiques, le tout est de bien faire attention à eviter les doublons, et retourner les bons messages d’erreur en cas d’une mauvaise utilisation de celui-ci.

  1. <?php
  2. class ServiceLocator
  3. {
  4.         static private $_registry = array ();
  5.  
  6.         /**
  7.          * Enregistre un objet dans le registre
  8.          *
  9.          * @param string $key
  10.          * @param objet $obj
  11.          */
  12.         static public function register ($key, $obj)
  13.         {
  14.                 // Verifie les doublons de clefs
  15.                 if (array_key_exists ($key, self::$_registry)) {
  16.                         throw new Exception (“La clef {$key} est deja enregisté.”);
  17.                 }
  18.                
  19.               &nb