IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Singleton qui s'initialise deux fois ?


Sujet :

Langage PHP

  1. #1
    Membre habitué Avatar de alejandro
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Septembre 2004
    Messages
    167
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn (Midi Pyrénées)

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2004
    Messages : 167
    Points : 188
    Points
    188
    Par défaut Singleton qui s'initialise deux fois ?
    Bonjour, j'ai un problème d'initialisation avec mon singleton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    <?php
     
    if( ! class_exists( 'Lib_Session' ) )
    {
        class Lib_Session
        {
            protected static $o_Instance;
     
            protected function __construct() 
            {
                $handle = fopen( "C:\\Log.txt", 'a+' );
                $string = "In __construct() \n";
                fwrite( $handle, $string );
                fclose( $handle );
            }
     
            public static function GetInstance()
            {
                $handle = fopen( "C:\\Log.txt", 'a+' );
                $string = "In GetInstance() \n";
                fwrite( $handle, $string );
                fclose( $handle );
     
                if( ! self::$o_Instance instanceof self )            
                    self::$o_Instance = new self;
     
                return self::$o_Instance;
            }
        }
    }
    En effet si vous regardes le fichier de logs situé à la racine du disque dur et généré par ces lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $handle = fopen( "C:\\Log.txt", 'a+' );
    $string = "In ... \n";
    fwrite( $handle, $string );
    fclose( $handle );
    vous obtenez les logs suivants :

    In GetInstance()
    In __construct()
    In GetInstance()
    In __construct()
    Dans un autre fichier j'initialise mon singleton comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $this->o_Session = Lib_Session::GetInstance();
    Si je commente cette ligne, mon fichier de logs reste vierge, prouvant qu'aucun autre appel à GetInstance() n'est effectué ailleurs dans le programme.

    Alors pourquoi ma fonction GetInstance() est-elle appelée deux fois ?
    Et surtout pourquoi mon constructeur __construct() également ?

    Merci pour votre aide.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    336
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 336
    Points : 341
    Points
    341
    Par défaut
    Bonjour,

    j'ai exécuté le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    <?php
     
    if( ! class_exists( 'Lib_Session' ) )
    {
      class Lib_Session
      {
        protected static $o_Instance;
     
        protected function __construct()
        {
          echo 'in construct <br>';
        }
     
        public static function GetInstance()
        {
          echo 'in GetInstance <br>';
     
          if( ! self::$o_Instance instanceof self )
          self::$o_Instance = new self;
     
          return self::$o_Instance;
        }
      }
    }
     
    $toto = Lib_Session::GetInstance();
     
    ?>
    et j'ai bien le résultat une seule fois :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    in GetInstance 
    in construct
    Sinon, je crois que le pattern demande à mettre le constructeur & le membre en private.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    <?php
     
    if( ! class_exists( 'Lib_Session' ) )
    {
      class Lib_Session
      {
        private static $o_Instance;
     
        private function __construct()
        {
          echo 'in construct <br>';
        }
     
        public static function GetInstance()
        {
          echo 'in GetInstance <br>';
     
          if( !isset(self::$o_Instance) ) {
          self::$o_Instance = new self;
          echo "j'instancie <br>";
          }
     
          return self::$o_Instance;
        }
      }
    }
     
    $toto = Lib_Session::GetInstance();
     
    ?>
    Enfin, attention à implémenter __clone() pour jeter une exception ou faire un trigger d'erreur, pour éviter que l'instance ne se trouve dupliqué.
    Est-ce que si tu testes les bouts de code que je t'ai mis, ça fonctionne chez toi ?

    Karl3i

  3. #3
    Membre actif Avatar de bigltnt
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    227
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Mars 2007
    Messages : 227
    Points : 205
    Points
    205
    Par défaut
    Une petite erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     self::$o_Instance = new self;
    je n'ai jamais appellé un contructeur avec un self, mais dans tous les cas il manque les parenthèses:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     self::$o_Instance = new self();

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    336
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 336
    Points : 341
    Points
    341
    Par défaut
    En quoi est-ce une erreur pour un constructeur qui n'attend pas de paramètre ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    <?php
     
    class A {
      protected $test;
      public function __construct() {
        $this->test = "init";
      }
    }
     
    $a = new A;
     
    echo "<pre>";
    print_r($a);
    echo "</pre>";
    ?>
    A Object
    (
    [test:protected] => init
    )

Discussions similaires

  1. Message d'erreur qui s'affiche deux fois au lieu de trois
    Par popolvictory dans le forum Forms
    Réponses: 2
    Dernier message: 23/10/2008, 16h00
  2. Message de confirm qui s'affiche deux fois
    Par Lolie11 dans le forum Langage
    Réponses: 17
    Dernier message: 07/06/2007, 11h00
  3. Message de confirm qui s'affiche deux fois
    Par Lolie11 dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 05/06/2007, 09h03
  4. Script qui s'exécute deux fois ?
    Par ben53 dans le forum Langage
    Réponses: 1
    Dernier message: 29/01/2007, 15h56
  5. Pop-up qui s'ouvre deux fois
    Par arnapou dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/06/2006, 08h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo