probleme jointure en POO

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : probleme jointure en POO

Re: probleme jointure en POO

par juliette » 19 juil. 2012, 13:37

je n'en attendais pas tend, je travail la dessus, un grand merci Moogli :D

Re: probleme jointure en POO

par moogli » 19 juil. 2012, 12:49

ok, merci moogli...
pour les ereurs, j'i compris comment faire en revanche pour la factorisation je ne m'en sort pas, je vois bien le code qui se repete mais je ne comprend pas comment faire, peut tu me montrer un exemple ou un tuto, tous ce que je trouve sur google ne correspond pas a ce que je cherche...
je commence par corriger mon annerie précédente ;)
<?php
$save = null;
while( $req){
if($save !== null && $req-> blog !== $save){ // on affiche le nouveau blog seulement le nouveau est différent de l'ancien et pas s'il est égale ;)
$save = $req->blog;
// affichage de la séparation
echo 'affichage du nouveau blog';
}
echo 'affichage du commentaire quelque soit le blog';
}
?>
quand à la factorisation :

tu a dans classe un bout de code qu se répète dans toutes tes méthodes
if ($critere !== null)
            $critere = array_values($critere);
        $select = $this->pdo->prepare($requete);
        $select->execute($critere);
tu peux très bien partir du principe que ceci est "autonome" et qu'il peux être utiliser dans une méthode privée qui est appelée dans chaqu'une des autres méthodes.

Sur le même principe update et insert sont identiques (elles font exactement la même, même si les variables n'ont pas les mêmes nom ;)) on peux donc réduire l'utilisation de ces méthodes à une seule.
En regardant de plus pret on se rend compte que cette méthode peux être utilisée dans les autres.

ça peux donner ceci
<?php

class connexion {
	private $host;
	private $user;
	private $pass;
	private $conn;
	private $pdo;

	public function __construct($bdd = "genea_bdd") {
		$this->host = "localhost";
		$this->user = "root";
		$this->pass = "";
		$this->conn = "host={$this->host};dbname={$bdd}";
		try {
			$this->pdo = new PDO('mysql:'.$this->conn, $this->user, $this->pass);
			$this->pdo->setAttribute(PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			// on lève une exception avec un message perso on affiche pas l'erreur à la barbare :)
			throw new Exception('Connexion au serveur MySQL impossible : '. $e->getMessage());
		}
	}
// on  fait les tests + requete et on retourne l'objet $select
// vérifie le comportement avec les update / insert
	public function execQuery($critere, $requete){
		if ($critere !== null)
			$critere = array_values($critere);
		else
			throw new Exception('critère null  normal ?');
		if($requete === null)
			throw new Exception('La requete ne peux être nul');
		$select = $this->pdo->prepare($requete);
		$ret = $select->execute($critere);
		if ($ret === false){
			$err = $this->pdo->errorInfo();
			throw  new PDOException('Erreur SQL : '.$errr[2]);
		}
		return $select;
	}
	// fonction pour rechercher un resultat unique
	public function unique($critere, $requete) {
		$select = $this->execQuery($critere, $requete);
		$select->setFetchMode(PDO :: FETCH_OBJ);
		$objet = $select->fetch();
		return $objet;
	}

	// fonction pour faire une boucle
	public function boucle($critere, $requete) {
		$select = $this->execQuery($critere, $requete);
		$select->setFetchMode(PDO :: FETCH_OBJ);
		// retour les résultat dans un table et non l'objet car la vue ou autre n'a pas connaitre la "sauce" que tu utilise ;)
		return $select->fetchAll();
	}

	// fonction pour comptre des champs
	// Attention ça foncitonne pas tout le temps ça, il est préférable de faire un select count(*) si tu veux un truc plus universel
	// ou un fetchAll + un count php
	//
	function compte($critere, $requete) {
		$count = $this->execQuery($critere, $requete);
		$nombre = $count->rowCount();
		return $nombre;
	}
/*
 * // on supprime au profit de la méthode execQuery, on se fiche de savoir s'il s'agit d'un insert ou d'un update c'est pareil (à la limite idem pour un select / delete ;) )
	public function insert($critere, $requete) {
		$insert = $this->execQuery($critere, $requete);
	}

	public function update($critere, $requete) {
		$update = $this->execQuery($critere, $requete);
	}
*/
}

?>
au final tu n'a plus que
  • ExecQuery : qui permet d’exécuter une requête (si si) a utiliser pour tous ce que tu veux :)
  • Boucle : toujours la même chose, hors mis le fait que je lui fait retourner un tableau (d'objet) et non plus l'objet pdoStatement, cela permet de séparer completement la couche DAO (accès aux données) des autres (affichage ou métier) et donc tu pourra changer comme tu veux ta façon de faire pour les requêtes tant qu'elle retourne un tableau c'est pas un problème :)
  • Unique : pareil, mais la j'airien fait, hors mis la factorisation
tu a 2 méthodes inutile en moins et une générique en plus :)

la factorisation c'est ça, ni plus ni moins. Dès que tu a un bout de code qui se répete tu le déporte dans une fonction, ou une méthode suivant le cas.
Tu peux même créer un objet pour cela si besoin, vois même, avec php 5.4, un trait qui va te permettre de faire des bibliothèque de fonction générique ;) (j'ai vue un article où le gars créer un trait permettant de créer un singleton générique pour les classes, tu a juste a passer ton constructeur en privé et utiliser le traits.

etc etc.

@+

Re: probleme jointure en POO

par juliette » 16 juil. 2012, 12:27

ok, merci moogli...
pour les ereurs, j'i compris comment faire en revanche pour la factorisation je ne m'en sort pas, je vois bien le code qui se repete mais je ne comprend pas comment faire, peut tu me montrer un exemple ou un tuto, tous ce que je trouve sur google ne correspond pas a ce que je cherche...

Re: probleme jointure en POO

par moogli » 10 juil. 2012, 00:00

Césure : dans notre cas cela consiste à organiser le changement de ligne.

Par exemple tu garde le blog courant et à chaque "tour" de while tu compare avec celui du tour d'avant.
Exemple
<?php
$save = null;
while( $req){
if($save !== null && $req-> blog === $save){
$save = $req->blog;
// affichage de la séparation 
echo 'affichage du nouveau blog';
}
echo 'affichage du commentaire quelque soit le blog';
}
?>
Quand au reste c'est assez "simple"

Factoriser c'est comme en math ;). Le but est de réduire le code au maximum.
C'est que tu fait en création une fonction ou une classe que tu va ré employer. (plus besoin de copier / coller partout la connexion pdo ou autre test de validation etc etc.

Le traitement d'erreur la le but c'est de faire en sorte que les messages d'erreurs s'affichent ( ou pas ) de façon à ce que le site reste navigable. Donc supprimer les Die et exit qui parfois pullule dans les scripts et empêche la page de s'afficher totalement.

Cela passe, par exemple, par l'utilisation de try / catch et le fait de vérifier les retours de fonction pour éviter les messages d'erreur du à un retour null / false.
Ça permet aussi de logger les erreurs pour les analyser ensuite (par exemple). Ça permet de masque les véritables erreurs afin de ne pas montrer à tout le monde des infos qui pourrait être utilisée à ton encotre ;).


@+

Re: probleme jointure en POO

par juliette » 09 juil. 2012, 13:36

cool Mazarini, merci...
j'ai bien l’intention de la continuer, mais la tu vois ton post tombe a point, par exemple je ne comprend pas:
je factoriserai du code présent dans beaucoup de tes fonctions dans une fonction privée
traiter les erreurs qui provoquent une fin de script dans cette classe pour ne traiter que de l'applicatif dans la partie qui utilise la classe. Je pense au "non trouvé" et au "clé en double"
la est mon vrai problème, bien souvent je ne comprend que la moitié de ce qu'on me dis... #-o je ne désespère pas, ça viendras :wink:
merci a tous =D>

Re: probleme jointure en POO

par Mazarini » 09 juil. 2012, 13:22

Bonjour,

Je trouve ton code bien. Il manque une fonction pour le delete. Eventuellement, je factoriserai du code présent dans beaucoup de tes fonctions dans une fonction privée.

Il pourrait être intéressant de retourner l'id en cas d'insert, le nombre de lignes touchées en cas d'update ou de delete.

Pour les erreurs, tu pourrais déjà traiter les erreurs qui provoquent une fin de script dans cette classe pour ne traiter que de l'applicatif dans la partie qui utilise la classe. Je pense au "non trouvé" et au "clé en double"

Re: probleme jointure en POO

par juliette » 09 juil. 2012, 13:11

et je fait une requete comme ca:
<?php
                                                $bdd = new connexion ();
                                                $critere = array();
                                                $requete = "SELECT * FROM members";
                                                $resulta = $bdd->boucle($critere, $requete);

                                                while ($champ = $resulta->fetch()) {
                                                    echo'
                                                    <tr>
                                                        <td>
                                                            '.$champ->member_id.'
                                                        </td>
                                                        <td>
                                                            '.$champ->firstname.'
                                                        </td>
                                                        <td>
                                                            '.$champ->lastname.' 
                                                        </td>
                                                        <td>
                                                            '.$champ->email.' 
                                                        </td>
                                                        <td>
                                                            '.date('j-m-Y à H:i:s', $champ->inscription).' 
                                                        </td>
                                                    </tr>';
                                                }
                                                ?>
en fait, on est sorti du sujet...
mon test avec la 1er classe était d'afficher le dernier post du blog avec ses commentaires et j'ai voulu faire le tout en une requête mais impossible de séparer les commentaires et blogs des objets, tu ma proposer césure et j'ai chercher mais je n'ai trouver que sur des chaines donc je n'ai pas réussi alors j'ai fait une requête pour avoir le dernier blog et ensuite une jointure pour avoir les message de ce dernier blog, et tous fonctionne bien même avec ta classe...
ensuite j'ai voulu préparer mes fonctions pour les requête mais la non plus, je n'ai rien réussi alors j'ai tous recommencer pour arriver a la dernière classe que j'ai affiché au dessus.
voila en gros l'historique de mes déboires avec php pour cet exercice :?

Re: probleme jointure en POO

par juliette » 09 juil. 2012, 12:55

je ne sais pas trop ce que je ne comprend pas, et ce n'est pas réellement que je ne comprend pas mais plutôt que j'avance trop vite je pense sans avoir une maîtrise complète de ce que je connais déjà...
en procédurale j'arrive a faire ce dont j'ai besoin mais la avec les objets, je ne comprend plus rien...
quand j'ai commencer avec cette classe, j'avais le but de faire une classe pour tous les types de requête que j'utilise et je n'ai rien réussi a faire avec la connexion que tu m'a donner pourtant elle fonctionne très bien, pour le coup j'ai tous recommencer et j'en suis arrivé la:
class connexion {
<?php
    private $host;
    private $user;
    private $pass;
    private $conn;
    private $pdo;

    public function __construct($bdd = "genea_bdd") {
        $this->host = "localhost";
        $this->user = "root";
        $this->pass = "";
        $this->conn = "host={$this->host};dbname={$bdd}";
        try {
            $this->pdo = new PDO("mysql:$this->conn", $this->user, $this->pass);
            $this->pdo->setAttribute(PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);
        } catch (PDOException $e) {
            echo "error " . $e->getMessage();
        }
    }
    
    // fonction pour rechercher un resultat unique
    public function unique($critere, $requete) {
        if ($critere !== null)
            $critere = array_values($critere); 
        $select = $this->pdo->prepare($requete);
        $select->execute($critere);
        $select->setFetchMode(PDO :: FETCH_OBJ);
        $objet = $select->fetch();
        return $objet;
    }

    // fonction pour faire une boucle
    public function boucle($critere, $requete) {
        if ($critere !== null)
            $critere = array_values($critere); 
        $select = $this->pdo->prepare($requete);
        $select->execute($critere);
        $select->setFetchMode(PDO :: FETCH_OBJ);
        return $select;
    }

    // fonction pour comptre des champs
    function compte($critere, $requete) {
        if ($critere !== null)
            $critere = array_values($critere);
        $count = $this->pdo->prepare($requete);
        $count->execute($critere);
        $nombre = $count->rowCount();
        return $nombre;
    }

    public function insert($critere, $requete) {
        if ($critere !== null)
            $critere = array_values($critere);
        $insert = $this->pdo->prepare($requete);
        $insert->execute($critere);
    }
    
    public function update($critere, $requete) {
        if ($critere !== null)
            $critere = array_values($critere);
        $update = $this->pdo->prepare($requete);
        $update->execute($critere);
    }

}

?>
peut être un mélange entre les différences version de php, je ne sais pas trop te dire. quoi qu'il en soit, je suis souvent dans la flou...

merci d'avance pour tous...

Re: probleme jointure en POO

par moogli » 09 juil. 2012, 09:03

ce que je ne comprend pas toujours, ce sont les thermes employé et les sous entendus sur les actions de php...
dit nous ce que tu ne comprend pas, on peux t'expliquer (c'est d'ailleurs pour cela que l'on traine ici :)).

au pire on te filera un liens ves un bon tuto :mrgreen:


@+

Re: probleme jointure en POO

par juliette » 07 juil. 2012, 12:43

bon, encore un peut complexe pour moi, je suis revenu sur un code plus simple, ce que je ne comprend pas toujours, ce sont les thermes employé et les sous entendus sur les actions de php...
je n'abandonne pas l'objet :non: , au contraire mais je dois continuer a lire des trucs avant de vraiment pouvoir continuer... #-o

Re: probleme jointure en POO

par moogli » 04 juil. 2012, 16:56

Pour l'affichage il faut que tu fasse une "césure" dans la boucle pour n'afficher que les commentaire associé au "blog" et ainsi ne pas afficher toutes les autres infos. (en gros tu garde le nom / l'id du blog dans une variable et a chaque tour tu regarde si celui gardé est le même que celui "actuel" tu n'affiche que les commentaires, sinon tu affiche tout et remplace la sauvegarde par le nouveau.

en plus clair
<?php
$save = null;
while($truc) {
if (save != $truc->id){
$save = $truc->id;
echo 'j affiche les infos "globale"';
}
echo 'j affiche le commentaire courant';
}
?>
@+

Re: probleme jointure en POO

par xTG » 04 juil. 2012, 14:21

echo $array[0]->titre;
Par exemple. :)

Re: probleme jointure en POO

par juliette » 04 juil. 2012, 14:10

en fait, je n'aurais pas su faire, je ne saisie pas encore tous...
la j'obtiens avec:
array
  0 => 
    object(stdClass)[5]
      public 'id_blog' => int 1
      public 'titre' => string 'titre' (length=5)
      public 'intro' => string 'intro' (length=5)
      public 'member_post_bl' => int 1
      public 'timestamp' => int 1330873498
      public 'id_com' => int 1
      public 'member_post_com' => int 1
      public 'com_id_blog' => int 1
      public 'commentaire' => string 'commentaire' (length=11)
      public 'com_timestamp' => int 0
  1 => 
    object(stdClass)[6]
      public 'id_blog' => int 1
      public 'titre' => string 'titre' (length=5)
      public 'intro' => string 'intro' (length=5)
      public 'member_post_bl' => int 1
      public 'timestamp' => int 1330873498
      public 'id_com' => int 2
      public 'member_post_com' => int 1
      public 'com_id_blog' => int 1
      public 'commentaire' => string 'commentaire 2' (length=13)
      public 'com_timestamp' => int 0
je t'avoue que je suis bien largué mais ça viendras mais pour le coup, je ne sais pas trop comment récupérer les informations des objets.
comme tu peux le voir, chaque objets contient le post du blog et 1 commentaire...

Re: probleme jointure en POO

par moogli » 04 juil. 2012, 13:34

J'avoue qu'a part l'ajout du message d'erreur je ne vois pas trop de modif :)

je voyais plutôt vu quelque chose comme ça
<?php 
class DB extends PDO{

	private $host = 'localhost';
	private $username = 'root';
	private $password = '';
	private $database = 'chien-drouais';
	private $db;
	/**
	 * Constructeur
	 * @param String $host
	 * @param String $database
	 * @param String $username
	 * @param String $password
	 * @throws \Exception
	 */
	public function __construct($host = null, $database = null, $username = null, $password = null) {
		if (empty($host) == false) { // donc en considérant qu'un accès annonyme est possible et qu'un use laBase sera fait
			$this->host = $host;
			$this->username = $username;
			$this->password = $password;
			$this->database = $database;
		}
		try {
			parent::__construct('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->username, $this->password,
					array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8', PDO::ERRMODE_EXCEPTION);
		} catch (PDOException $e) {
			throw new \Exception('<h1>Impossible de se connecter a la base de donnees !</h1>'.$e->getMessage());
		}
	}
	/**
	 * Retourne tout les résultats de la requete dans un tableau d'objet
	 * @see PDO::query()
	 */
	public function query($sql) {
		if (empty($sql) == false){
			$req = parent::query($sql);
			return $req->fetchAll(PDO::FETCH_OBJ);
		}
		else {
			throw new Exception('La requete SQL ne peux être vide');
		}
	}
}
?>
A tester

par contre si ta requete est fonctionnelle, ça ne devrait pas poser de problème.

Essai en ajoutant des var_dump() dans la classe pour vori ce que retourne l'execute.

Ma remarque quand l'execute est que tu n'a pas besoin de faire une requete préparé quand tu n'utilise pas ce mécanisme.
Les requete préparée sont utile dans le cas d'utilisation massive d'une requête, par exemple lors d'insertion en base des données d'un fichier c'est utilise et tu peux gagner en perf façon un l'utilisation d'une requete "normale".
Mais la aucun besoin, cette utilisation n'apporte absolument rien dans ton cas ;)

Re: probleme jointure en POO

par juliette » 04 juil. 2012, 13:12

bon, je pense avoir correctement corrigé la classe, en tous cas ça marche...
<?php

Class DB {

    private $host = 'localhost';
    private $username = 'root';
    private $password = '';
    private $database = 'chien-drouais';
    private $db;

    public function __construct($host = null, $database = null, $username = null, $password = null) {
        if ($host != null) {
            $this->host = $host;
            $this->username = $username;
            $this->password = $password;
            $this->database = $database;
        }
        try {
            $this->db = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->username, $this->password,
                        array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES UTF8', PDO::ERRMODE_EXCEPTION, PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
        } catch (PDOException $e) {
            die($e->getMessage().'<h1>Impossible de se connecter a la base de donnees !</h1>');
        }
    }

    public function query($sql) {
        $req = $this->db->prepare($sql);
        $req->execute();
        return $req->fetchAll(PDO::FETCH_OBJ);
    }

}

?>
donc, j'ai maintenant besoin d'une 2eme fonction autre que prépare: c'est bien ça ???