Page 1 sur 3

Collection d'objet

Posté : 07 juin 2007, 12:08
par Wells83
Bonjour à tous, je me pose une question existentielle.
Je travaille tout les jours en .Net (de microsoft) et je fait de l'objet. Or il existe en .net ce qu'on appelle les collections d'objets.

Ce ne sont ni plus ni moins que des listes ou des tableaux contenant des objets. J'aimerais savoir si il existe un équivalent en php. Un exemple d'utilisation. Je veux afficher la liste des membres de mon forum. J'ai une classe membre qui me permet de créer des objets membres. Je vais donc créer une collection de membres que je vais ensuite parcourir avec une boucle.

Seconde question, j'aimerais savoir si les propriété de nos objets peuvent être aussi des objets.
Par exemple mon objet membre aura une propriété type qui sera lui même un objet.

Voila merci à tous pour votre aide.

Posté : 07 juin 2007, 12:16
par titerm
Tu devrais trouver ton bonheur dans la SPL et ICI aussi

Posté : 07 juin 2007, 12:24
par Genova
Pour ta seconde question, bien sur que les propriétés peuvent être des objets. Exemple :
class maClasse1
{
   public $propriete;

   function __construct()
   {
      $this->propriete = new maClasse2();
   }
}

class maClasse2
{
   public $autrePropriete;

   function __construct()
   {
      $this->autrePropriete = 'toto';
   }
}

$class = new maClasse1();
echo $class->propriete->autrePropriete; // Affiche toto

Posté : 07 juin 2007, 13:31
par Klomac
Je suppose que ce que tu appelles "collection d'objets" est en PHP un objet implémentant l'interface "Iterator". Auquel cas comme l'a suggéré titerm, la SPL est nickel :) L'interface d'itérateurs récursifs est pas mal aussi :)

Posté : 07 juin 2007, 14:31
par Wells83
Je comprend pas tout, je débute en objet au niveau de PHP. Donc soyez miséricordieux, dites moi si je me plante.

De ce que je comprend la SPL permet de faire des tableaux d'objets. Mais je n'ai pas bien compris:

1)Faut il installer qq chose en plus sur le serveur (pose soucis en cas de mutualité)
2)Comment ça se déclare tout ca, syntaxe parlant
3)Apparemment il n'y a pas moyen de tirer aléatoirement une valeur dans la liste d'objet?


Voila si qq'un si connait ^^

Posté : 07 juin 2007, 15:02
par titerm
LA SPL fait partie de PHP, y a rien a installer

C'est un ensemble de classe et d'interface. Ca s'utilise comme n'importe quelle classe ou interface. C'est pas très different de l'objet en java ou en .net

$collection = new ArrayObject() ;

Comme ArrayObect implement les interfaces ArrayAcces, Counttable, et Iterator, tu peux donc utiliser ca comme n'importe quelle tableau
foreach($collection as $item) ...

count($collection)

$collection[] = $object
ou
$collection->append($objet) ;

etc...

Un tutorial sympas dispo ici

Posté : 07 juin 2007, 15:11
par Wells83
Merci beaucoup et concernant la fonction pour tirer une valeur aléatoirement, je l'ai pas vue dans la doc. qq'un a une piste ?

Posté : 07 juin 2007, 15:23
par Hubert Roksor
En fait je crois que vous avez pris le problème à l'envers. Plutôt que d'essayer d'appliquer en PHP les concepts d'un autre langage il vaut mieux envisager la situation en tant que "problème / solution". Quel est le problème que tu essaies de résoudre avec une collection d'objet ?

PHP n'est pas spécialement adapté pour créer puis traiter des myriades d'objets, et si tu essaies de traiter chaque bout d'information sous la forme d'objets je peux te garantir que tes pages vont être très très lentes. Si pour afficher une liste de 25 membres avec leur type tu es obligé de créer 50 objets tu vas rapidement te heurter à des problèmes de performance et d'utilisation de la mémoire.

Posté : 07 juin 2007, 15:34
par Wells83
En fait je réfléchit plutôt pour mon moteur de jeu. Je m'explique, je possède un jeu de conquête spa. Donc j'ai un moteur de combat qui fait combattre deux flottes. Ces flottes sont composés de X vaisseaux.

Actuellement je gère tout avec des tableaux, et ca devient vite l'anarchie en terme de maintenance.

Je réfléchit donc à la façon dont je pourrais transformer ca en objet. Maintenant il sera courant que je créer 1000 objets vaisseaux ou plus. Donc si tu me dit que niveau mémoire c'est mort.....

Mon autre problématique, d'ou ma question est:

le vaisseau A tire, je doit donc choisir une cible dans le camp B. J'ai donc besoin de tirer aléatoirement un vaisseau B, donc un objet B.

Posté : 07 juin 2007, 16:28
par titerm
Juste pour la qusetion aléatoire, array_rand() est ton amis

Pour le reste je lirai plus tard, la c'est l'heure du KAWA :)

Posté : 07 juin 2007, 16:40
par Sékiltoyai
PHP n'est pas spécialement adapté pour créer puis traiter des myriades d'objets, et si tu essaies de traiter chaque bout d'information sous la forme d'objets je peux te garantir que tes pages vont être très très lentes. Si pour afficher une liste de 25 membres avec leur type tu es obligé de créer 50 objets tu vas rapidement te heurter à des problèmes de performance et d'utilisation de la mémoire.
Je ne vois pas pourquoi les objets, ca prendrait beaucoup plus de place que les variables classiques...

Posté : 07 juin 2007, 16:49
par titerm
Plutot d'accord avec Sékiltoyai.
De tte facon, si tu as une page un peu compliqué, qu'elle soit géré en objet ou via des fonctions, ca sera lent.
Si tu doit faire face a une forte charge, il n'y a qu'une seule solution, c'est d'utiliser des systèmes de caches.

Quand tu utilises des framework tel que zendFramework ou autre, c'est pas 50 objets qui sont créés, mais des centaines. Et par objet, j'entend bien des classes distincts ou dérivée l'une de l'autre.

Créer 1000 vaisseaux d'un type ce n'est pas 1000 classes mais 1000 instances.

Posté : 07 juin 2007, 16:52
par Wells83
Je précise que le moteur dont je parle n'est pas une page web. C'est un script que je lance, qui modifie la bdd. Je le lance lors du passage de tour et les utilisateurs ne l'utilise jamais. C'est donc un cas trés précis de traitement.

Posté : 07 juin 2007, 16:53
par Genova
Ben en mémoire c'est clair qu'un objet prend largement plus de place qu'une variable. Fait le test :
<?php
set_time_limit(0);
error_reporting(E_ALL);
define('OS_SERVER', (preg_match('/^WIN/', PHP_OS)) ? 'windows' : 'unix');

function memory()
{
	if (function_exists('memory_get_usage'))
	{
		return (memory_get_usage());
	}
	else if (OS_SERVER == 'windows')
	{
		$curent_pid = getmypid();
		exec('tasklist /FO CSV', $out);
		foreach ($out AS $line)
		{
			$split = explode(',', $line);
			if (count($split) > 1)
			{
				list($cmd, $pid, $sess, $nb, $memory) = $split;
				$pid = intval(substr($pid, 1, -1));
				if ($pid == $curent_pid)
				{
					return (intval(preg_replace('#[^0-9]#', '', $memory)));
					break;
				}
			}
		}
	}

	return (NULL);
}

class Vaisseau
{
	public $vie;
	public $attaque;
	public $pilote;

	function __construct($vie, $attaque, $pilote)
	{
		$this->vie = $vie;
		$this->attaque = $attaque;
		$this->pilote = $pilote;
	}
}

$vaisseau = array();

$begin = memory();
for ($i = 0; $i < 10000; $i++)
{
	$vaisseau[] = array(
		'vie' =>		20,
		'attaque' =>	30,
		'pilote' =>		2,
	);
}
$end = memory();
echo ($end - $begin) . ' pour le tableau<br />';


$begin = memory();
for ($i = 0; $i < 10000; $i++)
{
	$vaisseau[] = new Vaisseau(20, 30, 2);
}
$end = memory();
echo ($end - $begin) . ' pour le l\'objet<br />';

?>
affiche
5452 pour le tableau
6068 pour le l'objet
EDIT : Après benchmarck, le code avec objets met environ 20% de temps de génération en plus.


L'objet avec PHP n'a jamais été un point fort de rapidité. Cependant il a de nombreux avantages inégalables avec les tableaux.

Posté : 07 juin 2007, 17:14
par Hubert Roksor
Je ne vois pas pourquoi les objets, ca prendrait beaucoup plus de place que les variables classiques...
Ils prennent plus de place parce qu'ils nécessitent plus de place... C'est aussi simple que ça. Je ne connais pas les détails techniques de façon intime, mais si tu fais un tour du côté de n'importe quel article sur les performances [des objets] ou du côté des mailing list de PHP tu trouveras sûrement des infos à ce sujet.
De tte facon, si tu as une page un peu compliqué, qu'elle soit géré en objet ou via des fonctions, ca sera lent.
...et puis vu qu'on va tous mourrir un jour ça sert à rien de vivre. Si ta page est lente, raison de plus de ne pas l'alourdir encore plus.
Si tu doit faire face a une forte charge, il n'y a qu'une seule solution, c'est d'utiliser des systèmes de caches.
Très bien, j'aime bien les caches, merci d'avoir utiliser ce terme. Mais comment penses-tu implémenter un "cache" sur un jeu qui stocke 1000 objets pour représenter tes adversaires ? Cela ne règle pas non plus les impératifs d'utilisation de la mémoire.
Je précise que le moteur dont je parle n'est pas une page web. C'est un script que je lance, qui modifie la bdd. Je le lance lors du passage de tour et les utilisateurs ne l'utilise jamais. C'est donc un cas trés précis de traitement.
Err... c'est un script que tu lances comment ? Quelle est l'interface de ce jeu, n'est-ce pas une page web ? Si c'est un script qui est exécuté à chaque action d'un joueur la problèmatique reste la même : beaucoup de création d'objets, beaucoup de destruction d'objets, etc... (faut bien libérer la mémoire en fin de script)