在 PHP 中获取特定类的所有实例


Get all the instances of a particular class in PHP

我希望能够执行以下操作:

objects = getAllInstances(ClassName);

其中 ClassName 具有唯一字段,因此两个实例不能具有该字段完全相同的值。

class ClassName {
    protected $unique_field;
    public function __construct($value)
    {
         $objects = getAllInstances(self);
         foreach($objects as $object)
         {
             if($object->getUniqueField() === $value)
             {
                 return $object;
             }
         }
    }
    public function getUniqueField()
    {
        return $this->unique_field;
    }
};

是否有设计模式,PHP 中的内置函数用于此目的,或者我必须使用一个静态数组来保存所有创建的实例,然后只循环它?

您可以创建一个工厂,该工厂保留对使用它创建的所有实例的引用:

class ClassNameFactory 
{
    private $instances = [];
    public function create($value)
    {
        return $this->instances[] = new ClassName($value);
    }
    public function getInstances()
    {
        return $this->instances;
    }
}
$f = new ClassNameFactory();
$o1 = $f->create('foo');
$o2 = $f->create('bar');
print_r($f->getInstances());

您可以保存包含所有现有实例的静态数组。类似的东西...

static $instances;
public function __construct($name) {
    $this->unique_field = $name;
    if (empty($instances)) {
        self::$instances = array();
    }
    foreach (self::$instances as $instance) {
        if ($instance->getUniqueField() === $name)
            return $instance;
    }
    self::$instances[] = $this;
}

您需要的是注册表模式:

class ClassNameRegistry {
    private $instances = array();
    public function set($name, InterfaceName $instance) {
        $this->instances[$name] = $instance;
    }
    public function get($name) {
        if (!$this->has($name)) {
            throw new 'LogicException(sprintf(
                'No instance "%s" found for class "ClassName".',
                $name
            );
        }
        return $this->instances[$name];
    }
    public function has($name) {
        return isset($this->instances[$name]);
    }
    public function getAll() {
        return $this->instances;
    }
}

这当然是最好的 OOP 体系结构选项,因为您可以将行为隔离在独立类中作为服务。如果您没有服务的依赖注入机制,我建议您将注册表类定义为单例!

在我的示例中,我使用了一个InterfaceName来在注册表与其处理的实例之间建立低耦合。