如何在PHP中获取特定类的实例?

时间:2010-01-21 15:40:46

标签: php class instance

我需要检查是否存在 class_A的实例,如果确实存在获取该实例。

如何在PHP中完成?

与往常一样,我认为一个简单的例子是最好的。

现在我的问题已成为:

$ins = new class_A();

如何在实例化时将实例存储在class_A的静态成员变量中?

如果在调用__construct()时可以存储实例,那会更好。比如,它应该不受限制地实现它的实现方式。

11 个答案:

答案 0 :(得分:29)

你所描述的基本上是单身人士模式。请see this question了解您可能不想这样做的充分理由。

如果你真的想这样做,你可以实现类似的东西:

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

答案 1 :(得分:7)

你要求的是不可能的(嗯,也许不是技术意义上的,但非常不切实际)。它表明你对对象和类的目的有更深的误解。

答案 2 :(得分:4)

答案 3 :(得分:3)

也许你想要像

这样的东西
for (get_defined_vars() as $key=>$value)
{
  if ($value instanceof class_A)
    return $value;
}

修改 在进一步阅读时,你必须跳过一些箍来获得对象引用。因此,您可能需要return $$key;而不是return $value;。或者其他一些技巧来获得对象的引用。

答案 4 :(得分:2)

单例模式,PHP example from Wikipedia我添加了一个“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();

答案 5 :(得分:1)

if ($object instanceof class_A)

请参阅PHP manual: Classes and objects

答案 6 :(得分:1)

我认为你想要的是Registry Pattern

答案 7 :(得分:1)

为了扩展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

答案 8 :(得分:0)

请记住,通过使用单身,你基本上是在创建一个大global variable。如果状态发生变化,您的代码就会变得不可预测。所以要小心。

答案 9 :(得分:0)

如果在文件中替换单例实例化指令是一个问题,您可能会变成一个常量驱动的行为:在脚本的所有持续时间内都是常量,因此在实例中哪个要求是唯一的(对于所有脚本持续时间),构造方法可以正确链接到常量的存在/值。

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

答案 10 :(得分:0)

以下代码具有提升效率的缓存质量:

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

}

虽然成本很高,但可以忽略不计。

您可能会注意到,仍然在构造函数中,通过全局变量循环查找最后添加的变量是不可能的。