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

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

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

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

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

$ins = new class_A();

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

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

Ответы [ 11 ]

30 голосов
/ 21 января 2010

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

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

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();
7 голосов
/ 21 января 2010

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

4 голосов
/ 21 января 2010

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

3 голосов
/ 21 января 2010

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

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

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

2 голосов
/ 21 января 2010

Шаблон синглтона с примером 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();
1 голос
/ 21 января 2010

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

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 голос
/ 21 января 2010

Я думаю, что вы хотите Шаблон реестра

1 голос
/ 21 января 2010
0 голосов
/ 10 декабря 2015

Код ниже имеет качество кэширования, которое способствует эффективности:

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 голосов
/ 11 октября 2010

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

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
    // ...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...