Script de Panier en PHP5 POO

WRInaute occasionnel
Bonsoir à tous,

Suite au post "POO ou pas POO ?" j'ai essayé de m'y mettre (ce fût laborieux) et ai tenté de faire quelque chose.
Vu qu'il y a apparemment ici des pros dans ce domaine, j'aimerai bien avoir vos avis sur la syntaxe, la façon dont c'est construit, comment optimiser etc...

Bien sur c'est quelque chose qui existe déjà mais bon faut bien débuter par quelque chose.

Voilà, suis-je sur la bonne voie ?

Merci

PS : Ce n'est pas sécurisé et un zip avec l'ensemble est dispo ici.

La classe qui gère le "catalogue"
Code:
class Store
{

	protected $db;
	private $product;
	
	public function __construct()
	{
		if (is_readable(PRODUCTS_DB))
			$this->db = new SimpleXMLElement(file_get_contents(PRODUCTS_DB));	
			//$this->db = simplexml_load_string(file_get_contents(PRODUCTS_DB));	
		else
			return exit('Products xml database missing or unreadable.');
	}
	
	private function selectone($id)
	{
		return $this->db->Xpath('/products/product[id="'.$id.'"]');
	}
	
	protected function productexist($id)
	{
		if (count($this->selectone($id)) > 0)
			return true;
		else
			return false;
	}
	
	public function productprice($id)
	{	
		if ($this->productexist($id))
			$this->product = $this->selectone($id);
			return $this->product[0]->price;
	}
	
	public function productname($id)
	{
		if ($this->productexist($id))
			$this->product = $this->selectone($id);
			return $this->product[0]->name;
	}
	
	public function viewstore()
	{
		return $this->db->product;
	}

}

Et celle qui gère le panier
Code:
class Cart extends Store
{

	protected $items;
	private $total;
	
	public function __construct()
	{
		parent::__construct();
		session_start();
		
		if (!isset($_SESSION['cart'])) 
			$this->items = array();
		else
			$this->items = unserialize($_SESSION['cart']);
	}
	
	public function additem($id)
	{
		if (array_key_exists($id, $this->items))
			$this->items[$id]++;
		else
			$this->items[$id] = 1;
	}
	
	public function delitem($id)
	{
		if (array_key_exists($id, $this->items))
			if ($this->items[$id] > 1)
				$this->items[$id]--;
			else
				unset($this->items[$id]);
	}
	
	public function emptycart()
	{
		$this->items = array();
	}
	
	public function nbitems()
	{
		return array_sum($this->items);
	}
	
	public function viewcart()
	{
		return $this->items;
	}
	
	public function totalcart()
	{
		$this->total = 0;
		
		foreach ($this->items as $id => $qty)
		{
			$this->total += $this->productprice($id) * $qty;
			//$this->total += parent::productprice($id) * $qty;
		}
		
		return $this->total;
	}
	
	public function __destruct()
	{
		$_SESSION['cart'] = serialize($this->items);
	}

}
 
WRInaute accro
Bah c'est déjà pas mal si tu débutes lol. Peut-être plus faire gaffe à bien nommer tes méthodes. Genre getXXXX quand tu récupères un truc, setXXXX quand tu veux initialiser. Pour delXXX et addXXX c'est bien. Et quand il y a rien on sait que c'est l'exécution d'un travail spécifique.

Sinon tu veux savoir quoi d'autre ? :D
 
WRInaute occasionnel
Salut et merci pour ta réponse.

Ok je corrigerais le nom des méthodes :) C'est vrai que c'est plus joli (mais plus long à écrire :D )

Ce que je veux savoir c'est si syntaxiquement tout est correct, si la logique est sensée (peut être n'ais-je pas pris tous les raccourcis) ou encore si j'ai bien pigé le concept.
Si oui, alors en fait c'est moins compliqué que ce que je pensais... ouf.

Ah oui aussi on dans la classe Cart a un endroit j'ai commenté un ligne, celle du dessus fait la même fonction mais je ne sais pas laquelle est la plus académique : this->fonctiondelaclassmère() ou parent::fonctiondelaclassemère() ?
 
WRInaute impliqué
hello,
une remarque c'est très crade le session_start dans le constructeur ainsi, tu devrais te créée une abstraction pour la session, genre un pattern registry ...
 
WRInaute occasionnel
Salut,

julienr a dit:
hello,
une remarque c'est très crade le session_start dans le constructeur ainsi, tu devrais te créée une abstraction pour la session, genre un pattern registry ...

Qu'entends tu par "abstraction pour la session, genre un pattern registry" ?
C'est faire appel à une fonction toute simple définie ailleurs ?
 
WRInaute occasionnel
Bonsoir à tous,

Donc après recherche il semblerait que julienr parlait se Singleton, c'est bien ça ?

Mais si j'ai plus ou moins compris le but de ce procédé (instancier une seule et unique fois une méthode) je ne sais pas trop si je dois transformer ma classe Cart en Singleton ou alors faire un Singleton qui gère la partie $_SESSION[] de la classe Cart...

Pouvez vous m'en dire plus ?
 
WRInaute impliqué
enfaite pas tout à fait singleton en design pattern c'est une façon élégante et objet de gérer en quelques sorte une variable globale, le pattern registry propose une entité pour mémoriser une valeur pour une clef défini, une session en d'autre mot.

ce que je voulais dire c'est que cela me choque de mettre session_start dans un constructeur, c'est pas, de mon avis, à l'objet de lancer la session. Il peux en revanche s'assurer que la session est bien lancé ou alors généré une exception.
 
WRInaute occasionnel
Ok, merci beaucoup pour ces explications.

Donc en fait il faut juste déplacer le session_start() dans un registry pattern ? La vérification de l'existence de la $_SESSION['cart'] et sa sérialisation je n'ai pas besoin d'y toucher ?

Et sinon aurais-tu un exemple du code du design pattern pour gérer le session_start() ? En cherchant des modèles de design pattern je tombe surtout sur le Singleton...
 
WRInaute impliqué
vi en faite tu as raison, il faut une registry comme celle ci, sauf qu'il faudrait l'améliorer en faisant en sorte que $_cache soit initialisé comme un singleton

Code:
class Registry {
    var $_cache;
    
    function Registry() {
        $this->_cache = array();
    }
    function setEntry($key, &$item) {
        $this->_cache[$key] = &$item;
    }
    function &getEntry($key) {
        return $this->_cache[$key];
    }
    function isEntry($key) {
        return ($this->getEntry($key) !== null);
    }
}
 
WRInaute occasionnel
Bon, c'est (un peu) plus clair.

Merci bien pour ton aide !

Je vais rêver de ça cette nuit et demain je tente de le coder. :D

A+!
 
WRInaute occasionnel
Bonjour à tous,

Ca y est, donc finalement je suis parti sur une classe Singleton pour gérer mes Sessions.

C'est mieux comme ça ? Je trouve ça un peu bizarre de gérer l'initialisation des sessions de la classe Cart dans le Singleton mais sinon il n'aurait servi qu'à lancer le session_start().

Autre petit pb, dans le constructeur de Cart() je ne peut pas faire directement $this->items = Sessions::getInstance()->iniCart() , ça me renvoie une erreur...

Voilà ce que ça donne :

Code:
class Sessions
{

	private static $instance = null;
	private $cart;
	
	private function __construct()
	{
		session_start();
	}
	
	public static function getInstance()
	{
		if (is_null(self::$instance))
			self::$instance = new Sessions();
		else
			return self::$instance;
	}
	
	public function initCart()
	{
		if (!isset($_SESSION['cart'])) 
			return $this->cart = array();
		else
			return $this->cart = unserialize($_SESSION['cart']);		
	}
	
	public function setCart($items)
	{
		$_SESSION['cart'] = serialize($items);
	}
	
	public function __clone()
	{
	}
	
	public function __destruct()
	{
	}

}


class Cart extends Store
{

	protected $items;
	private $total;
	
	public function __construct()
	{
		parent::__construct();

		$this->items = Sessions::getInstance();
		$this->items = Sessions::initCart();
	}
	
	public function addItem($id)
	{
		if (array_key_exists($id, $this->items))
			$this->items[$id]++;
		else
			$this->items[$id] = 1;
	}
	
	public function delItem($id)
	{
		if (array_key_exists($id, $this->items))
			if ($this->items[$id] > 1)
				$this->items[$id]--;
			else
				unset($this->items[$id]);
	}
	
	public function emptyCart()
	{
		$this->items = array();
	}
	
	public function nbItems()
	{
		return array_sum($this->items);
	}
	
	public function viewCart()
	{
		return $this->items;
	}
	
	public function totalCart()
	{
		$this->total = 0;
		
		foreach ($this->items as $id => $qty)
		{
			$this->total += parent::productPrice($id) * $qty;
		}
		
		return $this->total;
	}
	
	public function __destruct()
	{
		Sessions::getInstance()->setCart($this->items);
	}

}

Des suggestions ? :)
 
Discussions similaires
Haut