121 votes

Que fait le nouveau soi (); signifie en PHP?

Je n'ai jamais vu de code comme celui-ci:

 public static function getInstance()
{
    if ( ! isset(self::$_instance)) {
        self::$_instance = new self();
    }
    return self::$_instance;
}
 

Est-ce la même chose que new className() ?

MODIFIER

Si la classe est héritante, quelle classe pointe-t-elle?

230voto

Pascal MARTIN Points 195780

self de points à la classe dans laquelle elle est écrite.

Donc, si votre méthode getInstance est dans un nom de classe MyClass, la ligne suivante :

self::$_instance = new self();

Fera la même chose que :

self::$_instance = new MyClass();



Edit : un couple plus d'infos, d'après les commentaires.

Si vous avez deux classes qui étendent les uns des autres, vous avez deux situations :

  • getInstance est définie dans la classe enfant
  • getInstance est défini dans la classe parent

La première situation devrait ressembler à ceci (j'ai supprimé tous les codes non nécessaires, pour cet exemple, vous devez les ajouter en arrière pour obtenir le singleton comportement)* :

class MyParentClass {

}
class MyChildClass extends MyParentClass {
    public static function getInstance() {
        return new self();
    }
}

$a = MyChildClass::getInstance();
var_dump($a);

Ici, vous obtiendrez :

object(MyChildClass)#1 (0) { } 

Ce qui signifie self moyen MyChildClass -- c'est à dire la classe dans laquelle elle est écrite.


Pour la deuxième situation, le code ressemblera à ceci :

class MyParentClass {
    public static function getInstance() {
        return new self();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

Et vous obtenez ce genre de résultat :

object(MyParentClass)#1 (0) { }

Ce qui signifie self moyen MyParentClass -- c'est à dire ici aussi, la classe dans laquelle elle est écrite.




Avec PHP < 5.3, que "la classe dans laquelle il est écrit" c'est important-et peut parfois causer des problèmes.

C'est pourquoi PHP 5.3 introduit une nouvelle utilisation pour l' static mot-clé : il peut maintenant être utilisé exactement où nous avons utilisé self dans ces exemples :

class MyParentClass {
    public static function getInstance() {
        return new static();
    }
}
class MyChildClass extends MyParentClass {

}

$a = MyChildClass::getInstance();
var_dump($a);

Mais, avec static au lieu de self, vous allez obtenir :

object(MyChildClass)#1 (0) { } 

Ce qui signifie qu' static sorte de points de la classe qui est utilisée (nous avons utilisé MyChildClass::getInstance()), et non pas celui dans lequel il est écrit.

Bien sûr, le comportement de l' self n'a pas été modifié, pour ne pas casser les applications existantes -- PHP 5.3 juste d'ajouter un nouveau comportement, recyclage de l' static mot-clé.


Et, parlant de PHP 5.3, vous voudrez peut-être jeter un oeil à la résolution Statique à la volée page du manuel PHP.

10voto

Pekka 웃 Points 249607

Cela semble être une implémentation du pattern Singleton. La fonction est appelée de façon statique et vérifie si la classe statique a la variable $_instance ensemble.

Si elle ne l'est pas, il initialise une instance de lui-même (new self()) et les stocke dans $_instance.

Si vous appelez className::getInstance() , vous obtiendrez une seule et même instance de la classe à chaque appel, qui est le point de le pattern singleton.

Je n'ai jamais vu ça ce fait de cette façon, cependant, et honnêtement ne savais pas que c'était possible. Qu'est - $_instance a déclaré que dans la classe?

7voto

flimh Points 11

Cela est le plus souvent utilisé dans le modèle de conception singleton, où le constructeur est défini comme privé afin d'éviter d'être instancié, le double du côlon (::) opérateur peut accéder aux membres qui sont déclarées statiques à l'intérieur de la classe, donc si il y a des membres statiques, la pseudo-variable $this ne peut pas être utilisé, d'où le code utilisé l'auto au lieu de cela, les Singletons sont des bonnes pratiques de programmation qui permettra uniquement de 1 instance d'un objet comme le connecteur de base de données des gestionnaires. Depuis le code client, l'accès à cette instance serait fait par la création d'un point d'accès unique, dans ce cas, il l'a nommé getInstance(), Le getInstance en lui-même était la fonction qui a créé l'objet fondamentalement à l'aide du mot clé new pour créer un objet, sens de la méthode de constructeur a également été appelé.

la ligne if(!isset(self::instance)) vérifie si un objet a déjà été créé, vous ne pourriez pas comprendre ce parce que le code n'est qu'un fragment, quelque part dans le top, il devrait y avoir des membres statiques comme probablement

private static $_instance = NULL; 

dans les classes normales, nous aurions accédé à ce membre par tout simplement

$this->_instance = 'something';

mais ses déclarée statique et donc nous ne pouvions pas utiliser le $ce code que nous utilisons à la place

self::$_instance

en vérifiant si il y a un objet stocké sur cette statique de la variable de classe, la classe peut ensuite décider de créer ou ne pas créer une instance unique, donc, si ce n'est pas définie, !isset, ce qui signifie qu'aucun objet n'existe sur le membre statique $_instance, puis il génère un nouvel objet, les stocker dans le membre statique $_instance par la commande

self::$_instance = new self();

et l'a retourné à code client. Le code client peut alors heureux d'utiliser la seule instance de l'objet avec ses méthodes publiques, mais dans le code du client, en appelant le point d'accès unique, qui est, l' getInstance() méthode est aussi délicate, il doit être appelé comme ceci

$thisObject = className::getInstance();

la raison, la fonction en elle-même est déclarée statique.

2voto

Matteo Riva Points 14340

Oui, c'est comme new className() (faisant référence à la classe contenant cette méthode), probablement utilisé dans un modèle Singleton où le constructeur est privé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X