If you derive all your objects from a TrackableObject class, this class could be set up to handle such things (just be sure you call parent::__construct()
and parent::__destruct()
when overloading those in subclasses.
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;
}
}
The major issue with this is that no object would be automatically picked up by garbage collection (as a reference to it still exists within TrackableObject::$_instances
), so __destruct()
would need to be called manually to destroy said object. (Circular Reference Garbage Collection was added in PHP 5.3 and may present additional garbage collection opportunities)