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


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

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

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

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

$ins = new class_A();

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

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

Author: bool.dev, 2010-01-21

11 answers

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

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

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
Author: Tom Haigh, 2017-05-23 12:02:05

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

 7
Author: troelskn, 2010-01-21 16:04:23

Вы должны реализовать одноэлементный шаблон. http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729/page1.html

 4
Author: Pikrass, 2010-01-21 15:45:02

Может быть, вы хотите что-то вроде

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

РЕДАКТИРОВАТЬ: При дальнейшем чтении вам придется перепрыгнуть через некоторые обручи, чтобы получить ссылки на объекты. Таким образом, вы можете захотеть return $$key; вместо return $value;. Или какие-то другие трюки, чтобы получить ссылку на объект.

 3
Author: Dathan, 2010-01-21 16:06:40

Шаблон одноэлементного кода с примером 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();
 2
Author: Karl B, 2010-01-21 15:50:02
 1
Author: Pekka 웃, 2010-01-21 15:41:45

Я думаю, что вам нужен шаблон реестра

 1
Author: AntonioCS, 2010-01-21 15:45:13

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

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
Author: Aistina, 2010-01-21 15:49:56

Помните, что, используя синглтон, вы в основном создаете большую глобальную переменную . Если у него есть состояние, которое меняется, ваш код может стать непредсказуемым. Так что будьте осторожны.

 0
Author: JW., 2010-01-21 15:53:39

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

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
    // ...
    }
}
 0
Author: Emanuele Del Grande, 2010-10-11 19:25:10

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

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

}

Хотя это кажется дорогостоящим, это ничтожно мало.

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

 0
Author: Jesse Westendorf, 2015-12-09 22:36:34