当前位置:  开发笔记 > 编程语言 > 正文

在PHP中获取类的所有实例

如何解决《在PHP中获取类的所有实例》经验,为你挑选了2个好方法。

我想获得某个类的对象的所有实例.

例如:

class Foo {
}

$a = new Foo();
$b = new Foo();

$instances = get_instances_of_class('Foo');

$instances应该是array($a, $b)array($b, $a)(顺序无关紧要).

一个加号是函数是否会返回具有所请求类的超类的实例,尽管这不是必需的.

我能想到的一个方法是使用一个包含实例数组的静态类成员变量.在类的构造函数和析构函数中,我将$this在数组中添加或删除.如果我必须在许多课程上这样做,这是相当麻烦和容易出错的.



1> Kenzal Hunte..:

如果从TrackableObject类派生所有对象,可以设置此类来处理这些事情(只需确保调用parent::__construct()以及parent::__destruct()在子类中重载它们时).

class TrackableObject
{
    protected static $_instances = array();

    public function __construct()
    {
        self::$_instances[] = $this;
    }

    public function __destruct()
    {
        unset(self::$_instances[array_search($this, self::$_instances, true)]);
    }

    /**
     * @param $includeSubclasses Optionally include subclasses in returned set
     * @returns array array of objects
     */
    public static function getInstances($includeSubclasses = false)
    {
        $return = array();
        foreach(self::$_instances as $instance) {
            if ($instance instanceof get_class($this)) {
                if ($includeSubclasses || (get_class($instance) === get_class($this)) {
                    $return[] = $instance;
                }
            }
        }
        return $return;
    }
}

这个问题的主要问题是垃圾收集不会自动拾取任何对象(因为它的引用仍存在于其中TrackableObject::$_instances),因此__destruct()需要手动调用以销毁所述对象.(循环引用垃圾收集在PHP 5.3中添加,可能会提供额外的垃圾收集机会)



2> Jeremy Ruten..:

这是一个可能的解决方案:

function get_instances_of_class($class) {
    $instances = array();

    foreach ($GLOBALS as $value) {
        if (is_a($value, $class) || is_subclass_of($value, $class)) {
            array_push($instances, $value);
        }
    }

    return $instances;
}

编辑:更新代码以检查是否$class是超类.

编辑2:制作一个稍微杂乱的递归函数,检查每个对象的变量而不仅仅是顶级对象:

function get_instances_of_class($class, $vars=null) {
    if ($vars == null) {
        $vars = $GLOBALS;
    }

    $instances = array();

    foreach ($vars as $value) {
        if (is_a($value, $class)) {
            array_push($instances, $value);
        }

        $object_vars = get_object_vars($value);
        if ($object_vars) {
            $instances = array_merge($instances, get_instances_of_class($class, $object_vars));
        }
    }

    return $instances;
}

我不确定它是否可以与某些对象进行无限递归,所以要小心......

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有