Page 1 sur 1

Relecture de Code

Posté : 08 avr. 2009, 11:59
par GiorgioLino
Bonjour,

je planche actuellement sur les bugs d'une application en php. J'ai réussi plus ou moins à localiser le problème : dans la fonction init, les périmètres sont bien initialisés mais pas les sous périmètres.

Le problème ? Ben...j'ignore totalement pourquoi le code m'ayant plutôt l'air correct.

Regardez-plutôt :
<?php
require_once('DAO.class.php');

class PerimetreMgr extends DAO {

	private static $instance;
	// association with Perimetre class
	private $perimetres=array();
	// association with SousPerimetre class
	private $sousPerimetres=array();


/* Constructeur de la classe */
	protected function __construct($init){
		parent::__construct();
		$this->_init($init);
	}


/* Initialise les 2 attributs 'périmètres' et 'sousPerimetres' avec l'ensemble des valeurs en base de données */
	private function _init($init){
		$this->perimetres = array();
		$this->sousPerimetres = array();
		
		if($init){
			$q = "select * from perimetre order by nom_perimetre asc";
			$qr = parent::exec($q);
			while($row = $qr->fetch()){
				// Instanciation du périmetre
				$est_productif = ($row['est_productif'] == 1 ) ? true : false; 
				$newPerimetre = new Perimetre($row['id_perimetre'], $row['nom_perimetre'], $est_productif, "", array());
								
				try{
                      $_q = "select * from sous_perimetre where perimetre = " . $row['id_perimetre'] . " order by description asc";
  					$_qr = parent::exec($_q);
  	
  					while($_row = $_qr->fetch()){
  					// Instanciation des sous perimetre du perimetre
  					array_push($this->sousPerimetres, new SousPerimetre($_row['id_sous_perimetre'], $_row['description'], $newPerimetre));			
  					}
    		array_push($this->perimetres, $newPerimetre);
        }
        catch (PDOException $e){
            echo $e->getMessage();
        }			
			}
		}
	}


/* Crée une instance du singleton si aucune n'existe */	
	public static function getInstance($init = true) {
		if($instance == null){
			$instance = new PerimetreMgr($init);
		}
		return($instance);
	}

}
?>
Ma question est la suivante :
Est-ce qu'il y a quelque chose dans ce code qui pourrait expliquer pourquoi les sousPérimètres ne sont pas initialisés ?

Merci d'avance.

Posté : 08 avr. 2009, 13:19
par mojorisin
Bonjour,
le nom de la table des sous-périmètre me semble quelque peu exotique :)
Je pense que le soucis vient de là...

Code : Tout sélectionner

$_q = "select * from sous_perim//etre where perimetre = " . $row['id_perimetre'] . " order by description asc";

Posté : 08 avr. 2009, 13:43
par GiorgioLino
Très bonne remarque...malheureusement ce n'est pas ça.
J'avais mis ces barres pour que la requête déclenche une erreur au moment de l'accès à la base de données car la table 'sous_perim//etre' n'a évidemment aucun sens. Les logs montrent que la requête a bien été envoyée au serveur et pourtant, pas d'erreur.

D'où ma question.

P.S.
J'ai corrigé cette erreur dans mon post précédent (et mon fichier source aussi).

Posté : 08 avr. 2009, 16:56
par pascaltje
Hello,

Je vois une optimisation possible dans le code :
enlever la requête dans la boucle et utiliser une jointure pour tout sélectionner en une seule requête.

Pour le reste, ça ne saute pas aux yeux.

A+

Pascal

Posté : 09 avr. 2009, 12:08
par GiorgioLino
J'ai essayé de faire une jointure avec cette requête :
SELECT a.*, b.* FROM perimetre a, sous_perimetre b WHERE a.id_perimetre = b.perimetre ;
L'ennui c'est qu'après je ne voyais pas comment remplir mon tableau de périmètres à partir du résultat de ma requête. En effet elle renvoie plusieurs lignes avec les mêmes infos de périmètres, ce qui est normal : chaque sous-périmètre à les siennes (pour le même périmètre). Or en parcourant le tableau je n'ai pas envie de créer plusieurs fois le même périmètre et le mettre plusieurs fois dans mon tableau.

J'ai donc trouvé une autre solution : j'ai tout simplement fait deux boucles while l'une à la suite de l'autre comme ci-après :
	private function _init($init){
 		$this->perimetres = array();
		$this->sousPerimetres = array();
		
    if($init){
      try{      
          $_q = " select * from sous_perimetre order by perimetre asc ";
          $_qr = parent::exec($_q);         
          while ($_row = $_qr->fetch(PDO::FETCH_ASSOC)){
            array_push($this->sousPerimetres,new SousPerimetre($_row['id_sous_perimetre'], $_row['description'], $row['id_perimetre']));
            }      
      
          $q = "select * from perimetre order by nom_perimetre asc ";
          $qr = parent::exec($q);
          while ($row = $qr->fetch(PDO::FETCH_ASSOC)){
    				$est_productif = ($row['est_productif'] == 1 ) ? true : false; 
            array_push($this->perimetres,new Perimetre($row['id_perimetre'], $row['nom_perimetre'], $est_productif, "", array()));
            }
      }
      catch (PDOException $e){
            echo $e->getMessage();
      }
    }       
  }
De cette façon l'initialisation se fait bien et je récupère toutes les valeurs. Donc je considère le problème comme résolu.

Merci beaucoup pour le coup de main.