I have several observations regarding the newly implemented aggregate() und overload() extensions. Depending on the correctness of these observations you may want to reconsider the inclusion of these extensions in the current build of PHP.
The following has not in its entirety verified in the source and may be incorrect or incomplete. Please correct me. Situation: $obj = new Origclass; aggregate($obj, "Classname"); is a function which adds all instance variables and methods from class Classname to an object $obj of an original class Origclass. There are variations of aggregate which allow you to add instance variables and methods selectively by enumeration and regex. Observation: aggreate and friends break the introspection in PHP, and may interfere with serialization and sessions. This is, because get_class($obj) returns Origclass, and no trace of Classname. Also, $obj is_a() Origclass, but not is_a(Classname), leading to serialization of $obj as a pure Origclass, and reinstantiation as a pure Origclass with no methods from Classname at all. This is the situation of serialize() in PHP 3 at a slightly elevated level. Reminder: In PHP 3, serialize() did not record the class of an object on serialization, and unserialize() consequently produced an object with no methods at all, which is in fact quite useless. Also, because of the fine grained nature of the more advanced variations of aggregate, there is no fast way to describe the class or type of an object instance. The only way to completely describe an object is to completely enumerate its instance variables and instance methods. Essentially, get_class and friends become meaningless. Alternative: aggregate is a badly designed way to introduce multiple inheritance like functionality. There are at least two tested ways to implement MI functionality. Statically typed languages such as C++ set type == class and implement pure MI. Regarding PHP, this would lead to class C extends A, B { ... } with the order of A and B being important. Also, get_parent_class() would need to be modified to return inheritance level information or inheritance graph information together with class names in order to produce meaningful information. Something like $v = get_parent_class($complicated_object); $v would be array("A" => "B", "B" => "C", "B" => "D"); for class A extends B ... class B extends C, D ... An alternative, possibly cleaner way would be the introduction of interfaces and categories. In this scenario we keep single inheritance. We introduce declarations of interfaces, which may contain a number of instance variables and functions. Interfaces are a simple declaration of these, there is no implementation at all in an interface. A class may claim conformity with an interface. This means that the class at least has all the instance variables the interface demands and has at least implementations for all member functions of the interface. The class may implement all this independently or it may import a category. A category is class-subset, and always an implementation of an interface (you cannot define a category for which no interface definition is being known). Interfaces and Categories are found in some dynamically typed languages, sometimes under slightly different names. They separate type and class, and in order for them to function in PHP we would need enumerative functions and predicates to complement the new language constructs (get_defined_interfaces(), get_defined_categories(), conforms_to($interface_name)). Recommendation: As-is aggregate() is a broken design, and will break existing older functionality. It will create a number of support issues, and later backward compatibility issues. It may inspire even more broken "fixes" for these issues, effectively uglifying the language itself or at least its object system. The best would be to remove aggregate() completely, and bury it. It should be replaced by a proper MI system, probably one for a dynamically typed language, as PHP is such a language. If aggregate() functionality is being used right now, and is critical, it should be kept, properly documented, the drawbacks spelled out in all its ugliness and its use strongly discouraged. It should be clearly marked as obsolete from day 1, and may be removed at any time. If someone uses this feature despite the warning labels, this person deserves everything that happens. Situation: The overload() extension allows userland code to intercept get, set and call operations on the instance variables and instance functions of an object. It does this by defining the special fixed name functions __get, __set and __call in a class, which are enabled by calling overload() on this class. It also allows, according to Sebastian Bergmann, and in spite of the current documentation at http://www.php.net/ref.overload.php, __get_x(), __set_y() and __call_x() functions in order to intercept accesses and calls to instance variable x and method y respectively. I haven't verified this in source, but Sebastian claims it works. Observation: If this is NOT the case, I have no issue with overload(). It is dangoerous, but it is an expert feature and the design is okay. If overload() allows for __get_x(), though, this is bad design. The reason for this is that we get namespace pollution and, again (*), automatically called callback functions with a variable name. There will interoperate badly with inheritance, with dynamically created, undeclared instance variables and with aggregate(). Recommendation: If overload() indeed supports variably named callback functions such as __get_x(), support for this should be removed in order to avoid a number of possible inconsistencies and namespace pollution. End Rant, fire away... Kristian (*) We had them with PHP 3 constructor names, which were an extremely bad idea in the first place. -- Kristian Köhntopp, NetUSE AG, Dr.-Hell-Straße, D-24107 Kiel Tel: +49 431 386 435 00, Fax: +49 431 386 435 99 -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, visit: http://www.php.net/unsub.php