PHP implements an "stdClass". I expected that:
- this was the base class for all classes, even if they do not explicitly "extends stdClass",
- this class implemented all the "standard" methods (__construct(), __destruct(), ...).
In the PHP5 presentation, it is mentionned the interest of unified constructors. Currently it is not possible to call parent::__construct() if the class does not derived from another one, or none of its parent implements a constructor.
Another problem: when you change a class implementation and decide to now implement a constructor, you have to review all its derived classes.
Which finally limits the benefit of unified constructors.
I think all classes should be derived from a common base class (stdClass or a new dedicated one), even if it's not explicitly written. This base class should also implement all the standard methods:
__construct()
Empty.
__destruct()
Empty.
__clone()
Does the bit for bit copy of the object.
Note: I also added a post concerning a new cloning implementation proposal. In that case, __clone() would be empty.
__toString()
To be compatible with the current implementation, this method should return "Object id #n". However I would prefer it returns the class name instead, which gives a more useful piece of information than it's ID.
__get()
Display the "Notice: Undefined property ..." and returns NULL.
__set()
Create a new member (public).
Note: I would appreciate that a notice is also displayed, because I don't consider this is a normal way to create members.
__call()
Generates a "Fatal error: Call to undefined method ...".
Regards,
Stephane
Stephane Drouard wrote:
Currently it is not possible to call parent::__construct() if the
class does not derived
from another one, or none of its parent implements a constructor.
I agree that it should always be possible to call parent::__construct()
(at least if a
base class exists :-)).
__construct()
__destruct()
Empty.
Agreed.
If the method actually exists or is somehow magic is an implementation
detail. But one should always be able to call
parent::__construct/__destruct.
__clone()
Does the bit for bit copy of the object.
I think this and all other 'magic' methods you mention should be empty.
Right now a bit cloning is done before __clone() is called, I can live
with the minimal
performance penalty this might cause.
Keeps things simple and calling a non-implemented parent::__ never
causes any
harm like this.
- Chris
Hello Stephane,
Thursday, January 22, 2004, 3:48:19 PM, you wrote:
PHP implements an "stdClass". I expected that:
- this was the base class for all classes, even if they do not explicitly "extends stdClass",
nope, there is absolutely no reason for that
- this class implemented all the "standard" methods (__construct(), __destruct(), ...).
all __* are magic functions they must not exist and are not meant to be
called directly (which seems to be your problem). It is just easy: never
call a __* method directly with the exception neing __clone() which works
slightly different.
In the PHP5 presentation, it is mentionned the interest of unified
constructors. Currently it is not possible to call parent::__construct()
if the class does not derived from another one, or none of its parent
implements a constructor.
Well you design a class tree/framework and should know what you have done.
If not use reflection.
Another problem: when you change a class implementation and decide to
now implement a constructor, you have to review all its derived classes.
Which finally limits the benefit of unified constructors.
A change is a change.
I think all classes should be derived from a common base class
(stdClass or a new dedicated one), even if it's not explicitly written.
This base class should also implement all the standard methods:
[...]
That would slow down execution very much and makes absolutely no
sense at all. If you want a base class for your classes do it. Fell free.
Do implement whatever classtree/framework you whish to have. But don't
misuse internal classes.
--
Best regards,
Marcus mailto:helly@php.net
Marcus Boerger wrote:
Well you design a class tree/framework and should know what you have done.
If not use reflection.
So to be able to later add a constructor to a base class one would be
stuck with one of two options:
- have __construct() in all classes from the start, even if it's empty.
Ugly and stupid. Not even Java forces one to do that :-) - Use reflection in all extending classes to check if a constructor
exists. Inacceptable, a joke at best.
A change is a change.
OO is about extending classes without having to touch users of the class
if the interface remains the same. Arguing that adding a constructor
changes the interface is silly, especially if it is a parameterless one.
That would slow down execution very much and makes absolutely no
sense at all. If you want a base class for your classes do it. Fell free.
I don't buy that: The place where
zend_error(E_ERROR, "Can not call constructor");
is done could easily just ignore the call.
Maybe it could be turned into E_NOTICE
or E_STRICT
for people who want
to be notified about such calls.
I'll post a patch on the WE if noone else is doing it.
- Chris
[...]
I think all classes should be derived from a common base class
(stdClass or a new dedicated one), even if it's not explicitly
written.
This can be done in userland and should take a more or less skilled
programmer 5 to 10 minutes.
- Timm
So why must we all keep implementing it?
This can be done in userland and should take a more or less skilled
programmer 5 to 10 minutes.
So why must we all keep implementing it?
Well, because you'd probably not like it the way I'd like to see it (or
the other way around), someone else probably prefers PEAR's, Horde's,
$random_other_php_framework's solution, and so on.
Plus, as was already said, and to which I agree, not every class should
have a constructor. If it did, you'd have a noticeable and unnecessary
memory overhead, especially when you're creating big amounts of objects.
There are more reasons which do not necessarily have to do with
performance or memory consumption but rather with how one thinks a base
class should be designed - see what I mean by personal preferences?
All in all, I don't think it would be a good idea if PHP forced this on
you. What would be basically OK if you had the option of having such a
base class. But then again, why not simply write one for yourself? It's
not like any programmer utilizing OOP doesn't use any sort of
include(s) in where his/her classes reside. Add it there and you're all
set up.
It's basically the same with the built-in exception class. I can't have
my own (at least not with the sexy-most name "Exception"). Then, in my
(very personal) view I want it designed differently, and want to have it
extend my base class (which, incidentally, is called "Object" and does
not have constructor:)) - again, this is my very personal feeling
about how it should be - so I'll just have my own exception, which is
perfectly OK and dealt with very well by the Zend Engine.
I'm not the only PHP user out there with his or her own understanding of
subtleties in class design (new Reflection_Class("xxx") vs.
Reflection_Class::forName("xxx"). As for base classes, whip up Google,
search for object.php and see for yourself.
- Timm