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

时间:2014-12-24 07:12:27

标签: php oop

我希望能够做到这样的事情:

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中的内置函数用于此目的,或者我是否必须使用包含所有已创建实例的静态数组,然后只是循环它?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

您需要的是registry pattern

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架构选项,因为您将独立类中的行为隔离为服务。如果您没有服务的依赖注入机制,我建议您将注册表类定义为singleton

在我的示例中,我使用InterfaceName在Registry及其处理的实例之间有low coupling