Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

[PHP5] OBSERVER DESIGN PATTERN


Information sur la source

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é: 7 205 / 209

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

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10

Commentaire sur cette source (9)
Ajouter un commentaire et/ou une note

Description

Suite à cette source :
http://www.phpcs.com/codes/PROGRAMMATION-EVENEMENTIELLE-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

Pour les "Membres Club", vous pouvez 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

Commentaires et avis

signaler à un administrateur
Commentaire de coucou747 le 17/07/2007 07:18:59

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...

signaler à un administrateur
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 ;-)

signaler à un administrateur
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 !

signaler à un administrateur
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 :)

signaler à un administrateur
Commentaire de FhX le 18/07/2007 17:52:28

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

signaler à un administrateur
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++;
# }

signaler à un administrateur
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

signaler à un administrateur
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.

signaler à un administrateur
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 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 Recherche un créateur pour forum avec mon design contre rémunération en affichages ! [ par SkyCrasher ] Le titre en dit beaucoup mais je vais vous détaillez ma démarche :- Il me faut un forum avec :--- espace membre détaillé--- gestion admin détaillé--- Evènement onclick avec PHP [ par Kleidp ] &lt;u&gt;Voici mon problème:&lt;/u&gt;je veux réaliser un évènement avec un onclick, qui déclanche la procédure test :echo "&lt;input type=\"checkbox\ Pattern [ par charloteuf ] Salut à tous, J'ai un problème de pattern. J'aimerais travailler sur les chaines qui sont entre les balises pour un editeur WYSIWYG. il faut que je ra conversion fichier .doc en .html [ par thoru ] Bonjour!Je débute en php et je ne sais pas s'il existe une possibilité de convertir un fichier .doc en fichier.html.Je vous explique je dois prendre d


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Comparez les prix Nouvelle version

Photothèque Nouveau !



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
Temps d'éxécution de la page : 0,468 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.