begin process at 2012 02 15 13:39:59
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Astuces

 > [PHP5] OBSERVER DESIGN PATTERN

[PHP5] OBSERVER DESIGN PATTERN


 Information sur la source

Note :
9,5 / 10 - par 2 personnes
9,50 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Astuces Classé sous :design, pattern, observer, évènement, events Niveau :Expert Date de création :16/07/2007 Date de mise à jour :17/07/2007 11:03:00 Vu / téléchargé :9 117 / 248

Auteur : malalam

Ecrire un message privé
Site perso
Commentaire sur cette source (9)
Ajouter un commentaire et/ou une note

 Description

Suite à cette source :
http://www.phpcs.com/codes/PROGRAMMATION-EVENEME NTIELLE-PHP_41477.aspx
que j'ai trouvée très intéressante, j'ai poussé un peu les recherches.
J'ai appliqué l'observer design pattern (une recherche sur google vous en expliquera les tenants et les aboutissants) afin d'obtenir un package simple et facile à mettre en oeuvre permettant d'exécuter en cascade toute une série de traitements lors du déclenchement d'un évènement (côté serveur, on parle ici de programmation évènementielle côté serveur).

Il y a 2 fichiers, un pour les versions de PHP5 >= 5.1 (redéfinissant quand même certaines classes SPL au cas où), et une pour PHP5 < 5.1.
Les différences résident dans le typage forcé de l'appel de certaines méthodes, et dans l'ajout d'une petite exception dans la méthode SplSubject::notify().
J'ai aussi dans les deux versions modifié la méthode SplObjectStorage::rewind(), simplement parce sur PHp5.0.4 ça ne passait pas. Bref...vous rentrerez dans les détails si vous le voulez.

Le principe :
on a des observateurs, et un sujet observé. On lie au sujet observé des observateurs via un collecteur d'objets (ça, c'est pour facilité la mise ne place) : SplObjecStorage.
A chaque changement d'état important, les observateurs liés sont alertés via un appel à SplSubject::notify().
Ils réagissent en fonction de ce qu'ils doivent faire, simplement.

J'ai repris l'analogie de la voiture et du dépassement de la vitesse autorisée.
L'avantage ici est de pouvoir déclencher autant de traitements qu'on le veut sur 1 seul changement d'état. CX'est un peu le principe des triggers en SQL.


Source

  • <?php
  • /**
  • * defining abstract implementations
  • */
  • if (!interface_exists ('Countable')) {
  • /**
  • * Interface Countable
  • * @author: php
  • *
  • */
  • interface Countable {
  • public function count();
  • }
  • }
  • if (!interface_exists ('SplObserver')) {
  • /**
  • * Interface SplObserver
  • * @author: php
  • *
  • */
  • interface SplObserver {
  • public function update(SplSubject $subject);
  • }
  • }
  • if (!interface_exists ('SplSubject')) {
  • /**
  • * Interface SplSubject
  • * @author: php
  • *
  • */
  • interface SplSubject {
  • public function attach(SplObserver $observer);
  • public function detach(SplObserver $observer);
  • public function notify();
  • }
  • }
  • if (!class_exists ('SplObjectStorage')) {
  • /**
  • * Interface SplObjectStorage
  • * @author: php
  • *
  • */
  • class SplObjectStorage implements Iterator, Countable {
  • /**
  • * Array of objects
  • *
  • * @var array
  • */
  • private $storage = array();
  • /**
  • * Array of objects index
  • *
  • * @var int
  • */
  • private $index = 0;
  • /**
  • * public function rewind
  • * Rewind array pointer
  • *
  • * @Return void
  • */
  • public function rewind() {
  • rewind($this->storage);
  • }
  • /**
  • * public function valid
  • * Checks if current loop iteration is valid
  • *
  • * @Return boolean
  • */
  • public function valid() {
  • return key($this->storage) !== false;
  • }
  • /**
  • * public function key
  • * Returns current key
  • *
  • * @Return int
  • */
  • public function key() {
  • return $this->index;
  • }
  • /**
  • * public function current
  • * Returns current array entry
  • *
  • * @Return object
  • */
  • public function current() {
  • return current($this->storage);
  • }
  • /**
  • * public function next
  • * Iterates to the next entry
  • *
  • * @Return void
  • */
  • public public function next() {
  • next($this->storage);
  • $this->index++;
  • }
  • /**
  • * public function count
  • * Returns the number of entries in the array of objects
  • *
  • * @Return int
  • */
  • public function count() {
  • return count($this->storage);
  • }
  • /**
  • * public function contains
  • * Checks if an object is in the collector array
  • *
  • * @Param object $obj : object to check
  • * @Return boolean
  • */
  • public function contains($obj) {
  • if (is_object($obj)) {
  • foreach($this->storage as $object) {
  • if ($object === $obj) {
  • return true;
  • }
  • }
  • }
  • return false;
  • }
  • /**
  • * public function attach
  • * Attaches an object to the collector array
  • *
  • * @Param object $obj : object to attach
  • * @Return void
  • */
  • public function attach($obj) {
  • if (is_object($obj) && !$this->contains($obj)) {
  • $this->storage[] = $obj;
  • }
  • }
  • /**
  • * public function detach
  • * Detaches an object to the collector array
  • *
  • * @Param object $obj : object to detach
  • * @Return void
  • */
  • public function detach($obj) {
  • if (is_object($obj)) {
  • foreach($this->storage as $idx => $object) {
  • if ($object === $obj) {
  • unset($this->storage[$idx]);
  • $this->rewind();
  • return;
  • }
  • }
  • }
  • }
  • }
  • }
  • /**
  • * starting concrete implementations
  • */
  • /**
  • * class car implements SplSubject
  • * @author: Johan Barbier <johan.barbier@gmail.com>
  • *
  • */
  • class car implements SplSubject {
  • /**
  • * Name of the car
  • *
  • * @var string
  • */
  • private $sName;
  • /**
  • * State of the car
  • *
  • * @var int
  • */
  • private $iState = 0;
  • /**
  • * Speed of the car
  • *
  • * @var int
  • */
  • private $iSpeed = 0;
  • /**
  • * Collector array of observers
  • *
  • * @var SplObserver
  • */
  • private $aObservers;
  • /**
  • * public function __construct
  • * constructor
  • * Initializes car's nname
  • *
  • * @param string $sName
  • */
  • public function __construct ($sName) {
  • $this -> sName = $sName;
  • $this -> aObservers = new SplObjectStorage;
  • }
  • /**
  • * public function start
  • * Starts the car and notify observers
  • *
  • * @Return void
  • */
  • public function start () {
  • $this -> iState = 1;
  • $this -> notify();
  • }
  • /**
  • * public function stop
  • * Stops the car and notify observers
  • *
  • * @Return void
  • */
  • public function stop () {
  • $this -> iState = 0;
  • $this -> iSpeed = 0;
  • $this -> notify();
  • }
  • /**
  • * public function accelerate
  • * Accelerates the car and notify the observers
  • *
  • * @Param int $iAcceleration : how many Kmh you want to accelerate
  • * @Return void
  • */
  • public function accelerate ($iAcceleration) {
  • if (0 === $this -> iState) {
  • throw new Exception ('You must start the car before accelerating...');
  • }
  • if (!is_int ($iAcceleration) || $iAcceleration < 0) {
  • throw new Exception ('Wrong value for car::accelerate()');
  • }
  • $this -> iSpeed += $iAcceleration;
  • $this -> notify();
  • }
  • /**
  • * public function attach
  • * Attaches an observer
  • *
  • * @Param SplObserver $observer : the observer to attach
  • * @Return boolean
  • */
  • public function attach(SplObserver $observer) {
  • if(!$this->aObservers->contains($observer)) {
  • $this->aObservers->attach($observer);
  • }
  • return true;
  • }
  • /**
  • * public function detach
  • * Detaches an observer
  • *
  • * @Param SplObserver $observer : the observer to detach
  • * @Return boolean
  • */
  • public function detach(SplObserver $observer) {
  • if(!$this->aObservers->contains($observer)) {
  • return false;
  • }
  • $this->aObservers->detach($observer);
  • return true;
  • }
  • /**
  • * public function notify
  • * Notify all the observers
  • *
  • * @Return void
  • */
  • public function notify() {
  • foreach($this->aObservers as $observer) {
  • $observer->update($this);
  • }
  • }
  • /**
  • * public function __get
  • * Get properties value
  • *
  • * @Param string $sProp : property's name
  • * @Return mixed
  • */
  • public function __get ($sProp) {
  • switch ($sProp) {
  • case 'STATE' :
  • return $this -> iState;
  • break;
  • case 'SPEED' :
  • return $this -> iSpeed;
  • break;
  • case 'NAME' :
  • return $this -> sName;
  • break;
  • default :
  • throw new Exception ($sProp.' cannot be read');
  • }
  • }
  • /**
  • * public function __set
  • * Set properties value
  • *
  • * @Param string $sProp : property's name
  • * @Param mixed $mVal : property's value
  • * @Return void
  • */
  • public function __set ($sProp, $mVal) {
  • throw new Exception ($sProp.' cannot be set');
  • }
  • }
  • /**
  • * class carStateObserver implements SplObserve
  • * @author Johan Barbier <johan.barbier@gmail.com>
  • *
  • */
  • class carStateObserver implements SplObserver {
  • /**
  • * Stored subject's state
  • *
  • * @var int
  • */
  • private $iSubjectState;
  • /**
  • * public function update
  • * updater. Echoes subject's state (if the car is stopped or started)
  • *
  • * @param SplSubject $subject
  • * @return void
  • */
  • public function update(SplSubject $subject) {
  • switch ($subject -> STATE) {
  • case 0 :
  • if (is_null ($this -> iSubjectState)) {
  • echo $subject -> NAME.' has not been started<br />';
  • } else {
  • echo $subject -> NAME.' has been stopped<br />';
  • }
  • $this -> iSubjectState = 0;
  • break;
  • case 1:
  • if (1 !== $this -> iSubjectState) {
  • echo $subject -> NAME.' has been started<br />';
  • $this -> iSubjectState = 1;
  • }
  • break;
  • default :
  • throw new Exception ('Unexpected error in carStateObserver::update()');
  • }
  • }
  • }
  • /**
  • * class carSpeedObserver implements SplObserver
  • * @author Johan Barbier <johan.barbier@gmail.com>
  • *
  • */
  • class carSpeedObserver implements SplObserver {
  • /**
  • * public function update
  • * updater. Echoes subject's speed
  • *
  • * @param SplSubject $subject
  • * @return void
  • */
  • public function update(SplSubject $subject) {
  • if (0 !== $subject -> STATE) {
  • echo $subject -> NAME.' speed is '.$subject -> SPEED.'Kmh<br />';
  • }
  • }
  • }
  • /**
  • * class carOverspeedObserver implements SplObserver
  • * @author Johan Barbier <johan.barbier@gmail.com>
  • *
  • */
  • class carOverspeedObserver implements SplObserver {
  • /**
  • * public function update
  • * updater. Catches the subject if it is overspeeding!
  • *
  • * @param SplSubject $subject
  • * @return void
  • */
  • public function update(SplSubject $subject) {
  • if ($subject -> SPEED > 130) {
  • throw new Exception ('Speed limit is 130! You lost your driver license !');
  • }
  • }
  • }
  • try {
  • $oCar = new car ('AUDI A4');
  • $oObs = new carStateObserver;
  • $oObs2 = new carSpeedObserver;
  • $oObs3 = new carOverspeedObserver;
  • $oCar -> attach($oObs);
  • $oCar -> attach($oObs2);
  • $oCar -> attach($oObs3);
  • $oCar -> start();
  • $oCar -> accelerate(20);
  • $oCar -> accelerate(30);
  • $oCar -> stop();
  • $oCar -> start();
  • $oCar -> accelerate(50);
  • $oCar -> accelerate(70);
  • $oCar -> accelerate(100);
  • $oCar -> accelerate(150);
  • } catch (Exception $e) {
  • echo $e -> getMessage ();
  • }
  • ?>
<?php
/**
 * defining abstract implementations
 */
if (!interface_exists ('Countable')) {
	/**
	 * Interface Countable
	 * @author: php
	 *
	 */
	interface Countable {
		
		public function count();
	}
}
if (!interface_exists ('SplObserver')) {
	/**
	 * Interface SplObserver
	 * @author: php
	 *
	 */
	interface SplObserver {
		
		public function update(SplSubject $subject);
	}
}

if (!interface_exists ('SplSubject')) {
	/**
	 * Interface SplSubject
	 * @author: php
	 *
	 */
	interface SplSubject {
		
		public function attach(SplObserver $observer);
		
		public function detach(SplObserver $observer);
		
		public function notify();
	}
}

if (!class_exists ('SplObjectStorage')) {
	/**
	 * Interface SplObjectStorage
	 * @author: php
	 *
	 */
	class SplObjectStorage implements Iterator, Countable {
		
		/**
		 * Array of objects
		 *
		 * @var array
		 */
		private $storage = array();
		/**
		 * Array of objects index
		 *
		 * @var int
		 */
		private $index = 0;
	
		/**
		 * public function rewind
		 * Rewind array pointer
		 * 
		 * @Return void
		 */
		public function rewind() {
			rewind($this->storage);
		}
	
		/**
		 * public function valid
		 * Checks if current loop iteration is valid
		 * 
		 * @Return boolean 
		 */
		public function valid() {
			return key($this->storage) !== false;
		}

		/**
		 * public function key
		 * Returns current key
		 * 
		 * @Return int 
		 */
		public function key() {
			return $this->index;
		}
		
		/**
		 * public function current
		 * Returns current array entry
		 * 
		 * @Return object 
		 */
		public function current() {
			return current($this->storage);
		}
		
		/**
		 * public function next
		 * Iterates to the next entry
		 * 
		 * @Return void 
		 */
		public public function next() {
			next($this->storage);
			$this->index++;
		}
		
		/**
		 * public function count
		 * Returns the number of entries in the array of objects
		 * 
		 * @Return int 
		 */
		public function count()  {
			return count($this->storage);
		}
		
		/**
		 * public function contains
		 * Checks if an object is in the collector array
		 * 
		 * @Param object $obj : object to check
		 * @Return boolean 
		 */
		public function contains($obj) {
			if (is_object($obj)) {
				foreach($this->storage as $object) {
					if ($object === $obj) {
						return true;
					}
				}
			}
			return false;
		}
		
		/**
		 * public function attach
		 * Attaches an object to the collector array
		 * 
		 * @Param object $obj : object to attach
		 * @Return void 
		 */
		public function attach($obj) {
			if (is_object($obj) && !$this->contains($obj)) {
				$this->storage[] = $obj;
			}
		}
		
		/**
		 * public function detach
		 * Detaches an object to the collector array
		 * 
		 * @Param object $obj : object to detach
		 * @Return void 
		 */
		public function detach($obj) {
			if (is_object($obj)) {
				foreach($this->storage as $idx => $object) {
					if ($object === $obj) {
						unset($this->storage[$idx]);
						$this->rewind();
						return;
					}
				}
			}
		}
	}
}

/**
 * starting concrete implementations
 */
/**
 * class car implements SplSubject
 * @author: Johan Barbier <johan.barbier@gmail.com>
 *
 */
class car implements SplSubject {
	
	/**
	 * Name of the car
	 *
	 * @var string
	 */
	private $sName;
	/**
	 * State of the car
	 *
	 * @var int
	 */
	private $iState = 0;
	/**
	 * Speed of the car
	 *
	 * @var int
	 */
	private $iSpeed = 0;
	/**
	 * Collector array of observers
	 *
	 * @var SplObserver
	 */
	private $aObservers;
	
	/**
	 * public function __construct
	 * constructor
	 * Initializes car's nname
	 *
	 * @param string $sName
	 */
	public function __construct ($sName) {
		$this -> sName = $sName;
		$this -> aObservers = new SplObjectStorage;
	}
	
	/**
	 * public function start
	 * Starts the car and notify observers
	 * 
	 * @Return void
	 */
	public function start () {
		$this -> iState = 1;
		$this -> notify();
	}
	
	/**
	 * public function stop
	 * Stops the car and notify observers
	 * 
	 * @Return void
	 */
	public function stop () {
		$this -> iState = 0;
		$this -> iSpeed = 0;
		$this -> notify();
	}
	
	/**
	 * public function accelerate
	 * Accelerates the car and notify the observers
	 * 
	 * @Param int $iAcceleration : how many Kmh you want to accelerate
	 * @Return void
	 */
	public function accelerate ($iAcceleration) {
		if (0 === $this -> iState) {
			throw new Exception ('You must start the car before accelerating...');
		}
		if (!is_int ($iAcceleration) || $iAcceleration < 0) {
			throw new Exception ('Wrong value for car::accelerate()');
		}
		$this -> iSpeed += $iAcceleration;
		$this -> notify();
	}

	/**
	 * public function attach
	 * Attaches an observer
	 * 
	 * @Param SplObserver $observer : the observer to attach
	 * @Return boolean
	 */
	public function attach(SplObserver $observer) {
		if(!$this->aObservers->contains($observer)) {
			$this->aObservers->attach($observer);
		}
		return true;
	}
	
	/**
	 * public function detach
	 * Detaches an observer
	 * 
	 * @Param SplObserver $observer : the observer to detach
	 * @Return boolean
	 */
	public function detach(SplObserver $observer) {
		if(!$this->aObservers->contains($observer)) {
			return false;
		}
		$this->aObservers->detach($observer);
		return true;
	}
	
	/**
	 * public function notify
	 * Notify all the observers
	 * 
	 * @Return void
	 */
	public function notify() {
		foreach($this->aObservers as $observer) {
			$observer->update($this);
		}
	}
	
	/**
	 * public function __get
	 * Get properties value
	 * 
	 * @Param string $sProp : property's name
	 * @Return mixed
	 */
	public function __get ($sProp) {
		switch ($sProp) {
			case 'STATE' : 
				return $this -> iState;
				break;
			case 'SPEED' :
				return $this -> iSpeed;
				break;
			case 'NAME' :
				return $this -> sName;
				break;
			default :
				throw new Exception ($sProp.' cannot be read');
		}
	}
	
	/**
	 * public function __set
	 * Set properties value
	 * 
	 * @Param string $sProp : property's name
	 * @Param mixed $mVal : property's value
	 * @Return void
	 */
	public function __set ($sProp, $mVal) {
		throw new Exception ($sProp.' cannot be set');
	}
}

/**
 * class carStateObserver implements SplObserve
 * @author Johan Barbier <johan.barbier@gmail.com>
 *
 */
class carStateObserver implements SplObserver {
	
	/**
	 * Stored subject's state
	 *
	 * @var int
	 */
	private $iSubjectState;
	
	/**
	 * public function update
	 * updater. Echoes subject's state (if the car is stopped or started)
	 * 
	 * @param SplSubject $subject
	 * @return void
	 */
	public function update(SplSubject $subject) {
		switch ($subject -> STATE) {
			case 0 :
				if (is_null ($this -> iSubjectState)) {
					echo $subject -> NAME.' has not been started<br />'; 
				} else {
					echo $subject -> NAME.' has been stopped<br />'; 
				}
				$this -> iSubjectState = 0;
				break;
			case 1:
				if (1 !== $this -> iSubjectState) {
					echo $subject -> NAME.' has been started<br />'; 
					$this -> iSubjectState = 1;
				}
				break;
			default :
				throw new Exception ('Unexpected error in carStateObserver::update()');
		}
	}
}

/**
 * class carSpeedObserver implements SplObserver
 * @author Johan Barbier <johan.barbier@gmail.com>
 *
 */
class carSpeedObserver implements SplObserver {
	
	/**
	 * public function update
	 * updater. Echoes subject's speed
	 * 
	 * @param SplSubject $subject
	 * @return void
	 */
	public function update(SplSubject $subject) {
		if (0 !== $subject -> STATE) {
			echo $subject -> NAME.' speed is '.$subject -> SPEED.'Kmh<br />';
		}
	}
}

/**
 * class carOverspeedObserver implements SplObserver
 * @author Johan Barbier <johan.barbier@gmail.com>
 *
 */
class carOverspeedObserver implements SplObserver {
	
	/**
	 * public function update
	 * updater. Catches the subject if it is overspeeding!
	 * 
	 * @param SplSubject $subject
	 * @return void
	 */
	public function update(SplSubject $subject) {
		if ($subject -> SPEED > 130) {
			throw new Exception ('Speed limit is 130! You lost your driver license !');
		}
	}
}
try {
	$oCar = new car ('AUDI A4');
	$oObs = new carStateObserver;
	$oObs2 = new carSpeedObserver;
	$oObs3 = new carOverspeedObserver;
	$oCar -> attach($oObs);
	$oCar -> attach($oObs2);
	$oCar -> attach($oObs3);
	
	$oCar -> start();
	$oCar -> accelerate(20);
	$oCar -> accelerate(30);
	$oCar -> stop();
	$oCar -> start();
	$oCar -> accelerate(50);
	$oCar -> accelerate(70);
	$oCar -> accelerate(100);
	$oCar -> accelerate(150);
} catch (Exception $e) {
	echo $e -> getMessage ();
}
?>


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

16 juillet 2007 18:41:05 :
Ajout d'une méthode car::stop() histoire de... ;-)
16 juillet 2007 18:43:59 :
Ajout d'une exception pour être plus carré sur le code
16 juillet 2007 18:45:01 :
...
17 juillet 2007 11:03:00 :
Documentation du code

 Sources du même auteur

Source avec Zip ASTUCES/HACK PHP
SQUELETTE DE GESTION DES DROITS
[PHP 5.1] CLASS STRING : NOUVEL EXEMPLE SUR LA SPL
Source avec Zip Source avec une capture [PHP 5.1] PHOTOPHOP (PHPDRAW 2)
Source avec Zip Source avec une capture [PHP5.1] O-LOC : CLASSE ET BACKOFFICE D'INTERNATIONALISATION

 Sources de la même categorie

Source avec Zip Source avec une capture GENERATEUR D'ONGLET DE NAVIGATION PHP par pos123
FORMATER UN LIEN YOUTUBE, DAILYMOTION OU VIMEO POUR L'UTILIS... par kgb93
Source avec Zip Source avec une capture PAGINATION + FICHIER CSS par profdi
Source avec Zip Source avec une capture SYSTEME D'AUTHENTIFICATION PHP AVEC PROTÉCTION KEYLOGGER par mtrix000
Source avec Zip Source avec une capture GENERATEUR DE BOUTONS DE PARTAGES POUR RESEAUX SOCIAUX par cod57

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture GRACENATUR V02 - CDMS: CONTAIN AND DESIGN MANAGMENT SYSTEM par sajaris
Source avec Zip POO - FACTORY CLASS par Waredan
POO - SINGLETON CLASS par Waredan
Source avec Zip OBSERVER PATTERN ORIENTÉ DÉVELOPPEMENT ÉVÉNEMENTIEL DÉCLARAT... par aKheNathOn
Source avec Zip PHP EVENTS MANAGER par psykocrash

Commentaires et avis

Commentaire de coucou747 le 17/07/2007 07:18:59 administrateur CS

c'est etrange comme source, mais pourquoi pas :)

coder un radar :) je trouve ca etrange que ca soit autre chose qui observe l'objet, alors que l'objet possede lui meme du code pour qu'on lui branche quelquechose...

Commentaire de malalam le 17/07/2007 09:06:16 administrateur CS

Dans un contrôle radar, c'est bien le radar qui observe la voiture.
De plus, on peut très bien voir les observateurs comme des modules greffés à la voiture, dans ce cas.
Toujours est il que c'est ujn principe qui fonctionne bien, et colle bien à la POO je trouve.
A la base, mon exemple prenait des commandes qui étaient traitées, puis expédiées, avec envoi d'email  au destinataire, etc...mais bon, la voiture c'était pour rester dans la même analogie que la source précédente de localstone ;-)

Commentaire de FhX le 18/07/2007 00:52:30

Ah ca j'adore :)
Le mieux en utilisant les observers, c'est d'utiliser un état (state).

En pratique, voila ce que ca peut donner. On va compter le nombre de logging d'un utilisateur. Si le nombre est de 3, on annule toute possibilité d'identification.
Si par contre, le login et le mot de passe sont bon, alors on redirige.

J'ai mis 2 modules ici, le premier est le comptage du nombre de logging.
Le second est le module de redirection en fonction du "state" de l'objet.
Je n'ai pas mis d'interfaces, c'est juste du vite fait :

<?php
abstract class Item {

protected $_mods = null;
protected $state = null;

public function __construct() {

}

final protected function getState() {
return $this->state;
}
final protected function setState($state) {
                $this->state = $state;
        }
final protected function ModExist( Module $mod ) {
   foreach ( $this->_mods as $obj)
             if ( $object === $obj )
                 return true;
  return false;
}

final public function AddMod( Module $mod ) {
if ( !$this->contains($mod) )
       $this->$_mods[] = $mod;
}

final public function DeleteMod( Module $mod ) {
   foreach ( $this->_mods as $i => $obj) {
             if ( $mod === $obj ) {
                  unset( $this->_mods[$idx] );
                  return;
             }
   }
}

final public function SeekForEvent() {
  foreach ( $this->_mods as $mod)
            $mod->SeekEvent($this);
}
}

class Visitor extends Item {

const __WRONG_AUTHENTIFICATION__ = 'wrong_login_auth';
const __SUCCESSFUL_AUTHENTIFICATION__ = 'right_login_auth';

const __MAX_ATTEMPT_FOR_LOGIN__ = 'wrong_login_count';

private $login;
private $password;


public function setLogin($login) {
$this->login = trim($login);
}
public function getLogin() {
return $this->login;
}
public function setPassword($password) {
$this->password = trim($password);
}
public function getPassword($hashed=true) {
return $hashed ? sha1($this->password) : $this->password;
}

public function AuthValidation() {
if ( $this->getState() === self::__MAX_ATTEMPT_FOR_LOGIN__ )
      throw new LoginException();

$data = $mysqli->query('SELECT COUNT(*) FROM .... WHERE login = "..." AND password = "..." ')->fetch_row();  
if ( (int) $data[0] === 1 )
    $this->setState(self::__SUCCESSFUL_AUTHENTIFICATION__);
else
    $this->setState(self::__WRONG_AUTHENTIFICATION__);

$this->SeekForEvent();
}

}

class AttempLogin {

private $maxLoginAttemp = 3;
private $CurrentLoginAttemp = 0;

public function SeekEvent( Item $item ) {
  switch ( $item->getState() ) {
   case Visitor::__WRONG_AUTHENTIFICATION__ :
         $this->CurrentLoginAttemp++;
          if ( $this->CurrentLoginAttemp >= $this->maxLoginAttemp ) {
              $item->setState(Visitor::__MAX_ATTEMPT_FOR_LOGIN__);
              throw new LoginException();
          }    
         break;
  }
  
}

}
class Redirect {

public function SeekEvent( Item $item ) {
  switch ( $item->getState() ) {
   case Visitor::__SUCCESSFUL_AUTHENTIFICATION__  :
       header('Location: ./membre.php');
       exit();
       break;
  }
}

}

if ( isset($_SESSION['user']) && $_SESSION['user'] instanceof Visitor ) {
    $user = $_SESSION['user'];
} else {
    $user = new Visitor;
    $user->AddMod( new AttempLogin );
     $user->AddMod( new Redirect );
}
    
$user->setLogin('login de test');
$user->setPassword('Mot de passe de test');

try {
$user->AuthValidation();
} catch ( LoginException $e ) {
echo $e->getMessage();
   $_SESSION['user'] = $user;
}

?>

Voila ce que ca peut donner plus ou moins :)
A travailler bien sur ^^

Je ne met pas ca en tant que code pour éviter la concurrence et la duplication de sources, mais je le met ici pour donner un exemple plus concret :)

Vala !

Commentaire de FhX le 18/07/2007 14:27:27

J'ai oublié de mettre une méthode pour changer le "state" à la fin de ma recherche d'évènement sur mes observers.
On peut éventuellement rajouter un flag pour garder le dernier changement d'état :

abstract class Item {
proteted $lastState;
protected function KillState() {
  $this->lastState = $this->state;
  unset($this->state);
}
}

class Visitor extends Item {
public function AuthValidation() {
  // code
  $this->SeekForEvent();
  $this->KillState();
}
}

Voila voila :)

Commentaire de FhX le 18/07/2007 17:52:28

mon exemple plus haut ne marche pas... je corrige ca au plus vite :)

Commentaire de amezghal le 20/07/2007 17:57:31

ya une ptite erreur
deux public
#  public public function next() {
# next($this->storage);
# $this->index++;
# }

Commentaire de amezghal le 20/07/2007 18:08:42

#  public function attach(SplObserver $observer) {
# if(!$this->aObservers->contains($observer)) {
# $this->aObservers->attach($observer);
# }
# return true;
# }
cette fonction va retourner 'true' dans tous les cas.
le return true doit etre dans le bloc if(){} et false en dehors

Commentaire de malalam le 22/07/2007 14:40:18 administrateur CS

Hello,

1 - exact, curieux que cela fonctionne d'ailleurs (vu que ceci est une copie de mon code).

2 - c'est intentionnel. Que l'ojet existe déjà ou pas, dans tous les cas, c'est ok. Le seu problème serait qu'on attache pas un SplObservern ce qui provoquera une erreur fatale de toute façon puisque je le force dans l'appel dans la méthode.

Commentaire de FhX le 10/08/2007 17:10:40

Bon, j'ai fais un truc avec les observateurs et les évenements coté serveur... mais n'ayant plus internet jusqu'à la mi septembre, je ne peux pas poster le code avant.

Mais dès que je peux , je t'en fais profiter Mala :)

a++

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Design pattern : Factory [ par neigedhiver ] Salut, Je me pose une question tout bête. Est-il judicieux d'embarquer une factory dans une classe abstraite, ou est-il préférable d'utiliser une cla je ne peux pas changer de style [ par soulaimania ] Bonjour,   Je débute en php et je veux créer une sorte de StyleSwitcher, sauf que quand je fais appel au contenu de la cookie pour changer de feuille Peut-être une histoire de tableaux... [ par ptiromino ] Je fais appel à la communauté pour me guider un peu dans ma programmation.J'ai 3 tables dans ma base de donnée : "categorie", "souscategorie" et "desi Script Membrex [changer le tout le design] [ par 974militant ] Bonjour, j'ai projet de construire un site sur le Vtuning, j'ai acheté un kit graphique il y a quelques temps, j'ai pas mal avancé.J'ai télécharger le design site web [ par menyarito ] salut tous le monde, je entraine de créer un site,je voulait savoir quelle recherche je doit effectué pour trouver des designs??? Merci d'avance Affichage évènement enregistrer dans une base sur une date de calendrier. [ par Rykets24 ] Bonsoir a tous, je suis nouveaux sur phpcs et je ne sais pas si je suis dans la bonne section; si cela n'est pas le cas, je m'en excuse. Je suis actu Design 3 colonnes (liquide) [ par BencoAndCo ] Bonjour ! Comment faire un design avec 3 colonnes en css : 1 colonne centrales avec une largeur fixe et 2 colonnes gauche & droite dont la largeur s Gestion de thèmes (design) [ par lolboyx ] Bonjour, Je débute actuellement dans le codage PHP. Donc si mes explications ne sont pas très claires excusez le moi. [^^happy13] Voilà je me suis m Un p'tit code simple mais je sais pas comment le faire ! [ par N e x u m ] Salut,je voudrais avoir un simple code SANS MYSQL (Si possible) Qui garde le même design dans chaque pageAdmettons on a un design (Un look, un interfa Gestion d'évènement souris [ par BSide ] Bonjour,j'essaie depuis un sacré moment de faire fonctionner le code qui suit...(récupéré dans la source de MySQL)Impossible de le faire tourner !!! L


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 5,117 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales