Wez,
I have similar problems. I think your suggested solution is the wrong approach
because your problem is not creating objects, it is destroying them.
My solution would be to define a new magic static method __free() which is
given an instance of the class every time a reference to that instance is
deleted. This would be a hook into the code which calls __destruct() once an
object's ref count reaches zero, except that it would call __free() every
time an object's ref count was decremented.
class SomeClass {
public static __free($instance) {
/**
* Do some static instance caching magic here
**/
}
}
This would be a neat addition to the language, but unless it is implemented
you will have to use a bit of discipline in writing your code instead.
The example below is probably the best you can do:
/**
* This class provides the mechanism to load objects from the database
* and caches loaded instances
**/
class ObjectStore {
static $instances=array();
public static function loadObject($class, $id) {
if(isset(ObjectStore::instances[$class][$id])) {
ObjectStore::instances[$class][$id][1]++;
return ObjectStore::instances[$class][$id][0];
}
$handle = SomeDatabaseClass::getHandle();
$result = $handle->query("SELECT * FROM $class WHERE id=$id");
if(!$result->num_rows()) {
throw new Exception("Object $class $id does not exist
in the database");
}
$r = $result->fetch_object();
$obj = new $class();
$obj->deserialize($r);
ObjectStore::instances[$class][$id]=array($obj, 1);
return $obj;
}
public static function free($obj) {
ObjectStore::instances[$obj->class][$obj->id][1]--;
if(!ObjectStore::instances[$obj->class][$obj->id][1]) {
unset(ObjectStore::instances[$obj->class][$obj->id]);
}
}
}
/**
* All classes stored in the database must extend this class
**/
abstract class PersistentObject {
public function free() {
static $freed;
if(!$freed) {
ObjectStore::free($this);
$freed=true;
}
return $this;
}
/**
* Retrieve the object's properties from a database row
**/
abstract public function deserialize($db_object);
}
Then load objects by calling
$obj = ObjectStore::loadObject("SomeClass",27);
And when you're done with them call unset($obj->free());
Any classes which consume PersistentObjects must have a method __destruct()
which calls free() on any PersistentObjects they have references to in order
for this to work.
Duncan
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php