Rechercher : dans
Par :

Classes en PHP (instance unique)

Dernière réponse le 18 mai 2009 à 13:09:17 nickleus, le 13 mai 2009 à 11:58:59 
 Signaler ce message aux modérateurs

Bonjour à tous,

j'ai lu cette article (ce tuto) : http://www.apprendre-php.com/...

Qui explique comment créer une instance unique d'une classe. Je pense avoir saisie comment ça fonction. Mais je vois pas à quoi cela peut servir dans un cas concret.

Ou plutôt qu'est ce que cela peut apporter de créer un objet de ce type dans d'autres classes ?

Merci d'avance de votre éclaircissement. Il n'y a pas de problèmes, il n'y a que des solutions

Configu­ration: vista
Firefox

Meilleures réponses pour « Classes en PHP (instance unique) » dans :
Le mot-clé static ou les attributs et méthodes de classe en POO Voir(NOTE: Cet article explique la signification du mot-clé static au sein d'une classe. La signification de "static" en C n'a par exemple rien à voir.) Vous êtes débutant en programmation orientée objet. En Java, en C++...ou que sais-je encore,...
PHP - Les classes VoirLa notion de classe Php3 intègre un soupçon de caractéristiques empruntées aux langages orientés objet, c'est-à-dire la possibilité d'utiliser des objets, entités regroupant des données et des fonctions au sein d'une structure et rendant la...
Classe et instance d'objet VoirLa notion de classe On appelle classe la structure d'un objet, c'est-à-dire la déclaration de l'ensemble des entités qui composeront un objet. Un objet est donc « issu » d'une classe, c'est le produit qui sort d'un moule. En réalité on dit qu'un...
Java - Les objets VoirLa création d'objets Un objet est une instance de classe, la création d'objets s'appelle donc l'instanciation. Cette instanciation se fait grâce à l'opérateur new suivi du nom de la classe à instancier et de parenthèses contenant les paramètres...

1

nico7382, le 13 mai 2009 à 13:49:31

Salut,


Le lien est foureux ^^, mais bon :
http://www.apprendre-php.com/...

je connaissais pas non plus, mais bon, ce qui est peut être intéressant dans les singletons, c'est par exemple dans le cas, où plusieurs utilisateurs font des choses en parallèle:

Paul travail sur un document, et Jacques sur un autre.
Jacques fini sont boulot sur son doc plus tôt et il veut aider Paul à finir le sien, et bah, il ne pourra pas , car paul est déjà sur le document, le singleton t'indique que le document est déjà en édition par exemple.

Voilà un exemple, dans la majorité des cas, quand c'est pas géré ainsi, Jacques accède avec l'ancienne version du doc, et s'il enregistre après que paul est enregistré, Jacques effaces les données que Paul à marqué.


Si je me trompe n'hésite pas ^^

Répondre à nico7382

2

nickleus, le 14 mai 2009 à 10:48:25

Merci, c'est déjà un peu plus claire

Il va falloir que j'intègre cela dans mes codes maintenant. ;) Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

3

nickleus, le 14 mai 2009 à 19:07:13

Bonsoir,

Encore une petite question sur ce sujet. Dans le tuto que j'ai cité plutôt, est-ce une obligation de déclarer un private la méthode __construct ( ) ?

Car je fait un extends d'une autre class, et si ma méthode __construct ( ) (de la première class) est en private, ça ne marche pas.

houa, j'éspère que c'est claire tout ce ! :-))

Merci d'avance. Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

4

P@t@ch0n, le 14 mai 2009 à 21:12:31

Oui, c'est nécessaire, car en appelant directement le constructeur, tu auras une autre instance de ta classe, ce qui n'a plus aucun intérêt.

L'héritage d'une classe mère dont l'instance s'effectue via un singleton n'a aucun sens.

nico7382, ton explication m'as bien fait marrer, mais c'est pas du tout ça le but.

Un exemple plus basique, et concret.
Une classe Page dans une application qui s'occupe de mettre en forme une page html, bien évidemment, on ne veut qu'une instance de cette classe, sinon, on se retrouverait, avec plusieurs « pages ».
Plusieurs autres classes feront appel au singleton de cette classe, par exemple, une classe news, une classe menu, une classe formulaire, etc..

Répondre à P@t@ch0n

5

nickleus, le 14 mai 2009 à 22:11:02

Ton idée est intéressante ! Qui plus est elle se rapproche de mon type de projet ;)

Ce que je ne comprends pas dans ton explication, c'est que l'osque l'on charge une page, elle dépend de l'url, alors comment elle pourrait créer plusieurs "pages" ? (En faite je n'est pas vraiment compris le sens ce bout d'explication)

Est ce que cela voudrais aussi dire, qu'il faut créer un singleton pour chacune des parties ? Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

6

P@t@ch0n, le 14 mai 2009 à 23:14:00

J'avais mit des guillemets justement pour dire que ce n'était pas plusieurs pages au sens réel, mais plusieurs code de pages html mit bout à bout.

Il faut voir « page » comme un container global d'une page, contenant sa structuration (html).

Par exemple cette classe posséderait une méthode entete(), une méthode menu(), une méthode contenu(), une méthode corps(), etc...

Non pourquoi vouloir créer un singleton pour chaque partie ? tout dépend du but de la classe.

Répondre à P@t@ch0n

7

nickleus, le 15 mai 2009 à 09:10:51

Oui, c'est pas faux.

je reviens à ce que tu disais :

Oui, c'est nécessaire, car en appelant directement le constructeur, tu auras une autre instance de ta classe, ce qui n'a plus aucun intérêt.


S'il faut mettre en private le constructeur, on ne peux donc pas faire appel à une extension de class ?

Exemple


class bibi
{
code ...
}

class bobo extends bibi
{
code avec instance ...
}
Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

8

P@t@ch0n, le 15 mai 2009 à 09:21:28

Non, on ne peut pas en mettant la visibilé du constructeur en private.

Mais comme je t'ai dis précédemment, faire une classe fille héritant d'une classe mère dont l'instance se fait par singleton n'a aucun sens.

Répondre à P@t@ch0n

9

nickleus, le 15 mai 2009 à 09:38:52

Houa, tu es toujours sur ton PC ! lol

Je pense qu'en prenant une class que je suis entrain de créer comme exemple m'aiderai à mieux comprendre. Car je t'avoue que les class sont encore un grand mystère pour moi.

Je suis entrain de créer une class de traduction de langue :

Elle récupère le mot à traduire, puis je charge un fichier ini (suivant la page, j'en dit pas plus c'est très long à expliquer) où chaque ligne est contituée de la façon suivante :

CLE=valeur

dont je fait un explode pour avoir un tableau de type array ( [CLE] => valeur ). Puis je retourne la valeur et j'affiche.

Qu'elle serait l'intérêt de mette cette class en instance ? Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

10

P@t@ch0n, le 15 mai 2009 à 10:37:55

L'intérêt serait de ne charger qu'une seule fois ton fichier au cas où ton application ferait appel plusieurs fois dans divers endroit à ta classe.

Répondre à P@t@ch0n

11

nickleus, le 15 mai 2009 à 11:05:30

D'accord, encore une pitit question et après j'arrête de t'embêter :)

Est-ce qu'une instance d'une class peu faire office de "global" ou ça n'a rien à voir ?

Un peu comme lorsque l'on appel une variable dans une fonction. Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

12

pyfeu, le 15 mai 2009 à 11:12:16

L'intéret aussi est de ne pas créer plein d'objet à chaque fois
exemple : une première classe :
class FamilleDAO {

// Sauvegarde de l'instance
private static $_instance;
private $connexion;


/**
*
*/
private function __construct () {
global $host_db, $user_login, $user_password, $database, $acces_log;
$this->connexion = MySQLConnection::instance($acces_log);
if(!$this->connexion->isValid()){
$this->connexion->connect($host_db, $user_login, $user_password);
$this->connexion->useDB($database);
}
}

/**
*
*/
private function __clone () {}

/**
*
*/
public static final function getInstance(){
if (!isset(self::$_instance))
{
$c = __CLASS__;
self::$_instance = new $c();
}
return self::$_instance;
}

cette classe va servir par exemple a ajouter, supprimer des éléments de le base de données.
-------------------------------------------------------------------------
une classe qui va utilisé :
fera comme cela :
$familleDAO = FamilleDAO::getInstance();
et il n'y aura donc pas de nouvelle création d'objet

Répondre à pyfeu

13

nickleus, le 15 mai 2009 à 11:21:57

Est ce que le "final" veux dire la l'objet sera "détruit" à la fin de l'exécution ? Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

24

pyschopathe, le 18 mai 2009 à 12:48:52

Le mot-clé final signifie que la méthode ne pourra pas être redéfinie dans le classes filles (en cas d'héritage).

edit : la prochaine fois je lirai jusqu'au bout >_<

Répondre à pyschopathe

14

pyfeu, le 15 mai 2009 à 11:29:26

Non ça ne le détruit pas (je ne suis pas sur à 100% car je sais plus trop ce que ça fait final :s )
Mais il me semble que ça empêche la redéfinition de la fonction .

Répondre à pyfeu

15

P@t@ch0n, le 15 mai 2009 à 18:50:26

C'est ça, le final empêche la redéfinition de la méthode par une classe enfant.

Est-ce qu'une instance d'une class peu faire office de "global" ou ça n'a rien à voir ?

Si tu entends par là qu'une classe instanciée par singleton est une parade à la mise à global de la variable contenant l'objet, je dirais que oui.

Répondre à P@t@ch0n

16

nickleus, le 15 mai 2009 à 19:09:52

Donc je pourrais très bien instanciée ma classs (sinlgeton) en dehors de toutes mes classes et faire appel à une de ces méthodes dans n'importe quel autres classe ?

C'est ça ? Parce que ça m'arrangerais dans certains cas ! Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

17

P@t@ch0n, le 15 mai 2009 à 20:50:24

Oui, mais tu es obligé de passer par le singleton de la classe pour y accéder.

Répondre à P@t@ch0n

18

nickleus, le 15 mai 2009 à 21:21:23

MMM J'ai essayé un truc de ce genre :

class test
{
private function __construct ( ) 
{
echo "bibi";
}

public function getInstance ( )
{
static $instance;

if ( !isset ( $instance ) )
{
$instance = new test ( );
}

return $instance;
}

}


puis :

class test2
{

public function __contruct ( )
{
$var;
} 

}

$var = test::getInstance ( );
$val = new test2 ( );


Mais bien sur ça ne marche pas puisque la variable $var n'est pas définie. Pourquoi ? puisque j'ai déclarer la variable par un singleton. Ou alors est ce que ça marche qu'a partir du moment que les classes sont "empilée" ? Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

19

P@t@ch0n, le 15 mai 2009 à 22:04:20

Il faut toujours accéder à ton instance dans ton singleton avec self.

Tu n'as pas bien compris le fonctionnement je pense, en mettant un echo dans le constructeur, il ne sera affiché quuu'une seule fois, peu importe le nombre d'appel au singleton.

Les variables n'ont que des portées locales dans le fonctions.

Un exemple :

class Test
{
   private $qui;
   private static $instance;
   
   private function __construct($qui) 
   {
      $this->qui = $qui;
   }

   public function getInstance($qui)
   {
      if( !isset(self::$instance) )
         self::$instance = new Test($qui);
      return self::$instance;
   }
   
   public function getQui()
   {
      return $this->qui . "\n";
   }
}

class Test2
{
   private $Test;
   
   public function __construct()
   {
      $this->Test = Test::getInstance(__CLASS__);
   }
   
   public function getQui()
   {
      return $this->Test->getQui();
   }
}

//* Dans cet ordre, affichera Externe 2 fois
$Test = Test::getInstance('Externe');
echo $Test->getQui();

$Test2 = new Test2();
echo $Test2->getQui();//*/

// À l'inverse, affichera Test2 2fois
$Test2 = new Test2();
echo $Test2->getQui();

$Test = Test::getInstance('Externe');
echo $Test->getQui();

Répondre à P@t@ch0n

20

nickleus, le 16 mai 2009 à 19:13:22

Oui, maintenant je comprends mieux. En faite on pourrait considéré que cette instance, pourrait être une mémoire tampon entre plusieurs classes !

Et si par exemple, j'ai une méthode qui utiliser un array_push, je pourrais ajouter autant de valeurs suivant le nombre de classes qui appel cette instance.

Est ce c'est bien ça ? Il n'y a pas de problèmes, il n'y a que des solutions

Répondre à nickleus

25

 pyschopathe, le 18 mai 2009 à 13:09:17

Une utilisation de la classe singleton serait une classe de paramétrage : à sa construction, cette classe lit un fichier de paramètres et garde les valeurs en mémoire. Lorsqu'elle est détruite, si des paramètres ont été modifiés, elle réécrit le fichier de paramètres.

Tous les objets de ton application partagent les mêmes paramètres, donc si l'objet A modifie le paramètre 'toto', il faut que si l'objet B demande la valeur du parmètre 'toto', il obtienne la valeur modifiée. La classe Parametre devrait donc être un singleton, c'est à dire qu'il n'existera toujours qu'une seule instance (ou zéro si pas encore construit).

Les buts principaux sont le partage de données et l'économie de ressources. Dans le cas du fichier de paramètres, le partage est évident, et le fait de n'utiliser qu'une instance économise les accès au système de fichier et le parsing du fichier de paramètres.

Je n'ai pas compris ta question sur array_push...

Répondre à pyschopathe