collection d'objets

Eléphant du PHP | 109 Messages

21 juil. 2008, 06:45

donc dans la solution de sadeq

j'obtiens une erreur
Parse error: syntax error, unexpected T_VARIABLE in C:\wamp\www\rufus\writeMenu.php on line 37

ce qui correspond dans son code a $mi[] = (MenuItems)$row; qui de toute maniere est soulignee en rouge dans l'editeur php

ViPHP
ViPHP | 4674 Messages

21 juil. 2008, 09:05

Et que te donne var_dump($row); ?

var_dump() est très pratique en PHP, c'est un peu la fonction de débuggage. On peut aussi utiliser print_r() pour afficher les tableaux, mais var_dump affiche les booléens et les valeurs nulles en plus.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 juil. 2008, 09:16

Bonjour,

Excusez moi, j'ai donné ma solution rapidement car je n'avais pas assez de temps et merci pour la bonne explication de HYWAN.

Maintenant, je la complète en ajoutant l'instanciation de l'objet MenuItems :
class MenuItems
{
   public $sm;
   public $id_menu;
   public $menu;
}

$mi = array();

$result = mysql_query("select sm, id_menu, menu from ....");

while($row = mysql_fetch_object($result))
{
  if ($row) {
       // Instanciation de l'objet MenuItem
       $o = new MenuItems();
       // Affectation de contenu 
       $o = $row;
       // Stockage dans la collection
       $mi[] = $o;
  }
}

foreach ($mi as $menuItem) {
    echo $menuItem->sm, $menuItem->id_menu, $menuItem->menu;
}
exit; 
Modifié en dernier par sadeq le 21 juil. 2008, 09:27, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 109 Messages

21 juil. 2008, 09:21

dans l'editeur la ligne $o = (MenuItems)$row; est soulignee en rouge

et j'obtiens toujours Parse error: syntax error, unexpected T_VARIABLE in C:\wamp\www\rufus\writeMenu.php on line 31

si je fais un

var_dump($row);
exit;
//$o = (MenuItems)$row;



j'obtiens mes valeurs
object(stdClass)#1 (3) { ["id_menu"]=> string(1) "1" ["sm"]=> string(1) "1" ["menu"]=> string(4) "Voyage" }
Modifié en dernier par rufus_ le 21 juil. 2008, 09:29, modifié 1 fois.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 juil. 2008, 09:28

C'est effectivement le casting qui n'est pas supporté dans cette ligne : $o = (MenuItems)$row;
à remplacer par : $o = $row;
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 109 Messages

21 juil. 2008, 09:30

oui la ça marche, j'obtiens la meme chose qu'avec la methode de HyWaN

mais en ce cas je peux supprimer la ligne
$o = new MenuItems();
et ma class MenuItems ne sert a rien

je peux ecrire

if ($row) {
$mi[] = $row;
}

en tout cas cette methode est rapide

est il possible d'utiliser la cle pour stocker l'id_menu par exemple ?

au lieu du
$mi[] = $row;
du genre
$key = $row['id_menu'];
$mi[$key] = $row;



merci encore

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 juil. 2008, 10:08

Oui, tu peux utiliser cette clé comme ça bien sûr en écrivant :
$key = $row->id_menu;
$mi[$key] = $row; 
Mais si tu enlève l'instanciation de la classe MenuItems tu ne peux pas utiliser ses méthodes. Si ta classe ne contient pas de méthodes (fonctions) spéciales et se limite à des propriétés (champs) alors là tu peux ne pas l'utiliser et utiliser directement $row qui est déjà un objet issu de mysql_fetch_object().
Modifié en dernier par sadeq le 21 juil. 2008, 10:09, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 109 Messages

21 juil. 2008, 10:08

mais tu as supprime l'instanciation $o = new MenuItems(); car elle plantait
et en ce cas ma class MenuItems n'est pas utilisee

en tout cas ton code marche nikel sans la class menuitem et donc sans instanciation
avec

while($row = mysql_fetch_object($result))
{
$mi[$row->id_menu] = $row;
}

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 juil. 2008, 10:13

Non, j'ai supprimé le casting (conversion) de $row vers $o qui est un objet dument instancié au paravant.
Le casting sert simplement pour convertir un objet en un autre en utilisant une classe apparentée. Les objets sujets au casting par contre, doivent être instanciés (créés) au paravant selon le modèle objet. Si PHP n'a pas supporté cette forme de casting les langages objets le supporte et donc PHP le fait automatiquement par affectation.

Voici le récap du code :
class MenuItems
{
   public $sm;
   public $id_menu;
   public $menu;
}

$mi = array();

$result = mysql_query("select sm, id_menu, menu from ....");

while($result && $row = mysql_fetch_object($result))
{
  if ($row) {
       // Instanciation de l'objet MenuItem
       $o = new MenuItems();
       // Affectation de contenu 
       $o = $row;
       // Stockage dans la collection indéxée par id_menu
       $key = $row->id_menu;
       $mi[$key] = $o;
  }
}

foreach ($mi as $menuItem) {
    echo $menuItem->sm, $menuItem->id_menu, $menuItem->menu;
}
exit(); 
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 109 Messages

21 juil. 2008, 10:18

effectivement ça marche
mais si je fais

Code : Tout sélectionner

class MenuItems { public $sm; public $id_menu; public $menu; } $mi = array(); $result = mysql_query("select sm, id_menu, menu, XXX from ...."); while($row = mysql_fetch_object($result)) { if ($row) { // Instanciation de l'objet MenuItem $o = new MenuItems(); // Affectation de contenu $o = $row; // Stockage dans la collection indéxée par id_menu $key = $row->id_menu; $mi[$key] = $o; } } foreach ($mi as $menuItem) { echo $menuItem->sm, $menuItem->id_menu, $menuItem->menu, $menuItem->XXX; } exit();
la valeur XXX contenue dans la requête($result) et appelée dans le foreach est trouvée $menuItem->XXX alors qu'elle n'existe pas dans la class MenuItems

il faut juste que je m'habitue bien sur , mais la je comprend pas comment une valeur non définie dans la class MenuItems est trouvée , ou alors a quoi sert la class dans ce cas puisque c'est censé faire un genre de collection d'objets et qu'un intrus s'y ajoute sans générer d'erreur

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 juil. 2008, 11:41

Ok, en fait, en l'absence du casting sous PHP, ce dernier ne fait pas la conversion de type à type mais retype (recrée l'objet sujet de l'affectation) en l'occurence, il écrase l'objet MenuItems et le remplace par la définition de celui affecté ($row). Ce qui explique la prise en compte du champ XXX.
La preuve est que le type de l'objet reste : stdClass. Ce qui veut dire classe standard inconnue.

Pour palier à ce problème il faut toujours instancier correctement l'objet MenuItem en lui affectant les valeurs de $row et non l'objet $row lui-même.
if ($row) {
       // Instanciation de l'objet MenuItem et Stockage dans la collection indéxée par id_menu
       $key = $row->id_menu;
       $mi[$key] = new MenuItems();
       $mi[$key]->sm = $row->sm;
       $mi[$key]->id_menu = $row->id_menu;
       $mi[$key]->menu = $row->menu;
  } 
Mais voici un développement possible de ton script vers une vision globale de collection d'objets:
<pre>
<?php
mysql_connect("localhost", "root", ""); mysql_select_db("test");

//
class MenuItems
{
   // Propriétés de la classe
   private $id_menu;
   private $menu;
   private $sm;
   
   // Propriétés de la collection
   private $currentIndex;
   private $collection;
   
   // Constructeur de la classe
   public function MenuItems($id_menu=null, $menu=null, $sm=null){ // Params facultatifs
	$this->id_menu 	= $id_menu;
	$this->menu 	= $menu;
   	$this->sm 		= $sm;
   }
   // Méthodes SET pour les propriétés privées
   public function setId_menu($id_menu){
   	$this->id_menu 	= $id_menu;
   }  
   public function setMenu($menu){
   	$this->menu = $menu;
   }  
   public function setSm($sm){
   	$this->sm = $sm;
   } 
   // Méthodes GET pour les propriétés privées
   public function getId_menu(){
   	return $this->id_menu;
   }  
   public function getMenu(){
   	return $this->menu;
   }  
   public function getSm(){
   	return $this->sm;
   } 
   // Méthodes : Ajout, Recherche,  Suppression dans la collection
   public function exists($id_menu){
   	if (count($this->collection)>0 && $this->collection[$id_menu]) return true; else return false;
   }  
   public function add($menuObject){
   	if ($menuObject->id_menu && ! $this->exists($menuObject->id_menu)){
		$this->collection[$menuObject->id_menu] = new MenuItems($menuObject->id_menu, $menuObject->menu, $menuObject->sm);
	}
   }
   public function getObject($id_menu){
   	if ($id_menu && $this->exists[$id_menu]) return $this->collection[$id_menu];
   }  
   public function remove($id_menu){
   	if ($id_menu && $this->exists[$id_menu]) unset($this->collection[$id_menu]);
   }
   // iterator : Naviguer dans la collection
   public function getCollectionKeys(){
   	return array_keys($this->collection);
   }
   public function getCollectionSize(){
   	return count($this->collection);
   }
   public function current(){
	$keys = $this->getCollectionKeys();
	$currentKey = $this->currentIndex > 0 ? $keys[$this->currentIndex] : null;
   	if ($currentKey && $this->collection[$currentKey]){
		$this->id_menu 	= $this->collection[$currentKey]->id_menu;
		$this->menu 	= $this->collection[$currentKey]->menu;
		$this->sm 		= $this->collection[$currentKey]->sm;
		//		
		return $this->collection[$currentKey];
	}  
	else return null;
   }  
    public function first(){
	$this->currentIndex = 0;
	return $this->current();
   }  
   public function next(){
	$this->currentIndex ++;
	return $this->current();
   }  
   public function previous(){
	$this->currentIndex --;
	return $this->current();
   }  
   public function last(){
	$this->currentIndex = $this->getCollectionSize()-1;
	return $this->current();
   }  
}
//
$mi = new MenuItems();
//
$result = mysql_query("select id_menu, menu, sm from menu");
while($result && $row = mysql_fetch_object($result))
{
  if ($row) {
       // Alimentation de la collection d'objets MenuItem
       $mi->add($row);
  }
}
//
while ($mi->next()) {
   echo $mi->getId_menu(), $mi->getMenu(), $mi->getSm();
} 
?>
</pre>
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 109 Messages

21 juil. 2008, 12:08

ta premier champ

Code : Tout sélectionner

marche très bien j'ai un problème sur le second (développement possible ect ...) [b]Warning: array_keys() [function.array-keys]: The first argument should be an array in C:\wamp\www\rufus\menuTest.php on line 67[/b] qui correspond a [b]return array_keys($this->collection);[/b]

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

21 juil. 2008, 12:13

lol, j'ai opéré quelques modifs et notamment le test sur array_keys qui ne supporte que les tableaux.

J'ai modifié aussi le comportement de l'itterator : next(), previous() ... pour que la lecture de la collection soit séquentiel du début jusqu'à la fin
<pre>
<?php
mysql_connect("localhost", "root", ""); mysql_select_db("test");

//
class MenuItems
{
   // Propriétés de la classe
   private $id_menu;
   private $menu;
   private $sm;
   
   // Propriétés de la collection
   private $currentIndex;
   private $collection;
   
   // Constructeur de la classe
   public function MenuItems($id_menu=null, $menu=null, $sm=null){ // Params facultatifs
	$this->id_menu 	= $id_menu;
	$this->menu 	= $menu;
   	$this->sm 		= $sm;
   }
   // Méthodes SET pour les propriétés privées
   public function setId_menu($id_menu){
   	$this->id_menu 	= $id_menu;
   }  
   public function setMenu($menu){
   	$this->menu = $menu;
   }  
   public function setSm($sm){
   	$this->sm = $sm;
   } 
   // Méthodes GET pour les propriétés privées
   public function getId_menu(){
   	return $this->id_menu;
   }  
   public function getMenu(){
   	return $this->menu;
   }  
   public function getSm(){
   	return $this->sm;
   } 
   // Méthodes : Ajout, Recherche,  Suppression dans la collection
   public function exists($id_menu){
   	if (count($this->collection)>0 && $this->collection[$id_menu]) return true; else return false;
   }  
   public function add($menuObject){
   	if ($menuObject->id_menu && ! $this->exists($menuObject->id_menu)){
		$this->collection[$menuObject->id_menu] = new MenuItems($menuObject->id_menu, $menuObject->menu, $menuObject->sm);
	}
   }
   public function getObject($id_menu){
   	if ($id_menu && $this->exists($id_menu)) return $this->collection[$id_menu];
   }  
   public function remove($id_menu){
   	if ($id_menu && $this->exists($id_menu)) unset($this->collection[$id_menu]);
   }
   // iterator : Naviguer dans la collection
   public function getCollectionKeys(){
   	return is_array($this->collection) ? array_keys($this->collection) : 0;
   }
   public function getCollectionSize(){
   	return count($this->collection);
   }
   public function current(){
	$keys = $this->getCollectionKeys();
	$currentKey = $this->currentIndex >= 0 ? $keys[$this->currentIndex] : null;
   	if ($currentKey && $this->collection[$currentKey]){
		$this->id_menu 	= $this->collection[$currentKey]->id_menu;
		$this->menu 	= $this->collection[$currentKey]->menu;
		$this->sm 		= $this->collection[$currentKey]->sm;
		//		
		return $this->collection[$currentKey];
	}  
	else return null;
   }  
    public function first(){
	$this->currentIndex = 0;
   }  
   public function next(){
	$this->currentIndex ++;
   }  
   public function previous(){
	$this->currentIndex --;
   }  
   public function last(){
	$this->currentIndex = $this->getCollectionSize()-1;
   }  
}
//
$mi = new MenuItems();
//
$result = mysql_query("select id_menu, menu, sm from menu");
while($result && $row = mysql_fetch_object($result))
{
  if ($row) {
       // Alimentation de la collection d'objets MenuItem
       $mi->add($row);
  }
}
//
$mi->first();
while ($mi->current()) {
   echo "<b>Id Menu: </b>", $mi->getId_menu(),"<br />", "<b>Menu: </b>",$mi->getMenu(),"<br />", "<b>Sm: </b>",$mi->getSm(),"<br />";
   $mi->next();
} 
?>
</pre>
Modifié en dernier par sadeq le 21 juil. 2008, 12:34, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 109 Messages

21 juil. 2008, 12:24

je viens de retester , en copiant collant tout ton code
mais l'echo me donne rien , une page blanche

mais bon la c'est une caisse de biere que je vais te devoir !!

ViPHP
ViPHP | 4674 Messages

21 juil. 2008, 12:32

Je ne sais pas si tu comprends tout ce que fait Sadeq en fait.
Il n'implémente pas les interfaces, mais c'est tout comme. En fait, on pourrait ajouter : implements Iterator, par exemple.
Si tu regardes un des premiers liens que je t'avais donné sur ArrayObjet, on peut voir que cette classe implémente ArrayIterator, Iterator, et des choses du genre. C'est de là que viennent les méthodes next, previous, last, etc.
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).