Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

probleme de singleton en php

25 réponses
Avatar
ownowl
bonjour à tous

je souhaite faire un singleton en php (c'est à dire qu'il n'y ai qu'une
seule instance d'une classe dans l'environnement php)

Le problème est : A chaque fois que je fais appel à
TypesTruc::getInstance()->getTypes()
je repasse systématiquement dans le constructeur.


class TypesTruc {

private static $instance;

private $types = array();

private function __construct() {
$this->types['0'] = 'truc1;
$this->types['1'] = 'truc2';
}

final public static function getInstance() {
if (!IsSet(self::$instance)) {
error_log('initialisation du singleton');
self::$instance = new TypesTruc ();
}
return self::$instance;
}

public function getTypes(){
return $this->types;
}
}


une idée ?
Olivier

10 réponses

1 2 3
Avatar
Thomas Labourdette
ownowl a écrit le jeudi 5 avril 2007 14:57 :


ownowl a écrit le jeudi 5 avril 2007 09:41 :
je souhaite faire un singleton en php (c'est à dire qu'il n'y ai qu'une
seule instance d'une classe dans l'environnement php)

Le problème est : A chaque fois que je fais appel à
TypesTruc::getInstance()->getTypes()
je repasse systématiquement dans le constructeur.



Je viens de faire le test en PHP 5 et je n'ai pas ton problème.



Tu veux dire que dans ton log, tu n'as qu'une seule ligne de
'initialisation du singleton' quelque soit le nombre de page appelée ?


Non. Lors de plusieurs appels dans la même page. Pour le problème de
persistance d'un objet entre différents appels, les réponses ont été
données par ailleurs.

Il n'y a pas (à ma connaissance) de serveur d'application php comme tu peux
en connaître dans le monde Java.

@+
--
Djémal ALATAITE (signature et citation aléatoires)
Qu'est-ce qui fait 13,2 cm mais qui excite les femmes ?
Un billet de 500 Euros.



Avatar
Jibux

Si tu veux de la persistance de données entre deux appels de scripts, tu
dois utiliser un fichier ou une base de données.


Ou encore les variables de session

Avatar
Olivier Miakinen

Ah non, ça ce n'est pas possible. Lorsque le script PHP s'arrête, toute
la mémoire allouée est libérée... ce d'autant plus lorsque PHP est lancé
sous forme de CGI plutôt que de module Apache, puisque alors c'est
carrément le process qui s'arrête.


Ben les sessions en PHP elles sont gérées comment alors ???


En général, $_SESSION contient un id de session qui est une clé dans une
base de données. Mais nwonowl ne veut pas entendre parler de base de
données.

Les singletons liés à une session pourraient être stockés dans $_SESSION
non ?


Oui, si ce n'est pas trop gros. Mais dans ce cas, au lieu d'aller les
chercher sur le disque, les informations sont transmises (en aller et
retour) sur le réseau. En RTC je ne suis pas sûr qu'on y gagne, bien au
contraire.


Avatar
Bruno Desthuilliers
(snip)

c'est pourtant le but de ce design pattern. La gestion d'un
service/objet commun à l'ensemble des requêtes utilisateur.

La solution est simple: un autre process serveur fourni le service.


Avatar
Bruno Desthuilliers
merci de ta réponse


tu devrais constater que le constructeur n'est appelé qu'une fois dans la
page.



ok

mais à chaque appel de le page il va être rappelé.




oui je suis d'accord, mais c'est bien ca que je veux éviter. Je cherche
que le constructeur soit appelé une seule fois, à la première
utilisation de TypesTruc::getInstance(), quelque soit le nombre de pages
appelées ensuite.
Je précise que je viens du monde java, et qu'en java le constructeur
d'un singleton n'est appelé un seule fois durant la durée de vie de la
machine virtuelle.


C'est la même chose en PHP. Sauf que la durée de vie de l'interpréteur
est équivalente à celle d'une requête (bon, ok, techniquement ce n'est
pas tout à fait vrai si tu déploie PHP comme module Apache, mais dans la
pratique ça revient au même).

Cela est-il possible en php (sans utiliser un système
de cache (et d'ailleur un cache, pour être efficace doit bien rester en
mémoire en les appel des différentes pages))?


La solution habituelle est de cacher les objets "coûteux" à construire
et fréquemment utilisés dans une session. Mais - outre que c'est quand
même un poil différent puisque qu'il y a quand même autant d'instances
que de sessions - cela peut poser d'autres problèmes.

Si tu veux vraiment avoir une seule et unique instance d'un service pour
l'intégralité des requêtes, écris un processus serveur distinct dont ton
appli PHP sera cliente.


Avatar
Bruno Desthuilliers


Le problème est : A chaque fois que je fais appel à
TypesTruc::getInstance()->getTypes()
je repasse systématiquement dans le constructeur.


Je viens de faire le test en PHP 5 et je n'ai pas ton problème.


Tu veux dire que dans ton log, tu n'as qu'une seule ligne de
'initialisation du singleton' quelque soit le nombre de page appelée ?



Ah non, ça ce n'est pas possible. Lorsque le script PHP s'arrête, toute
la mémoire allouée est libérée... ce d'autant plus lorsque PHP est lancé
sous forme de CGI plutôt que de module Apache, puisque alors c'est
carrément le process qui s'arrête.



Ben les sessions en PHP elles sont gérées comment alors ???


Par défaut, sur des fichiers dans le répertoire /tmp. On peut aussi
gérer les sessions dans un SGBDR si on veut faire de la répartition de
charge entre plusieurs serveurs web.

Les singletons liés à une session pourraient être stockés dans $_SESSION
non ?


C'est une technique courante, mais qui peut poser des problèmes aussi
quand on en abuse.





Avatar
Bruno Desthuilliers


Si tu veux de la persistance de données entre deux appels de scripts, tu
dois utiliser un fichier ou une base de données.



Ou encore les variables de session


Et à ton avis, elles sont stockées comment, ces variables ?


Avatar
ownowl
L'intérêt d'un cache,
c'est justement de garder un mémoire (sur le serveur) des informations
souvent sollicitées. Un accès mémoire sera toujours beaucoup plus rapide
qu'un accès fichier ou base de données



Il reste à savoir si l'accès au fichier n'est pas négligeable par
rapport au temps passé sur le réseau.


C'est une application intranet, pas de soucis de réseau. La majorité des
requêtes passent par ajax, les données ne sont pas conséquentes en soit
mais peuvent être constituées d'un assemblage de pas mal de petit
fichier script; d'ou un éventuel goulot lors de l'accès à ces fichiers

Olivier


Avatar
ownowl
(snip)


c'est pourtant le but de ce design pattern. La gestion d'un
service/objet commun à l'ensemble des requêtes utilisateur.

La solution est simple: un autre process serveur fourni le service.



effectivement, mais ca nessécite de mettre en place un protocole de
communication (soap ou autre), n'est ce pas ?

Olivier


Avatar
ownowl



Si tu veux de la persistance de données entre deux appels de scripts, tu
dois utiliser un fichier ou une base de données.




Ou encore les variables de session



Et à ton avis, elles sont stockées comment, ces variables ?


ca ne serait pas sur le disque, par hasard ?



1 2 3