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
That is perfect Duncan, that was my first impression, but I think i read that
there was something to adding new magic methods, however, i think that would
be the perfect solution.
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
--
Leonardo Pedretti
Axon Sistemas
Líder de Equipo Proyecto Basalto