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 :

variable static contenant une isntance


Sujet :

Langage PHP

  1. #1
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut variable static contenant une isntance
    Bonjour,

    Je voudrais instancier une variable static avec un objet, mais ça n'a pas l'air possible en PHP. Pourquoi ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class A
    {
     
       public static $monInstance = new A(); // <= Génère une erreur
     
       .....
     
    }
    Il y a un contournement ?

    merci

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    Salut,

    Tu es confronté à une limitation du langage.
    Il n'y a pas de contournement (et si contournement il y a, ça doit être assez moche)

    Tu ne chercherais pas à faire par hasard un Singleton ?

  3. #3
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je voudrais instancier une variable static avec un objet
    de quoi

    On instancie des classes, pas des propriétés...

    Le code que tu montre ne peux pas marcher: en PHP les valeurs par défaut des propriétés (de classes ou d'instance) ainsi que les constantes de classes ne peuvent prendre qu'un littéral comme valeur, pas une expression.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    <?php
     
    class Foo {
     
      public $bar = "hello"; // bon
      public $baz = 1+1; // pas bon
     
    }
    Pour faire ce que tu veux faire, il faut passer par le constructeur s'ils s'agit d'une propriété d'instance ou par une méthode statique pour les propriétés de classe.

    Personnellement, j'ai quelques classes de service qui sont statiques, elles sont configurées comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php 
     
    class MaClasseDeService {
     
      proctected static $_config;
     
      public static function setConfig (array $config = array()) {
        self::$_config = $config + array(
           // valeurs par défaut...
        );
      }
     
      // autres trucs...
    }

  4. #4
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Je me suis peut être mal exprimé. Soyons précis alors. Je souhaite instancier un objet à partir d'une classe public non-static et le rendre accessible dans une variable static de cette même class. Il n'y a rien de tordu la dedans. C'est souvent utilisé pour que la classe fournisse des instances spéciales qui sont initialisées au chargement.

    Tu as par exemple une classe Color qui contiendrait Color::RED, Color::GREEN, Color::BLUE, Color::WHITE, Color::BLACK.

    Non ce n'est pas pour un singleton. Pour les singletons je passe toujours par une méthode getInstance() ce qui ne pose aucun problème en PHP.

    Par contre je suis assez surpris qu'on ne puisse pas avoir d'objet static, que des littéraux. On peut pourtant bien avoir des méthodes static. J'espère que ça sera corrigé dans les versions futures;

  5. #5
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    Je crois que tu voulais dire:
    je souhaite initialiser une propriété de classe avec une instance.
    Je souhaite instancier un objet à partir d'une classe public non-static et le rendre accessible dans une variable static de cette même class. Il n'y a rien de tordu la dedans. C'est souvent utilisé pour que la classe fournisse des instances spéciales qui sont initialisées au chargement.
    Si tant est que j'ai bien compris ton besoin, tu veux qu'une instance d'une classe soit enregistrée dans une propriété statique de cette même classe. C'est possible en effet mais j'ai du mal à comprendre ce que tu cherches à faire...

    Voici comment tu peux t'y prendre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Foo {
     
    	public static $foo;
     
    	public function bar () { echo 'sup?'; }
    }
     
    Foo::$foo = new Foo;
     
    Foo::$foo->bar(); // sup?
    Par contre je suis assez surpris qu'on ne puisse pas avoir d'objet static, que des littéraux
    On peut mettre ce qu'on veut dans une propriété de classe ou d'instance. Mais on ne peut pas l'initialiser par défaut avec une expression, c'est ça la nuance

    Exemple:
    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
    <?php
     
    class Foo1 {
     
        public $bar = 1+1; // ça marche pas, il faut mettre une valeur
    }
     
    class Foo2 {
     
        public $bar;
     
        public function __construct () {
            $this->bar = 1+1; // là ça marche, c'est à ça que sert un constructeur !
        }
    }
    Note: pour les constantes de classe, il faut utiliser le mot clé const:
    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
    <?php
     
    class Color {
     
        const BLACK = '#000000';
        const GREEN = '#00FF00';
        const RED   = '#FF0000';
        const BLUE  = '#0000FF';
     
        protected $_hex = '';
     
        public function __construct () {
            switch (func_num_args()) {
                case 3:
                    list($r,$g,$b) = func_get_args();
                    $this->_hex = self::rgb2hex($r,$g,$b);
                    break;
                case 1:
                    if (strpos($color = func_get_arg(), '#') === 0)
                        $this->_hex = $color;
                    else
                        $this->_hex = self::color2hex($color);
                    break;
            }
        }
     
        public static function rgb2hex ($r, $g, $b) {
            // ...
        }
     
        public static function color2hex ($color) {
            $color = strtolower($color);
     
            if (!isset(self::$unixColors[$color]))
                throw new UnexpectedValueException("not a valid unix color");
     
            return self::$unixColors[$color];
        }
     
        public static $unixColors = array(
            'red' => self::RED,
            // ... liste des couleurs UNIX
        );
    }

  6. #6
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Merci, j'aime assez ta première solution ou j'instancie mes variables static en dehors de la classe mais dans le même fichier. Ca devrait me convenir.

    Par contre quelle est la différence entre const et static ? Je viens du monde java, je connais bien static. const est bien pour déclarer une constante qui sera static (associée à une classe et non aux instances). Une fois initialisé, on ne peux plus changer la référence. C'est bien ça ? (public final static en java)

  7. #7
    Expert éminent
    Avatar de Benjamin Delespierre
    Profil pro
    Développeur Web
    Inscrit en
    Février 2010
    Messages
    3 929
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Février 2010
    Messages : 3 929
    Points : 7 762
    Points
    7 762
    Par défaut
    CONST et STATIC obéissent aux mêmes règles en ce qui concerne l'héritage et la surcharge. Elles sont toutes deux utilisables avec le late static binding (ce qui est une spécificité de PHP).

    La différence, c'est qu'une constante de classe n'est pas modifiable, elle est constante (duh) et qu'elle n'a pas le préfix $ comme pour les propriétés.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    // disponible dans le contexte d'instance
     
    $foo = new Foo;
     
    echo $foo->a; // 1
     
    // disponible dans le contexte de classe
     
    echo Foo::$b; // 2
    echo Foo::c; // 3
    Ce qui est disponible dans un contexte ne l'est pas forcément dans l'autre. Ce qui est vrai pour les méthodes ne l'est pas pour les propriétés: une méthode d'instance est implicitement aussi une méthode de classe mais une propriété d'instance n'est pas utilisable dans un contexte de classe.

    Exemple:
    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
    class Foo {
     
        public function bar () { echo 'sup?'; }
     
        public static function baz () { echo 'bro!' };
     
    }
     
    $f = new Foo;
     
    Foo::bar(); // une erreur Strict standards mais ça marche !
    $f->bar(); // pas d'erreur
     
    Foo::baz(); // pas d'erreur
    $f->baz(); // pas d'erreur
    Quand au late static binding, c'est assez tordu en fait. Quand tu hérite d'une classe, la fille hérite aussi des méthodes statiques de la mère. En revanche, c'est dans le contexte de la mère qu'elles sont invoquées, ce qui est parfois problématique.

    Exemple:
    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
    <?php
     
    class Foo {
     
        protected static $bar = 1;
     
        public static function getBar () { return self::$bar; }
     
        public static function factory () { return new self; }
     
    }
     
    class Bar extends Foo {
     
        protected static $bar = 2;
     
    }
     
    echo Bar::getBar(); // 1 (eh oui, on est dans le contexte de Foo et non de Bar)
    var_dump( Bar::factory() instanceof Bar ); // false (même chose)
    var_dump( Bar::factory() instanceof Foo ); // true
    Pour résoudre ce problème, depuis PHP 5.3 on peut utiliser le mot clé static au lieu du mot clé self:
    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
    <?php
     
    class Foo {
     
        protected static $bar = 1;
     
        public static function getBar () { return static::$bar; }
     
        public static function factory () { return new static; }
     
    }
     
    class Bar extends Foo {
     
        protected static $bar = 2;
     
    }
     
    echo Bar::getBar(); // 2
     
    var_dump( Bar::factory() instanceof Bar ); // true
    var_dump( Bar::factory() instanceof Foo ); // true (bah oui, on hérite)
    Le late static binding peut être perçu comme une abberation au yeux des puristes de la POO je le concède. Mais en PHP c'est souvent pratique car les méthodes de classes sont exécutées 4x plus rapidement que les méthodes d'instances.

    C'est plus clair ?

Discussions similaires

  1. Variable static dans une fonction membre
    Par uriotcea dans le forum C++
    Réponses: 8
    Dernier message: 09/07/2009, 14h48
  2. variable static d'une fonction[debutant]
    Par le_voisin dans le forum C++
    Réponses: 5
    Dernier message: 09/01/2009, 17h42
  3. variable Static dans une classe
    Par cubitus91 dans le forum Delphi
    Réponses: 3
    Dernier message: 29/11/2006, 00h07
  4. [héritage] héritage d'une variable static
    Par yaya44 dans le forum Langage
    Réponses: 14
    Dernier message: 29/09/2004, 13h36
  5. [ADO] requete contenant une variable ?
    Par kam dans le forum MFC
    Réponses: 9
    Dernier message: 28/04/2004, 11h08

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