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 :

Problème de singleton abstrait [PHP 5.2]


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé 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
    Par défaut Problème de singleton abstrait
    Bonjour,

    J'ai créé un singleton abstrait qui fonctionne très bien jusqu'ici :

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    if( ! class_exists( 'Singleton_Abstract' ) )
    {
        abstract class Singleton_Abstract
        implements Singleton_Interface
        {
            protected static $i_Counter = 0;
            protected static $s_Fline = null;
     
            final private function __clone(){}
            protected function __construct(){}
     
            final public static function GetInstance()
            {
                static $h_Instances = array();
     
                $s_Class = self::GetChild();
     
                if( ! isset( $h_Instances[ $s_Class ] ) )
                    $h_Instances[ $s_Class ] = new $s_Class;
     
                return $h_Instances[ $s_Class ];
            }
     
            final protected static function GetChild()
            {
                $h_Backtrace = debug_backtrace();
     
                $i_Line = $h_Backtrace[1]['line'];
                $s_File = $h_Backtrace[1]['file'];
                $s_Function = $h_Backtrace[1]['function'];
     
                self::$i_Counter = ( self::$s_Fline == $s_File . $i_Line )
                                 ? self::$i_Counter++ : 0;
     
                $s_Search = "/([a-zA-Z0-9\_]+)::$s_Function/";
     
                $a_Lines = file( $s_File );
                $s_Line = $a_Lines[ --$i_Line ];
     
                preg_match_all( $s_Search, $s_Line, $a_Matches );
     
                return $a_Matches[1][self::$i_Counter];
            }
     
        }
    }
    Sauf que j'ai un bug lorsque je réclame une instance de mon singleton via eval() comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    eval( "$s_Class::GetInstance();" );
    J'obtiens plusieurs messages d'erreur :

    Warning: file(C:\Documents and Settings\alejandro\Mes documents\Company\Programmes\Mairies\Framework\Default\Bootstrap.php(56) : eval()'d code) [function.file]: failed to open stream: No such file or directory in C:\Documents and Settings\alejandro\Mes documents\Company\Programmes\Mairies\Framework\Singleton\Abstract.php on line 47

    Notice: Undefined offset: 0 in C:\Documents and Settings\alejandro\Mes documents\Company\Programmes\Mairies\Framework\Singleton\Abstract.php on line 52

    Fatal error: Class name must be a valid object or a string in C:\Documents and Settings\alejandro\Mes documents\Company\Programmes\Mairies\Framework\Singleton\Abstract.php on line 29
    Les deux messages d'erreur suivants découlent de la première erreur.

    Quelqu'un saurait-il comment modifier mon singleton abstrait afin qu'il puisse également fonctionner lors d'une instanciation via la fonction eval() ???

  2. #2
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Par défaut
    Je suppose que tu sais que l'utilisation de eval() est fortement déconseillé et qu'elle est peut toujours être remplacé par quelque chose de correct.

    Pour revenir à ton problème, eval() semble vouloir inclure quelque chose au fichier ou il sert à inclure un fichier qui n'est pas trouvé.
    Que contient $s_Class ?
    Que contiennent les lignes citées par l'erreur ?

  3. #3
    Membre confirmé 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
    Par défaut
    Bonsoir,

    Je sais que l'utilisation d'eval n'est pas conseillée mais je n'ai pour l'instant pas trouvé de solution de remplacement. Mon eval se trouve dans un bootstrap :

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    if( ! class_exists( 'Default_Bootstrap' ) )
    {
        if( ! defined( 'APPLICATION_CONTROLLERS_DIRECTORY' ) )
            define( 'APPLICATION_CONTROLLERS_DIRECTORY', 'Controller' );
     
        if( ! defined( 'APPLICATION_DEFAULT_CONTROLLER' ) )
            define( 'APPLICATION_DEFAULT_CONTROLLER', 'Default' );
     
        final class Default_Bootstrap
        extends Strategy_Singleton_Abstract
        implements Factory_Interface
        {        
            protected function __construct()
            {
                $i_Segment = 1;
                $s_Path = APPLICATION_CONTROLLERS_DIRECTORY;
                $o_Uri = Default_Uri::GetInstance();
     
                while( $s_Segment = $o_Uri->GetSegment( $i_Segment ) )
                {                
                    $s_Segment = strtoupper( substr( $s_Segment, 0, 1 ) ) 
                               . strtolower( substr( $s_Segment, 1, strlen( $s_Segment ) ) );
     
                    $s_Path .= "/$s_Segment";
     
                    $i_Segment++;
                }
     
                $s_FrameworkPath = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
     
                if( $s_Path === APPLICATION_CONTROLLERS_DIRECTORY
                  OR is_dir( APPLICATION_PATH . str_replace( '/', DIRECTORY_SEPARATOR, $s_Path ) ) )
                    $s_Path .= '/' . APPLICATION_DEFAULT_CONTROLLER;
     
                $this->o_Strategy = $this->Factory( $s_Path );
            }
     
            public function Factory( $s_Path )
            {
                $s_FrameworkPath = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR;
                $s_Path = str_replace( '/', DIRECTORY_SEPARATOR, $s_Path );
                $s_Class = str_replace( DIRECTORY_SEPARATOR, '_', $s_Path );
     
                if( file_exists( APPLICATION_PATH . "$s_Path.php" )
                  OR file_exists( $s_FrameworkPath . "$s_Path.php" ) )
                    return eval( "$s_Class::GetInstance();" );
     
                throw new Exception( "PAGE_NOT_FOUND", 404 );
            }
        }
    }
    Je dois instancier de manière dynamique un singleton et je n'ai pas trouvé d'autre solution que d'utiliser eval. $s_Class est une string contenant le nom de la classe à instancier, par exemple "Default_Controller_404".

    Lorsque la classe contrôleur est appelée pour la première fois, une fonction _autoload() se charge d'inclure le fichier correspondant au chemin Default/Controller/404.php.

    Cette variable $s_Class est donc générée de manière dynamique en fonction de l'URI saisie par le client et utilisée pour appeler l'instance unique du contrôleur correspondant.

    Concernant le contenu des deux fichiers donnés dans les warnings, le bootstrap est ci-dessus et le singleton abstrait dans mon premier post.

  4. #4
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ${$s_Class}::GetInstance();
    ne fonctionne pas ??

    L'erreur vient tel de ton GetInstance() ??

  5. #5
    Membre confirmé 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
    Par défaut
    Bonjour et merci pour ta réponse, mais cela ne fonctionne pas ... Ma variable $s_Class contient un nom de classe de type "Controller_404" par exemple.

    J'essaye de caster de manière dynamique cette classe qui est un singleton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Controller_404::GetInstance();
    Sauf que puisque "Controller_404" est généré de manière dynamique par mon script j'ai essayé de faire comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $s_Class::GetInstance();
    et j'obtiens le message d'erreur suivant :

    Parse error: parse error, unexpected T_PAAMAYIM_NEKUDOTAYIM in C:\Documents and Settings\alejandro\Mes documents\Company\Programmes\Mairies\Framework\Default\Bootstrap.php on line 57
    Si j'essaye comme ceci cela ne marche pas non plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    {$s_Class}::GetInstance();
    J'obtiens le message d'erreur suivant :

    Parse error: parse error, unexpected '{' in C:\Documents and Settings\alejandro\Mes documents\Company\Programmes\Mairies\Framework\Default\Bootstrap.php on line 57
    et enfin mettre un dollar devant je ne comprends pas pourquoi car je ne cherche pas à faire $Controller_404::GetInstance(); mais Controller_404::GetInstance();

    En fait il faudrait que je puisse instancier un singleton de manière dynamique sans passer par eval... si vous avez une idée ...

  6. #6
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2007
    Messages
    121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Avril 2007
    Messages : 121
    Par défaut
    la solution a ton problème est dans la doc... et ca doit fonctionner (si la doc le dit...)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 26/08/2011, 14h44
  2. [PHP 5.3] Problème de Singleton
    Par adc15 dans le forum Langage
    Réponses: 23
    Dernier message: 30/04/2011, 15h27
  3. Problème avec classe abstraite
    Par Antoniom dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 29/01/2011, 14h03
  4. Problème de singleton
    Par Monstros Velu dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 19/02/2009, 16h27
  5. [GOF] Fabrique abstraite peut-elle être un Singleton ?
    Par manel007 dans le forum Design Patterns
    Réponses: 7
    Dernier message: 06/01/2005, 11h02

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