Как получить экземпляр определенного класса в PHP?

Мне нужно проверить, существует ли существующий экземпляр class_A, а если существует, получить этот экземпляр. p >

Как это сделать в PHP?

Как всегда, я считаю, что простой пример лучше.

Теперь моя проблема стала:

$ins = new class_A();

Как сохранить экземпляр в статической членной переменной class_A при создании экземпляра?

Лучше, если экземпляр можно сохранить при вызове __construct(). Скажем, он должен работать без ограничений на то, как он создавался.

Ответ 1

То, что вы описали, по сути, является одноэлементным. Пожалуйста, см. Этот вопрос по уважительным причинам, почему вы, возможно, не захотите это делать.

Если вы действительно хотите это сделать, вы можете реализовать что-то вроде этого:

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();

Ответ 2

То, что вы просите, невозможно (ну, может быть, не в техническом смысле, но крайне непрактично). Это говорит о том, что у вас есть более глубокое недоразумение в отношении целей объектов и классов.

Ответ 4

Возможно, вы хотите что-то вроде

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

EDIT: При дальнейшем чтении вам нужно перепрыгнуть через некоторые обручи, чтобы получить ссылки на объекты. Таким образом, вы можете захотеть return $$key; вместо return $value;. Или некоторые другие трюки, чтобы получить ссылку на объект.

Ответ 5

Синтаксический шаблон с PHP-пример из Википедии, который я добавил к методу checkExists, поскольку это звучит так, как будто вы хотите проверить существование класса, не создавая его, если он не выходит:

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();

Ответ 8

Чтобы расширить ответ на Pikrass, вы в основном захотите сделать что-то вроде этого:

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

Ответ 10

Если замена инструмента описания экземпляра singleton в ваших файлах является проблемой, вы можете перейти в поведение с постоянным управлением: константы таковы для всей продолжительности script, поэтому в случае экземпляра, которое требуется для быть уникальным (для всей длительности script) метод построения может быть правильно связан с существованием/значением константы.

class superObject {
    public function __construct() {
        if (defined('SUPER_OBJECT')) {
            trigger_error('Super object '.__CLASS__.' already instantiated', E_USER_ERROR);
                    // ...or just do whatever you want to do in case of instances overlap
        } else {
            define('SUPER_OBJECT', true);
        }
    // the rest of your construct method
    // ...
    }
}

Ответ 11

В приведенном ниже коде есть качество кеширования, которое повышает эффективность:

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;
  }

}

Несмотря на то, что это дорого, это незначительно.

Вы можете заметить, что найти последнюю добавленную переменную через петлю глобальной переменной невозможно, пока она еще находится в функции построения.