Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:16212 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 7098 invoked by uid 1010); 11 May 2005 16:08:34 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 69348 invoked from network); 11 May 2005 15:49:21 -0000 Received: from unknown (HELO suserver.com) (127.0.0.1) by localhost with SMTP; 11 May 2005 15:49:21 -0000 X-Host-Fingerprint: 200.32.3.79 200-32-3-79.prima.net.ar Linux 2.4/2.6 Received: from ([200.32.3.79:59594] helo=mail.bpservers.com.ar) by pb1.pair.com (ecelerity 1.2 r(5656M)) with SMTP id 24/D3-35155-67922824 for ; Wed, 11 May 2005 11:49:12 -0400 Received: (qmail 17589 invoked by uid 0); 11 May 2005 15:48:51 -0000 Received: from unknown (HELO ?192.168.0.240?) (200.42.80.195) by 200-32-3-79.prima.net.ar with SMTP; 11 May 2005 15:48:51 -0000 Reply-To: lpedretti@suserver.com Organization: Axon Sistemas To: internals@lists.php.net Date: Wed, 11 May 2005 12:48:45 -0300 User-Agent: KMail/1.7.2 References: <200505111014.59892.duncan@calligram.co.uk> In-Reply-To: <200505111014.59892.duncan@calligram.co.uk> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-ID: <200505111248.45508.lpedretti@suserver.com> Subject: [PHP-DEV] magic detecting reference deletion From: lpedretti@suserver.com (Leonardo Pedretti) That is perfect Duncan, that was my first impression, but I think i read th= at=20 there was something to adding new magic methods, however, i think that woul= d=20 be the perfect solution. On Wednesday 11 May 2005 06:14, Duncan McIntyre wrote: > 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 implement= ed > 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=3Darray(); > > public static function loadObject($class, $id) { > if(isset(ObjectStore::instances[$class][$id])) { > ObjectStore::instances[$class][$id][1]++; > return ObjectStore::instances[$class][$id][0]; > } > > $handle =3D SomeDatabaseClass::getHandle(); > $result =3D $handle->query("SELECT * FROM $class WHERE id=3D$id"); > if(!$result->num_rows()) { > throw new Exception("Object $class $id does not exist in the database"= ); > } > $r =3D $result->fetch_object(); > $obj =3D new $class(); > $obj->deserialize($r); > ObjectStore::instances[$class][$id]=3Darray($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=3Dtrue; > } > return $this; > } > > /** > * Retrieve the object's properties from a database row > **/ > abstract public function deserialize($db_object); > } > > Then load objects by calling > > $obj =3D 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 =2D-=20 Leonardo Pedretti Axon Sistemas L=EDder de Equipo Proyecto Basalto