开发者

How to get instance of a specific class in PHP?

开发者 https://www.devze.com 2022-12-16 22:56 出处:网络
I need to check if there exists an instance of class_A ,and if there does exist, get that instance. How to do it in PHP?

I need to check if there exists an instance of class_A ,and if there does exist, get that instance.

How to do it in PHP?

As always, I think a simple example is best.

Now my problem has become:

$ins = new class_A();

How to store the instance in a static member variable of class_A when instantiating?

It'll be better if the instance can be stored when calling __construct(). 开发者_开发问答Say, it should work without limitation on how it's instantiated.


What you have described is essentially the singleton pattern. Please see this question for good reasons why you might not want to do this.

If you really want to do it, you could implement something like this:

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


What you ask for is impossible (Well, perhaps not in a technical sense, but highly impractical). It suggests that you have a deeper misunderstanding about the purpose of objects and classes.


You should implement the Singleton pattern. http://www.developertutorials.com/tutorials/php/php-singleton-design-pattern-050729/page1.html


Maybe you want something like

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

EDIT: Upon further reading, you have to jump through some hoops to get object references. So you might want return $$key; instead of return $value;. Or some other tricks to get a reference to the object.


if ($object instanceof class_A)

See PHP manual: Classes and objects


To expand on Pikrass answer, you basically will want to do something like this:

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


The singleton pattern, with a PHP example from Wikipedia that I've added a "checkExists" method to, as it sounds like you want to check for the existence of the class without necessarily creating it if it doesn't exit:

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


I think what you want is the Registry Pattern


Remember that by using a singleton, you're basically creating a big global variable. If it's got state that changes, your code can become unpredictable. So use caution.


If the replacement of the singleton instantiation instrucion in your files is a problem you may turn into a constant-driven behaviour: constants are such for all the duration of the script, so in case of an instance which requirement is to be unique (for all the script duration) the construction method may be properly linked to the existence/value of a constant.

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
    // ...
    }
}


The code below has a caching quality that promotes efficiency:

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

}

Although appearing costly, it is negligible.

You may note that finding the last added variable through a global-variable loop is impossible while still in the constructing function.


In last version you can this


class Foo
{
}
$object=new Foo();
echo $object::class;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号