Classes en PHP (instance unique)
Fermé
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
-
13 mai 2009 à 11:58
pyschopathe Messages postés 1974 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 22 mars 2010 - 18 mai 2009 à 13:09
pyschopathe Messages postés 1974 Date d'inscription dimanche 2 mars 2008 Statut Membre Dernière intervention 22 mars 2010 - 18 mai 2009 à 13:09
A voir également:
- Classes en PHP (instance unique)
- Easy php - Télécharger - Divers Web & Internet
- Vue unique whatsapp - Accueil - WhatsApp
- Ora-00001: violation de contrainte unique - Forum Programmation
- Php natif - Forum PHP
- Envoi en instance dhl ✓ - Forum Réseaux sociaux
22 réponses
nico7382
Messages postés
279
Date d'inscription
lundi 6 juin 2005
Statut
Membre
Dernière intervention
22 décembre 2010
50
13 mai 2009 à 13:49
13 mai 2009 à 13:49
Salut,
Le lien est foureux ^^, mais bon :
https://apprendre-php.com/tutoriels/tutoriel-45-singleton-instance-unique-d-une-classe.html
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 ^^
Le lien est foureux ^^, mais bon :
https://apprendre-php.com/tutoriels/tutoriel-45-singleton-instance-unique-d-une-classe.html
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 ^^
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
14 mai 2009 à 19:07
14 mai 2009 à 19:07
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.
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.
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
14 mai 2009 à 21:12
14 mai 2009 à 21:12
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..
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..
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
14 mai 2009 à 22:11
14 mai 2009 à 22:11
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 ?
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 ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
14 mai 2009 à 23:14
14 mai 2009 à 23:14
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.
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.
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
15 mai 2009 à 09:10
15 mai 2009 à 09:10
Oui, c'est pas faux.
je reviens à ce que tu disais :
S'il faut mettre en private le constructeur, on ne peux donc pas faire appel à une extension de class ?
Exemple
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 ... }
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
15 mai 2009 à 09:21
15 mai 2009 à 09:21
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.
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.
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
15 mai 2009 à 09:38
15 mai 2009 à 09:38
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 ?
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 ?
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
15 mai 2009 à 10:37
15 mai 2009 à 10:37
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.
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
15 mai 2009 à 11:05
15 mai 2009 à 11:05
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.
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.
pyfeu
Messages postés
38
Date d'inscription
vendredi 23 mai 2008
Statut
Membre
Dernière intervention
26 novembre 2009
15 mai 2009 à 11:12
15 mai 2009 à 11:12
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
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
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
15 mai 2009 à 11:21
15 mai 2009 à 11:21
Est ce que le "final" veux dire la l'objet sera "détruit" à la fin de l'exécution ?
pyschopathe
Messages postés
1974
Date d'inscription
dimanche 2 mars 2008
Statut
Membre
Dernière intervention
22 mars 2010
135
18 mai 2009 à 12:48
18 mai 2009 à 12:48
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 >_<
edit : la prochaine fois je lirai jusqu'au bout >_<
pyfeu
Messages postés
38
Date d'inscription
vendredi 23 mai 2008
Statut
Membre
Dernière intervention
26 novembre 2009
15 mai 2009 à 11:29
15 mai 2009 à 11:29
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 .
Mais il me semble que ça empêche la redéfinition de la fonction .
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
15 mai 2009 à 18:50
15 mai 2009 à 18:50
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.
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.
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
15 mai 2009 à 19:09
15 mai 2009 à 19:09
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 !
C'est ça ? Parce que ça m'arrangerais dans certains cas !
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
15 mai 2009 à 20:50
15 mai 2009 à 20:50
Oui, mais tu es obligé de passer par le singleton de la classe pour y accéder.
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
15 mai 2009 à 21:21
15 mai 2009 à 21:21
MMM J'ai essayé un truc de ce genre :
puis :
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" ?
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" ?
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
15 mai 2009 à 22:04
15 mai 2009 à 22:04
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 :
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();
nickleus
Messages postés
374
Date d'inscription
dimanche 20 janvier 2008
Statut
Membre
Dernière intervention
18 juin 2011
5
16 mai 2009 à 19:13
16 mai 2009 à 19:13
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 ?
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 ?
pyschopathe
Messages postés
1974
Date d'inscription
dimanche 2 mars 2008
Statut
Membre
Dernière intervention
22 mars 2010
135
18 mai 2009 à 13:09
18 mai 2009 à 13:09
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...
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...
P@t@ch0n
Messages postés
565
Date d'inscription
mercredi 15 avril 2009
Statut
Membre
Dernière intervention
28 décembre 2009
85
17 mai 2009 à 17:25
17 mai 2009 à 17:25
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.
Je n'ai pas bien compris ce que tu dis.
Je n'ai pas bien compris ce que tu dis.
14 mai 2009 à 10:48
Il va falloir que j'intègre cela dans mes codes maintenant. ;)