Page 1 sur 1

[POO] Liaison entre les classes

Posté : 22 mai 2008, 17:06
par agité
Bonjour,

voilà j'ai réaliser une première petite classe pour gérer mes connections sql et les requtes.

maintenant j'ai une 2ème classe pour gérer des programmes.

Dans cette 2ème classe j'ai besoin des requête de la 1ère classe, mais je pense que faire une extension de classe n'est pas bon, enfin c'est 2 classes sont différentes, l'une utilise une partie de l'autre mais je pense pas que ca soit la bonne solution.

Par exemple je veux ajouter un nouveau programme donc j'utilise un appel de classe de ma classe dbquery pour pouvoir exécuter les requêtes.

Une idée ?

Posté : 23 mai 2008, 09:45
par vince_weed
L'extension de classe n'est en effet pas adaptée a ce genre de situation elle permet plustôt de créer une classe à partir d'une autre en lui ajoutant des méthodes/attributs supplémentaires mais qui reste dans le même style (notion d'héritage plustôt utilisée en partant d'une classe abstraite par exemple).

pour ca genre de problème je te conseillerai d'utiliser la notion de package qui permet de regrouper des classe et ainsi d'accéder au fonction d'une classe depuis une autre, ou d'utiliser la fonction "require_once" qui importe une classe dans une autre (en fait son appel est équivanlent à copier entierement une classe dans une autre sauf que ca tiend sur une petite ligne :) ).

Dans ton cas je ferai un "require_once" de ta classe permettant l'acces a la DBB et aux requetes SQL dans les classes qui on besoin d'interagir avec ta BDD.

Mais bon j'ai peut etre mal compri ton probleme donc si besoin hésite pas à préciser :wink:

Posté : 23 mai 2008, 10:00
par agité
L'extension de classe n'est en effet pas adaptée a ce genre de situation elle permet plustôt de créer une classe à partir d'une autre en lui ajoutant des méthodes/attributs supplémentaires mais qui reste dans le même style (notion d'héritage plustôt utilisée en partant d'une classe abstraite par exemple).

pour ca genre de problème je te conseillerai d'utiliser la notion de package qui permet de regrouper des classe et ainsi d'accéder au fonction d'une classe depuis une autre, ou d'utiliser la fonction "require_once" qui importe une classe dans une autre (en fait son appel est équivanlent à copier entierement une classe dans une autre sauf que ca tiend sur une petite ligne :) ).

Dans ton cas je ferai un "require_once" de ta classe permettant l'acces a la DBB et aux requetes SQL dans les classes qui on besoin d'interagir avec ta BDD.

Mais bon j'ai peut etre mal compri ton probleme donc si besoin hésite pas à préciser :wink:

c'est tout a fait ce que je veux faire, ajouter donc un require_once sur la page ou j'appel la classe de bdd.

Mais ensuite comment je fais pour faire appel a cette classe dans une autre classe ?

il faut que je fasse comme pour un script et faire un new maclasse ? ou l'appeler via $this->maclasse->mafonction ?

Posté : 23 mai 2008, 10:16
par vince_weed
Tu place ton "require_once" au début de ton fichier puis tu fait comme si ta classe était écrite en dur a la place du "require_once".
Donc un simple" $MyClass() = new MyClass; " suffit à en créer une instance puis tu utilise ton objet comme comme tu en à envie.

Posté : 23 mai 2008, 10:21
par agité
Tu place ton "require_once" au début de ton fichier puis tu fait comme si ta classe était écrite en dur a la place du "require_once".
Donc un simple" $MyClass() = new MyClass; " suffit à en créer une instance puis tu utilise ton objet comme comme tu en à envie.
Oui c'est sur quoi je bloque depuis hier et pourtant j'ai bien utiliser ca :
// Appel de la classe bdd
require_once("dbfactory.php");

$bdd = new dbquery();

// Classe de gestion des programmes
class programme {

	function misenavant($id_programme,$id_etat)
	{
		$req = $bdd->req_query("UPDATE programme SET est_mis_en_avant = ".$id_etat." WHERE id_programme = '".$id_programme."' ");
	}
}
donc j'appel la classe et ensuite je fais comme pour mes autres script mais il me retourne :

Code : Tout sélectionner

Fatal error: Call to a member function req_query() on a non-object in programme.php on line 11

Posté : 23 mai 2008, 10:33
par vince_weed
essaye :


// Classe de gestion des programmes 
class programme 
{

// Appel de la classe bdd 
require_once("dbfactory.php"); 

$bdd = new dbquery(); 
 

    function misenavant($id_programme,$id_etat) 
    { 
        $req = $bdd->req_query("UPDATE programme SET est_mis_en_avant = ".$id_etat." WHERE id_programme = '".$id_programme."' "); 
    } 
}
la je pense que ca recrée une variable $bdd dans ta class puisque ton premier $bdd est crée en dehors du coup il essaye d'utiliser une proprièté de ta classe sur une simple variable apellée $bdd mais qui n'est en aucun cas une instance de ta classe bdd :wink:

Posté : 23 mai 2008, 10:45
par agité
apparement il attends une fonction plutôt qu'un include ou appel d'une autre classe :cry:

Posté : 23 mai 2008, 10:51
par vince_weed
La j voit pas, essaye

// Appel de la classe bdd  
require_once("dbfactory.php");  

// Classe de gestion des programmes  
class programme  
{ 

$bdd = new dbquery();  
  

    function misenavant($id_programme,$id_etat)  
    {  
        $req = $bdd->req_query("UPDATE programme SET est_mis_en_avant = ".$id_etat." WHERE id_programme = '".$id_programme."' ");  
    }  
}
et post ta classe dbquery() pour voir ce qu'il y a dedans

Re: [POO] Liaison entre les classes

Posté : 23 mai 2008, 10:57
par Berzemus
Bonjour,

voilà j'ai réaliser une première petite classe pour gérer mes connections sql et les requtes.

maintenant j'ai une 2ème classe pour gérer des programmes.

Dans cette 2ème classe j'ai besoin des requête de la 1ère classe, mais je pense que faire une extension de classe n'est pas bon, enfin c'est 2 classes sont différentes, l'une utilise une partie de l'autre mais je pense pas que ca soit la bonne solution.
Pardon, mais je trouve très flou le require_once dans l'instantiation de ta classe programme..
Je crains que l'objet ne soit pas encore complètement assimilé (c'est normal, on ne change pas de paradigme comme on change de slip. Quoique, pour certains..)

Dans ton cas, tu n'as qu'a définir un objet dbquery dans le contructeur de ta classe programme, dans ce genre-ci:
class programme 
 {
 private $bdd;
 function __construct()
   {
   $this->bdd = new dbquery();
   }
  // etc...
  }
Ou encore, quand tu définis ton objet dbquery autre part (pour n'en utiliser qu'un, sans passer par le singleton):

(dans ton script d'initialisation)
$ma_db = new dbquery();
$programme = new programme($ma_db);
Et puis dans le constructeur de ta classe programme:
function __construct($db)
  {
  $this->bdd = $db;
  }
Bien sur, il faudra avoir inclus le fichier contenant la classe dbquery auparavant.

Ou bien tu utilises l'autochargement de classes (petit lien) pour charger automatiquement les classes non encore chargées.

A moins que je n'ais rien compris à la problématique..

Posté : 23 mai 2008, 11:09
par agité
Merci Berzemus !

C'est exactement ce que je cherchais a faire, c'est vrai que ca me semble plus "logique" de faire comme ca, quand je construit la classe, il en appel une autre, enfin dans ma tête c'est plus clair !

Du coup ca donne ca :

Classe programme
<?
/********************************
* 	Classe de gestion programmes
*
********************************/

// Classe de gestion des programmes
class programme {

private $bdd;

	function __construct()
	{
	$this->bdd = new dbquery();
	}

	function misenavant($id_programme,$id_etat)
	{
		$this->bdd->req_query("UPDATE programme SET est_mis_en_avant = ".$id_etat." WHERE id_programme = '".$id_programme."' ");
	}
}
?>

Pour la classe dbquery ca reste la même que la derniere postée

Pour l'appel :
<?php
require_once('../_includes/php/classes/dbfactory.php');
require_once('../_includes/php/classes/programme.php');
require_once('../_includes/php/functions.php');

// Appel de la classe
$connect = new dbquery();
$programme = new programme();

// Formulaire ajout programme
if($_POST)
{
	$query = $programme->misenavant($_POST['id_programme'],1);
}
else
{
	// Supprimer un programme par $_GET
	if($_GET['mode'] == "supprimer")
	{
	$query = $programme->misenavant($_GET['id_programme'],0);
	}
}	
?>
Voilà il me fait bien ce que je lui demande :)

Maintenant petit hic !

Les scripts tournent correctement mais j'ai quand même une message d'erreur qui c'est mis :
Warning: mysql_close(): 5 is not a valid MySQL-Link resource
Il doit pas trop aimer mon destructeur sur dbquery.

Si j'ai bien compris, lors de l'appel par programme il construit la classe et la détruit après utilisation donc lors de la destruction il arrive pas a fermer la connexion mysql puisque les destructeur correspond à :

 // Deconnection de la bdd
 function __destruct() {
	
		mysql_close($this->dbconnect);
 }

Il ne doit pas trouver le $this->dbconnect ou ne pas l'apprécier pourtant il correspond à :
 // Connection a la bdd
 function __construct() {
 
 		$this->dbconnect = @mysql_connect($this->config['host'],
																			$this->config['user'],
																			$this->config['pass']);
																			
		$this->dbtable = 	@mysql_select_db($this->config['dbname'],$this->dbconnect);	

									
		if(!$this->dbconnect)
		{
 			echo "<b>- Impossible de se connecter a la base de donnée</b><br />";
		}
									
			
		if(!$this->dbtable)
		{
			echo "<b>- La base de donnée : '".$this->config['dbname']."' n'éxiste pas</b><br />";
		}
									
 }
Donc comment fermer proprement la connexion sql a la destruction ?

Posté : 23 mai 2008, 11:12
par vince_weed
En effet c'était une erreur de mettre le require_once dans la classe programme (j'ai copié/collé un peu vite) ;).

Posté : 23 mai 2008, 11:15
par agité
En effet c'était une erreur de mettre le require_once dans la classe programme (j'ai copié/collé un peu vite) ;).
pas de soucis c'est sympa d'aider, le principale est que ca marche maintenant :twisted:

Posté : 23 mai 2008, 11:35
par Berzemus
Donc comment fermer proprement la connexion sql a la destruction ?
Essaye voir sans la fermer explicitement. La connexion se ferme tout seul quand php à fini son petit train train, peut-être même qu'il ferme la connexion avant même le destructeur (enfin, je m'avancerais pas trop la-dessus).

Sinon, je peux te proposer d'utiliser mysqli plutôt que mysql, c'est mieux, ça va plus vite, et ça supporte les requêtes préparées ainsi qu'une utilisation orienté objet :wink: .