8797 sujets

Développement web côté serveur, CMS

Salut tout le monde, je viens avec un petit soucis d'organisation où j'ai pas trouvé de solution simple pour l'instant... Possiblement c'est ma structure le soucis, j'en suis consciente, donc je demande l'avis du public Smiley rolleyes

Soit une classe parent "objet". Elle contient un certain nombre d'attribut :
ID, catégorie, prix, skin, nom

Soit un classe enfant "bouffe" extends d'Objet. Elle contient deux attributs propres et un certains nombres de méthodes :
puissance, carac

Soit une seconde classe enfant "Equipement" extend d'objet elle aussi. Elle contient certains attributs propres et certaines méthodes :
Force, Precision, Resistance, Chance, Vitesse, Emplacement

J'ai dans mon application 3 grands types d'objets :
ressources, consommables et Equipement.

Au niveau de la classe objet, les trois se distinguent par la catégorie (0,1,2). La ressource est un Objet "pur"; le consommables est un Objet "bouffe" et l'équipement est un Objet "Equipement".


Maintenant, mon soucis est simple.

Quand un joueur va sur la fiche d'un objet, il transmet au serveur un ID.

Ma question est :

Y a-t-il un moyen pour que ma classe "objet" (parent) se transforme automatiquement dans tel ou tel enfant en fonction de sa catégorie ? De manière à ce que je puisse accéder aux attributs des enfants ?

ou suis-je obligé de charger et créer l'objet puis, en fonction de la catégorie charger les informations de l'enfant et de créer l'Enfant ? Smiley sweatdrop
Je suis pas sûr de comprendre ton problème. Si tu as un objet "bouffe" enfant de "objet" tu n'as qu'à instancier "bouffe".

Admettons que ton id 2 soit "bouffe", quand tu reçois cet ID tu fais un new Bouffe(); et c'est tout.
Ca je sais instancier un enfant, c'est pas la difficulté...

Pour faire plus clair, mon fichier qui affiche la fiche d'un objet a une structure de type :

- verif de l'id envoyé par _POST grâce à un ajax
- connexion à la base
- charge "objet", instancie $objet comme étant un "Objet"
si(objet->Categorie==1) alors charge "bouffe" et instancie $objet" comme étant une "bouffe"
si(objet->Categorie==2) alors charge "equipement" et instancie $objet comme étant un "équipement"
- met l'affichage de l'objet ($objet->AffFiche() ) dans $retour
- echo $retour sous forme d'un JSON

On a donc la même méthode AffFiche() sur les 3 classes (méthode surchargée en réalité), qui retournent les informations nécessaires à l'affichage en fonction du type d'objet.


J'ai moyen d'éviter le double chargement en chargeant le contenu des trois tables (objet_global, objet_bouffe et objet_equip) ce qui laissera des champs vides, ceux ne correspondant pas au type.

Mais c'est plutôt la double instanciation qui me cause problème... J'aurais voulu un truc plus clean, genre que la classe "objet" fasse ça tout seul... mais je sais pas si c'est possible en fait... Smiley ohwell

(sachant que c'est le seul vrai cas où j'en ai besoin, les autres moments, j'utilise tous mes objets comme des objets ou alors dans leur catégorie précise en sachant la catégorie)
Modifié par Lothindil (13 Feb 2013 - 10:38)
a écrit :

si(objet->Categorie==1) alors charge "bouffe" et instancie $objet" comme étant une "bouffe"
si(objet->Categorie==2) alors charge "equipement" et instancie $objet comme étant un "équipement"


Ça se traduit comment dans ton code ?

Tu peux aussi poster la structure de tes 3 classes ?
if($objet[1]->Categorie==1)
{
     $ressource=GestionPossession::Charger($id,"bouffe");
     $objet=ToolBox::MysqlAObjet($ressource,"Bouffe");
}
elseif($objet[1]->Categorie==2)
{
     $ressource=GestionPossession::Charger($id,"equip");
     $objet=ToolBox::MysqlAObjet($ressource,"Equipement");
}


Avec :
Abstract Class GestionPossession
{
	public static function ChargerObjet () //validé et testé
	{
		$nbre_arg=func_num_args();
		
		$rq="Select g.`Type` AS TypeObjet, g.Prix, g.Quete,
		g.Collection, g.Echangeable, g.ID, g.Taux, g.Alchimie";
		if($nbre_arg==0)//tous les objets
		{
			$rq.=" From objet_global where objet_global.`Type`<>3";
		}
		elseif($nbre_arg==1) //en fonction de l'id
		{
			$id=func_get_arg(0);
			$rq.=" From objet_global as g
			Where objet_global.ID = '".$id."'";
		}
		elseif($nbre_arg==2) //en fonction d'un id et du type
		{
			$type=func_get_arg(1);
			$id=func_get_arg(0);
			if($type=="bouffe")		
			{ 
				$rq.="c.Force, c.Carac From objet_conso AS c
				Inner Join objet_global AS g ON g.ID = c.IDobjet Where g.ID = '".$id."'";
			}
			elseif($type=="equip")		
			{ 
				$rq=" e.Emplacement, e.Puissance, e.Resistance, e.`Precision`, e.Vitesse, e.Chance, e.Lvl_min
				From objet_global AS g Inner Join objet_equip AS e ON e.IDobjet = g.ID
				Where g.ID = '".$id."'";
			}
		}
		$ressource=Sql::requeteReponse($rq);
		return $ressource;
	}
}


Et
abstract class ToolBox
{	
	public static function MysqlAObjet($ressource,$classe)
	{
		if($ressource->num_rows>0)
		{
			$i=0;
			while($mysql=$ressource->fetch_assoc())
			{	$i++;
				$objet[$i] = new $classe;
				$objet[$i] -> Assigner($mysql);
			}
		}
		else
		{
			$objet='';	
		}
		return $objet;
	}
}



Structure des classes

Classe Objet
{
	protected $ID;
	protected $Nom;	
	protected $TypeObjet;
	protected $NomType;
	protected $Prix;
	protected $PrixVente;
	protected $PrixAchat;
	protected $Quete;
	protected $Collection;
	protected $Echangeable;
	protected $Taux;
	protected $Alchimie;
	protected $Skin;
	protected $langueObjet;

	protected function DeterminePrix($prix)
	{
		$this->PrixVente=round($this->Prix/100*125);
		$this->PrixAchat=round($this->Prix/100*75);
	}
	public function Assigner(array $arr)
	{
		foreach ($arr as $key => $value) {
			$this->$key = $value;
		}
		unset($arr);
		$this->DeterminePrix($this->Prix);
		$this->Skin=GestionPossession::SrcObjet($this->ID);
		$this->Nom=GestionPossession::NomObjet($this->ID);

		if($this->TypeObjet==0){$this->NomType="Ressource";}
		elseif($this->TypeObjet==1)
		{
			$this->NomType="Conso";
		}
		elseif($this->TypeObjet==2)
		{
			$Type=GestionEquip::ChargerType($this->ID);
			$this->NomType=GestionEquip::NomPlace($Type);
		}
	}
	public function __get($name)
    	{
      		 if (property_exists($this, $name)) {
            	return $this->$name;
        	}
    }
}


class Equipement extends Objet
{
	private $Emplacement;
	private $Force;
	private $Resistance;
	private $Precision;
	private $Vitesse;
	private $Chance;
	private $Lvl_min;
	public function Assigner(array $arr)
	{
		foreach ($arr as $key => $value) {
			$this->$key = $value;
		}
		unset($arr);
		$this->DeterminePrix($this->Prix);
		$this->Skin=GestionPossession::SrcObjet($this->ID);
		$this->Nom=GestionPossession::NomObjet($this->ID);
		$this->NomType=GestionEquip::NomPlace($this->Emplacement);
	}
}


class Bouffe extends Objet
{
	private $Puissance;
	private $Carac;

	public function Assigner(array $arr)
	{
		foreach ($arr as $key => $value) {
			$this->$key = $value;
		}
		unset($arr);
		$this->DeterminePrix($this->Prix);
		$this->Skin=GestionPossession::SrcObjet($this->ID);
		$this->Nom=GestionPossession::NomObjet($this->ID);
		$this->NomType=GestionEquip::NomPlace($this->Emplacement);
	}
}



Voilà, s'il te faut autre chose, dis-le ^^