web-dev-qa-db-fra.com

Comment obtenir l'instance d'une classe spécifique en PHP?

J'ai besoin de vérifier si existe une instance de class_A, et s'il y a existe , get cette instance.

Comment le faire en PHP?

Comme toujours, je pense qu'un exemple simple est le meilleur.

Maintenant mon problème est devenu:

$ins = new class_A();

Comment stocker l'instance dans une variable membre statique de class_A lors de l'instanciation?

Ce sera mieux si l'instance peut être stockée en appelant __construct(). Dis, cela devrait fonctionner sans limitation sur la façon dont il est instancié.

11
user198729

Ce que vous avez décrit est essentiellement le motif singleton. S'il vous plaît voir cette question pour de bonnes raisons pour lesquelles vous ne voudrez peut-être pas le faire.

Si vous voulez vraiment le faire, vous pouvez implémenter quelque chose comme ceci:

class a {
    public static $instance;
    public function __construct() {
        self::$instance = $this;
    }

    public static function get() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

$a = a::get();
29
Tom Haigh

Ce que vous demandez est impossible (enfin, peut-être pas dans un sens technique, mais très peu pratique). Cela suggère que vous avez un malentendu plus profond sur le but des objets et des classes.

7
troelskn
4
Pikrass

Peut-être que vous voulez quelque chose comme

for (get_defined_vars() as $key=>$value)
{
  if ($value instanceof class_A)
    return $value;
}

EDIT: Après avoir lu plus avant, vous devez sauter à travers quelques cerceaux pour obtenir des références d'objet. Donc, vous voudrez peut-être return $$key; au lieu de return $value;. Ou d'autres astuces pour obtenir une référence à l'objet.

3
Dathan

Le modèle singleton, avec un exemple PHP de Wikipedia auquel j'ai ajouté une méthode "checkExists", car il semblerait que vous souhaitiez vérifier l'existence de la classe sans nécessairement la créer. si elle ne sort pas:

final class Singleton 
{
    protected static $_instance;

    protected function __construct() # we don't permit an explicit call of the constructor! (like $v = new Singleton())
    { }

    protected function __clone() # we don't permit cloning the singleton (like $x = clone $v)
    { }

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

    public static function checkExists() 
    {
      return self::$_instance;
    }
}

if(Singleton::checkExists())
   $instance = Singleton::getInstance();
2
Karl B

if ($object instanceof class_A)

Voir PHP manual: Classes et objets

1
Pekka 웃

Je pense que ce que vous voulez, c'est le Registre Pattern

1
AntonioCS

Pour développer la réponse à Pikrass, vous voudrez essentiellement faire quelque chose comme ceci:

class class_A {
  private static $instance = false;

  public static function getInstance() {
    if (!self::$instance) {
      self::$instance = new class_A();
    }

    return self::$instance;
  }

  // actual class implementation goes here
}


// where you need to use the instance:
$mySingleton = class_A::getInstance();
// do something with $mySingleton
1
Aistina

Rappelez-vous qu'en utilisant un singleton, vous créez en gros une grande variable globale . Si son état change, votre code peut devenir imprévisible. Alors soyez prudent.

0
JW.

Le code ci-dessous a une qualité de mise en cache qui favorise l'efficacité:

class Object {

  public $instance_variable;
  public $last_added_global_variable;

  public function __construct(){
    //we are saving the global variable before this one so that
    //we can be confident that we will always get the correct value
    $this->last_added_global_variable = $this->get_last_variable_added()[count($array_of_global_variables)-1];
  }

  //runs everytime a function is called in this class
  public function __call(){
    //remember, this is skipped whenever the variable name is saved
    if(!$this->instance_variable){
      for($i=0; $i=count($this->get_last_variable_added()); $i++){
        if($this->last_added_global_variable == get_last_variable_added()[$i]){
          $this->instance_variable = get_last_variable_added()[$i+1];
        }
      }
    }
  }

  private function get_last_variable_added(){
    $array_of_global_variables = array();

    foreach($GLOBALS as $g=>$v){
      array_Push($array_of_global_variables, $g);
    }

    //return last added global variable
    return $array_of_global_variables;
  }

}

Bien que semblant coûteux, il est négligeable.

Vous remarquerez peut-être qu'il est impossible de trouver la dernière variable ajoutée par le biais d'une boucle de variable globale tant que vous vous trouvez dans la fonction de construction.

0
Jesse Westendorf

Si le remplacement de l’instruction d’instanciation singleton dans vos fichiers pose problème, vous pouvez vous transformer en un comportement basé sur la constante: les constantes le sont pour toute la durée du script. Ainsi, dans le cas d’une instance dont la condition doit être unique (pour tous la durée du script) la méthode de construction peut être correctement liée à l'existence/la valeur d'une constante.

 class superObject {
 public function __construct () {
 if (défini ('SUPER_OBJECT')) {{.____.] trigger_error ('Super objet' .__ CLASS__. 'déjà instancié ', E_USER_ERROR); 
 // ... ou faites ce que vous voulez faire en cas de chevauchement d'instances 
} sinon {
 définir (' SUPER_OBJECT ', vrai) ; 
} 
 // le reste de votre méthode de construction 
 // ... 
} 
} 
0