The reason I have this base class is that there is equivalent functionality within the built in object in PHP. No concept of ownership or relationship.
In my rudimentary framework, nearly my components are related in some way. VERY little stands alone. Therefore, for me, the base object having ownership capabilities is perfect. The main advantage of having this functionality is that, in theory, you only ever destroy 1 object. All other objects are owned and are therefore destroyed in the correct order. If you notice from my code, the __destruct() method of the base object deals with destroying all owned objects. I am not sure I agree with you about having interfaces. PHP does not allow method inclusion into a class (I cannot build a class from a set of methods in different files). If PHP handled multiple inheritence, then this would be ideal, but as far as I know only a handful of specialist languages support true MI. I think I understand the issues that argue against it and I am not advocating that PHP SHOULD support it, it just would be nice if it did. It would be useful. An alternative way to building a deep class structure is to have a "flattening" script. So, take the deep classes and creat squashed classes via a script. You would have some constraints though. No longer would every class be of type abstract_object as well as constraints on the origin of class constants. Not an ideal solution. The basic reason I have this base class is to enforce the order of destruction. I try very hard to make my classes no more than 3 deep, but ownership goes WAY deep! (I have a particular instance of 23 levels of ownership!). Now trying to destroy all of those objects in the right order would be a nightmare without the base object dealing with it. As for using a third party framework (Zend / PEAR / eZ / Prado / etc), then each would have to be examined to see if it dealt with ownership. I would be truly surprised if it did not. On 06/12/06, Arnold Daniels <[EMAIL PROTECTED]> wrote:
Hi, I think having to extend a base class is not a good idea. First of all you deprive yourself of extending a class of a library you haven't written (like something from Zend Framework or PEAR). Second it puts a huge constraint on the code of the users of your library, because any class they write needs to extend your base class. A slightly better solution would be to use an interface. A solution like this forces you to have some kind of framework with general interfaces/classes used in all of your libraries. To my opinion a user shouldn't have to set up an elaborate framework in PHP to prevent memory leaks. I've heard some good comments, but no real good solutions. So I think I should just write the destroy function. I hope it will find its way into PHP or (even better) that someone can find a way to prevent these memory leaks. Best regards, Arnold Richard Quadling schreef: > In user land, I have an abstract_object like this > (http://rquadling.php1h.com/abstract_object.html). > > I've come from a Delphi environment so some of the code you see is > based upon some of the ideas I see in the TObject class. > > There are some comments, but the basic idea is there. > > On 05/12/06, Arnold Daniels <[EMAIL PROTECTED]> wrote: >> >> >> Richard Lynch schreef: >> > On Mon, December 4, 2006 7:21 pm, Arnold Daniels wrote: >> > >> >> I'm struggling with the problem that cross-referenced objects don't >> >> get >> >> destroyed. I can off course write a method to break the >> >> cross-reference, >> >> but that's kind of a pain in the butt, especially if the >> >> cross-reference >> >> is not strait forward. >> >> >> > >> > Seems to me that a simple unset() on the data members in userland >> > coude so PHPs refcount is decremented ought to do it... >> > >> > If a user creates a monstrous data structure and doesn't prune it, how >> > much responsibility can PHP take for that? >> > >> > But maybe I'm just being naive. >> > >> > >> I myself run into problems when implementing parent/child relationships >> within object. I probably use PHP a bit different than the regular user >> and therefor run into different problems, but with more elaborate >> frameworks being build, I think more people will run into these kind of >> problems. >> Think about a DOM implementation fully in PHP (I'm not building that, >> but just to give you an idea). Using uset() on each child wouldn't do >> much good, since each also holds a parent/child relationship with its >> children and therefor the child is not destroyed, meaning the parent is >> not destroyed. To overcome this you need implement a method destroy(), >> which runs through all property to see if it is a DOM object and call >> the destroy() on it. But now imagine another class which has properties >> with objects of all kinds of classes, some of which have parent/child >> relationships. Now you need all these classes to implement some sort of >> destroyable interface. I don't really like a solution like this. With >> the destroy function you would still need to walk through the children >> and call destroy forcing an unset in the destructor of the class, but >> it's a step up. >> >> >> To solve this I'm thinking of building one of 2 thing: >> >> 1.) Write a destroy() function which works much like a close function >> >> on >> >> a recourse, changing the object to a zval of type 'unknown'. >> >> 2.) Specify that a property of an object does not count for the >> >> reference count of a zval. >> >> >> > >> > I don't think this is a Good Idea... >> > >> > Seems like it would be WAY too easy for userland code to end up with a >> > 0 for the refcount and then GC kicks in. >> > >> > >> Yes, that is what I want. If the parent object is unset, the parent >> property of the child object should be set to unknown or something. But >> I guess that the memory is freed and the zval isn't set to unknown and >> you would just get unexpected results. >> >> 3.) Write code to find cross-references and destroy the objects >> still. >> >> >> >> The first solution should be quite easy to implement, but you need to >> >> call destroy() to free the object, introducing the whole alloc/free >> >> responsibility thing to PHP. >> >> >> > >> > Just use unset() for this, rather than introduce yet another confusing >> > function. >> > >> > >> >> The second solution would require some extra keyword within the >> class, >> >> but require no special code within the code using the object. >> Though I >> >> wouldn't have a clue how how to implement this or what would be the >> >> consequences. >> >> >> > >> > >> >> I don't think the third solution is really possible or would at least >> >> cause performance problems. >> >> >> > >> > Finding a "dead branch" of cyclic structures is basic CS stuff. >> > >> > Add a second temp "refcount" and start walking the graph. >> > >> > Either you end up with something known to be in the GLOBAL scope, or >> > you don't. >> > >> > It can take a long time, depending on the size of the graph, but it's >> > just pointer-chasing and integer arithmetic, so shouldn't be THAT >> > slow. >> > >> > >> I don't really see this solution. I wouldn't unnecessarily find anything >> in the GLOBAL scope. When using unset or returning from a function, a >> check should be made to find if the variable is used within the scope of >> the call stack, global or statically. To my knowledge (which is small >> on the PHP internals subject) it is only possible to see how many >> references to the object there are, not where there references are. >> >> Thank you for commenting on my e-mail. I hope you understand where I'm >> coming from with this problem and understand why unset will not do. I >> hope that you or perhaps someone else might have some other comments or >> solutions I haven't yet thought of. >> >> Best regards, >> Arnold >> >> > >
-- ----- Richard Quadling Zend Certified Engineer : http://zend.com/zce.php?c=ZEND002498&r=213474731 "Standing on the shoulders of some very clever giants!" -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php