All,
Yesterday, someone complained that classes that implement interfaces
succeed in doing so even when they don't satisfy the prototypes. While
this does cause an E_STRICT
message to be emitted, it would go unnoticed in
most cases, as E_STRICT
is off by default, in some cases - even when people
think it's on.
I believe that this behavior is wrong. I believe that classes should not
be allowed to say they implement an interface X, unless they actually
implement all of the methods in that interface with methods that are
compatible with its prototypes.
Reasoning:
- Interfaces (and for that matter, abstract classes) are a new feature in
PHP 5, used solely to enforce implementing classes to abide to the
prototypes. There's no issue of downwards compatibility, and there's no
other use case. - Without this, the whole mechanism of class type hints is rendered
useless. With it, it gives users the full power of class type hints (and
instanceof, for that matter) - because they always have the option of
adding an interface for their base classes.
Suggested behavior:
Any method that implements (directly or indirectly) an interface method or
an abstract method, will have implementation checks fully enforced, with an
E_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do not have
interface/abstract prototypes, will not change (E_STRICT message).
Comments welcome - we'd like to sort this out before RC2...
Zeev
Suggested behavior:
Any method that implements (directly or indirectly) an interface method or
an abstract method, will have implementation checks fully enforced, with an
E_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do not have
interface/abstract prototypes, will not change (E_STRICT message).Comments welcome - we'd like to sort this out before RC2...
Sounds good... I already thought we were doing this.
regards,
Derick
Zeev Suraski wrote:
Any method that implements (directly or indirectly) an interface method
or an abstract method, will have implementation checks fully enforced,
with anE_COMPILE_ERROR
emitted in case of an error.
Excuse my ignorance: What is defined as fully implementing the
interface? I guess all methods have to be implemented with all the
parameters having the same type if specified, right? What about
extending the parameter set, especially with default values?
E.g. is foo(A $a, $newparam = 'false) valid for foo(A $a)?
- Chris
Hey,
I just wanted to note the fact that I disagree with this.
In a perfect world, I would go with an E_COMPILE_ERROR
in all situations;
when inheriting regular classes (w/o abstract methods), abstract methods
and interfaces. That is what the academic part of me feels but knows can't
be done.
As this would break BC too much, I agree that inheriting from regular
classes should not lead to an error. I believe that for consistency sake
interfaces and abstract classes should behave the same as regular classes,
thus, if regular classes don't cause an error, the former also shouldn't.
I propose to leave things the way they are:
a) In E_STRICT
error_reporting there's an E_STRICT
warning when overriding
a method with an incompatible signature (for all cases).
b) PHP will keep BC compatibility for old classes and consistency between
them and the new classes. This way old classes and new classes/interfaces
will all behave the same.
That said, if the majority of people prefer the more aggressive approach of
E_COMPILE_ERROR
with interfaces and abstract methods, it can be changed.
Andi
At 11:49 AM 4/19/2004 +0300, Zeev Suraski wrote:
All,
Yesterday, someone complained that classes that implement interfaces
succeed in doing so even when they don't satisfy the prototypes. While
this does cause anE_STRICT
message to be emitted, it would go unnoticed
in most cases, asE_STRICT
is off by default, in some cases - even when
people think it's on.I believe that this behavior is wrong. I believe that classes should not
be allowed to say they implement an interface X, unless they actually
implement all of the methods in that interface with methods that are
compatible with its prototypes.Reasoning:
- Interfaces (and for that matter, abstract classes) are a new feature in
PHP 5, used solely to enforce implementing classes to abide to the
prototypes. There's no issue of downwards compatibility, and there's no
other use case.- Without this, the whole mechanism of class type hints is rendered
useless. With it, it gives users the full power of class type hints (and
instanceof, for that matter) - because they always have the option of
adding an interface for their base classes.Suggested behavior:
Any method that implements (directly or indirectly) an interface method or
an abstract method, will have implementation checks fully enforced, with
anE_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do not
have interface/abstract prototypes, will not change (E_STRICT message).Comments welcome - we'd like to sort this out before RC2...
Zeev
Andi Gutmans wrote:
aggressive approach of
E_COMPILE_ERROR
+1 :)
--
Sebastian Bergmann
http://sebastian-bergmann.de/ http://phpOpenTracker.de/
Das Buch zu PHP 5: http://professionelle-softwareentwicklung-mit-php5.de/
At 13:01 19/04/2004, Christian Schneider wrote:
Zeev Suraski wrote:
Any method that implements (directly or indirectly) an interface method
or an abstract method, will have implementation checks fully enforced,
with anE_COMPILE_ERROR
emitted in case of an error.Excuse my ignorance: What is defined as fully implementing the interface?
I guess all methods have to be implemented with all the parameters having
the same type if specified, right? What about extending the parameter set,
especially with default values?
E.g. is foo(A $a, $newparam = 'false) valid for foo(A $a)?
This is valid. As long as you can call the function using the same
prototype as the one in the interface, it's considered to be
compatible. You can extend it using default values.
Zeev
Zitat von Zeev Suraski zeev@zend.com:
At 13:01 19/04/2004, Christian Schneider wrote:
Zeev Suraski wrote:
Any method that implements (directly or indirectly) an interface
method or an abstract method, will have implementation checks fully
enforced, with anE_COMPILE_ERROR
emitted in case of an error.Excuse my ignorance: What is defined as fully implementing the
interface? I guess all methods have to be implemented with all the
parameters having the same type if specified, right? What about
extending the parameter set, especially with default values?
E.g. is foo(A $a, $newparam = 'false) valid for foo(A $a)?This is valid. As long as you can call the function using the same
prototype as the one in the interface, it's considered to be
compatible. You can extend it using default values.
+1 from a user's perspective, that is pro fatal errors on interfaces and
abstract methods but not on regular methods. That's the best balance on
keeping BC and introducing useful OO features.
Jan.
--
http://www.horde.org - The Horde Project
http://www.ammma.de - Neue Wege des Lernens
http://www.tip4all.de - Deine private Tippgemeinschaft
At 13:04 19/04/2004, Andi Gutmans wrote:
Hey,
I just wanted to note the fact that I disagree with this.
In a perfect world, I would go with anE_COMPILE_ERROR
in all situations;
when inheriting regular classes (w/o abstract methods), abstract methods
and interfaces. That is what the academic part of me feels but knows can't
be done.
As this would break BC too much, I agree that inheriting from regular
classes should not lead to an error. I believe that for consistency sake
interfaces and abstract classes should behave the same as regular classes,
thus, if regular classes don't cause an error, the former also shouldn't.
Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are out of
the picture, people will be more receptive to the idea - if we can go down
that route, that option clearly gets my vote. - If going for
E_COMPILE_ERROR
in all situations is not an option, then I
do see a significant difference between interface/abstract methods, and
real methods, when it comes to inheriting from them. The whole
interface/abstract/class type hints mechanism was added for the sole reason
of enforcing prototypes, and effectively, it is pretty much useless the way
things are now. If we re-enable fatal errors for interface inheritance -
we give OO programmers the ability to enforce prototypes. They would have
to use an interface (or an abstract class) in order to do so, since it
won't be enforced for just plain classes - but at least they'd have this
option.
To make it clear, my vote still goes for option #1, if people feel better
about it now...
Zeev
Zeev Suraski wrote:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are out
I'm not sure I understand what you mean by everything.
whole interface/abstract/class type hints mechanism was added for the
sole reason of enforcing prototypes, and effectively, it is pretty much
Concerning interface/abstract classes I can see you reasoning for
enforcing the prototype. Personally I don't feel like using interfaces
and abstract classes but as it is implemented in PHP5 it should be done
right. Make whips and chains people suffer fully from their bondage
addiction :-)
For class type hints (this is specifying the parameter type in your
function definition, right?) I think it should be enforced for calling
but not for extending. A specialized class often leaves out parameters
of the generic base class. E.g. db_record_foo may extend db_record which
takes the table as an argument which will always be foo for the
specialized class and hence left out there.
Does that make sense?
- Chris
Hello Zeev,
Monday, April 19, 2004, 12:14:40 PM, you wrote:
At 13:04 19/04/2004, Andi Gutmans wrote:
Hey,
I just wanted to note the fact that I disagree with this.
In a perfect world, I would go with anE_COMPILE_ERROR
in all situations;
when inheriting regular classes (w/o abstract methods), abstract methods
and interfaces. That is what the academic part of me feels but knows can't
be done.
As this would break BC too much, I agree that inheriting from regular
classes should not lead to an error. I believe that for consistency sake
interfaces and abstract classes should behave the same as regular classes,
thus, if regular classes don't cause an error, the former also shouldn't.
Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are out of
the picture, people will be more receptive to the idea - if we can go down
that route, that option clearly gets my vote.- If going for
E_COMPILE_ERROR
in all situations is not an option, then I
do see a significant difference between interface/abstract methods, and
real methods, when it comes to inheriting from them. The whole
interface/abstract/class type hints mechanism was added for the sole reason
of enforcing prototypes, and effectively, it is pretty much useless the way
things are now.
repeat useless.
If we re-enable fatal errors for interface inheritance -
we give OO programmers the ability to enforce prototypes. They would have
to use an interface (or an abstract class) in order to do so, since it
won't be enforced for just plain classes - but at least they'd have this
option.
To make it clear, my vote still goes for option #1, if people feel better
about it now...
fellBetter++
Doesn't this bring us back to the option to couple the severity for 'normal'
methods (no interface/abstract/typehints btw easily detecable by a new
fn_flag) with the ini setting for the engine's bc mode?
Best regards,
Marcus mailto:helly@php.net
Hello Zeev,
Monday, April 19, 2004, 12:14:40 PM, you wrote:
At 13:04 19/04/2004, Andi Gutmans wrote:
Hey,
I just wanted to note the fact that I disagree with this.
In a perfect world, I would go with anE_COMPILE_ERROR
in all
situations;
when inheriting regular classes (w/o abstract methods), abstract
methods
and interfaces. That is what the academic part of me feels but knows
can't
be done.
As this would break BC too much, I agree that inheriting from regular
classes should not lead to an error. I believe that for consistency
sake
interfaces and abstract classes should behave the same as regular
classes,
thus, if regular classes don't cause an error, the former also
shouldn't.Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are
out of
the picture, people will be more receptive to the idea - if we can go
down
that route, that option clearly gets my vote.
+1
- If going for
E_COMPILE_ERROR
in all situations is not an option,
then I
do see a significant difference between interface/abstract methods,
and
real methods, when it comes to inheriting from them. The whole
interface/abstract/class type hints mechanism was added for the sole
reason
of enforcing prototypes, and effectively, it is pretty much useless
the way
things are now.repeat useless.
yep.
To make it clear, my vote still goes for option #1, if people feel
better
about it now...fellBetter++
I also think this is the way to go.
George
George Schlossnagle wrote:
Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are+1
Are you guys serious about a compile error if I override a method with
different parameters? This must be the mailing list of a different
language than PHP...
- Chris
George Schlossnagle wrote:
Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are
+1Are you guys serious about a compile error if I override a method with
different parameters? This must be the mailing list of a different
language than PHP...
If you override an interface with a different number of parameters or
with incorrectly typed parameters, yes.
George
George Schlossnagle wrote:
Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are
+1Are you guys serious about a compile error if I override a method
with different parameters? This must be the mailing list of a
different language than PHP...If you override an interface with a different number of parameters or
with incorrectly typed parameters, yes.
^^^^^^^
make that read 'implement', of course.
George
George Schlossnagle wrote:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are+1
Are you guys serious about a compile error if I override a method with
different parameters? This must be the mailing list of a different
language than PHP...If you override an interface with a different number of parameters or
with incorrectly typed parameters, yes.
I agree there but 1. was saying everything, that included more than
just interfaces and abstract classes. That's why I'm asking if you're
serious.
Let's recap:
a) People agree to be strict for interfaces and abstract classes.
b) There was a proposal to also give a compile error for normal methods.
I'm not sure if people who gave a +1 here really meant it.
- Chris
It is. This is a mailing list discussing for discussing the use of
exceptions and compile errors in java. If you are not interested in
that, please unsubscribe.
-Sterling
George Schlossnagle wrote:
Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are
+1Are you guys serious about a compile error if I override a method with
different parameters? This must be the mailing list of a different
language than PHP...
- Chris
mo compile errors mo better.
+1.
-Sterling
Hello Zeev,
Monday, April 19, 2004, 12:14:40 PM, you wrote:
At 13:04 19/04/2004, Andi Gutmans wrote:
Hey,
I just wanted to note the fact that I disagree with this.
In a perfect world, I would go with anE_COMPILE_ERROR
in all
situations;
when inheriting regular classes (w/o abstract methods), abstract
methods
and interfaces. That is what the academic part of me feels but
knows can't
be done.
As this would break BC too much, I agree that inheriting from
regular
classes should not lead to an error. I believe that for consistency
sake
interfaces and abstract classes should behave the same as regular
classes,
thus, if regular classes don't cause an error, the former also
shouldn't.Just to clarify a bit on why I think that we should differentiate:
- First of all, I agree that in a perfect world we should go with
E_COMPILE_ERROR
for everything. Maybe now that's constructors are
out of
the picture, people will be more receptive to the idea - if we can
go down
that route, that option clearly gets my vote.+1
- If going for
E_COMPILE_ERROR
in all situations is not an option,
then I
do see a significant difference between interface/abstract methods,
and
real methods, when it comes to inheriting from them. The whole
interface/abstract/class type hints mechanism was added for the sole
reason
of enforcing prototypes, and effectively, it is pretty much useless
the way
things are now.repeat useless.
yep.
To make it clear, my vote still goes for option #1, if people feel
better
about it now...fellBetter++
I also think this is the way to go.
George
mo compile errors mo better.
But NOT for normal methods!
Derick
mo compile errors mo better.
But NOT for normal methods!
I agree with Derick. Compile errors for interfaces methods good.
Compile errors for normal inherited methods bad.
Derick
--
// George Schlossnagle
// Postal Engine -- http://www.postalengine.com/
// Ecelerity: fastest MTA on earth
mo compile errors mo better.
But NOT for normal methods!
I agree with Derick. Compile errors for interfaces methods good.
Compile errors for normal inherited methods bad.
Amen! While I'm in favor of this for other reasons, my largest
argument is backwards compatibility.
Compile errors for normal methods is guaranteed to break lots of PHP
4 code and not in a trivial s/var/public/g kind of way.
-adam
--
adam@trachtenberg.com
author of o'reilly's php cookbook
avoid the holiday rush, buy your copy today!
Suggested behavior:
Any method that implements (directly or indirectly) an interface method or
an abstract method, will have implementation checks fully enforced, with an
E_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do not have
interface/abstract prototypes, will not change (E_STRICT message).Comments welcome - we'd like to sort this out before RC2...
I couldn't agree more (since I'm the one who "complained" =)
This can be very frustrating..
/Magnus
--
BOFH Excuse #412:
Radial Telemetry Infiltration
Suggested behavior:
Any method that implements (directly or indirectly) an interface
method or
an abstract method, will have implementation checks fully
enforced, with an
E_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do
not have
interface/abstract prototypes, will not change (E_STRICT
message).Comments welcome - we'd like to sort this out before RC2...
I don't like the idea as it does not allow var args to emulate
overloaded methods. I repeat myself when I say that IMO such
strictness does not fit to PHP's loose character.
--
Ferdinand Beyer
<fb@fbeyer.com
Hello Ferdinand,
Monday, April 19, 2004, 4:10:29 PM, you wrote:
Suggested behavior:
Any method that implements (directly or indirectly) an interface
method or
an abstract method, will have implementation checks fully
enforced, with an
E_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do
not have
interface/abstract prototypes, will not change (E_STRICT
message).Comments welcome - we'd like to sort this out before RC2...
I don't like the idea as it does not allow var args to emulate
overloaded methods. I repeat myself when I say that IMO such
strictness does not fit to PHP's loose character.
Simply decalre thos methos with an empty signature and use the
appropriate functions to handle the arguments?
marcus
--
Best regards,
Marcus mailto:helly@php.net
I agree. Interfaces are useless if you can't guarantee that a class
actually implements them. Violating an interface is violating a contract
and it should be an compile error - indeed, when coding I mostly rely on not
properly implementing interfaces to be a compile error.
-Sterling
-----Original Message-----
From: Zeev Suraski [mailto:zeev@zend.com]
Sent: Monday, April 19, 2004 1:49 AM
To: internals@lists.php.net
Subject: [PHP-DEV] Interface inheritance
All,
Yesterday, someone complained that classes that implement interfaces
succeed in doing so even when they don't satisfy the prototypes. While
this does cause an E_STRICT
message to be emitted, it would go unnoticed in
most cases, as E_STRICT
is off by default, in some cases - even when people
think it's on.
I believe that this behavior is wrong. I believe that classes should not
be allowed to say they implement an interface X, unless they actually
implement all of the methods in that interface with methods that are
compatible with its prototypes.
Reasoning:
- Interfaces (and for that matter, abstract classes) are a new feature in
PHP 5, used solely to enforce implementing classes to abide to the
prototypes. There's no issue of downwards compatibility, and there's no
other use case. - Without this, the whole mechanism of class type hints is rendered
useless. With it, it gives users the full power of class type hints (and
instanceof, for that matter) - because they always have the option of
adding an interface for their base classes.
Suggested behavior:
Any method that implements (directly or indirectly) an interface method or
an abstract method, will have implementation checks fully enforced, with an
E_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do not have
interface/abstract prototypes, will not change (E_STRICT message).
Comments welcome - we'd like to sort this out before RC2...
Zeev
Yes, but I claim that inheritance is exactly the same thing. I comes with
an interface which needs to be adhered to. It does tend to be inconsistent
if we E_ERROR
out on interfaces and not on inheritance.
At 09:31 AM 4/19/2004 -0700, Sterling Hughes wrote:
I agree. Interfaces are useless if you can't guarantee that a class
actually implements them. Violating an interface is violating a contract
and it should be an compile error - indeed, when coding I mostly rely on not
properly implementing interfaces to be a compile error.-Sterling
-----Original Message-----
From: Zeev Suraski [mailto:zeev@zend.com]
Sent: Monday, April 19, 2004 1:49 AM
To: internals@lists.php.net
Subject: [PHP-DEV] Interface inheritanceAll,
Yesterday, someone complained that classes that implement interfaces
succeed in doing so even when they don't satisfy the prototypes. While
this does cause anE_STRICT
message to be emitted, it would go unnoticed in
most cases, asE_STRICT
is off by default, in some cases - even when people
think it's on.I believe that this behavior is wrong. I believe that classes should not
be allowed to say they implement an interface X, unless they actually
implement all of the methods in that interface with methods that are
compatible with its prototypes.Reasoning:
- Interfaces (and for that matter, abstract classes) are a new feature in
PHP 5, used solely to enforce implementing classes to abide to the
prototypes. There's no issue of downwards compatibility, and there's no
other use case.- Without this, the whole mechanism of class type hints is rendered
useless. With it, it gives users the full power of class type hints (and
instanceof, for that matter) - because they always have the option of
adding an interface for their base classes.Suggested behavior:
Any method that implements (directly or indirectly) an interface method or
an abstract method, will have implementation checks fully enforced, with an
E_COMPILE_ERROR emitted in case of an error.
Behavior for methods that override regular parent methods, that do not have
interface/abstract prototypes, will not change (E_STRICT message).Comments welcome - we'd like to sort this out before RC2...
Zeev
I would prefer <speak evil>an ini option</speak evil>, while on a
development or testing server interfaces are great, I would love to be
able to reduce this to a E_NOTICE
on a live server, and stuff it in an
error log...
Regards
Alan
Zeev Suraski wrote:
All,
Yesterday, someone complained that classes that implement interfaces
succeed in doing so even when they don't satisfy the prototypes. While
this does cause anE_STRICT
message to be emitted, it would go unnoticed
in most cases, asE_STRICT
is off by default, in some cases - even when
people think it's on.I believe that this behavior is wrong. I believe that classes should
not be allowed to say they implement an interface X, unless they
actually implement all of the methods in that interface with methods
that are compatible with its prototypes.Reasoning:
- Interfaces (and for that matter, abstract classes) are a new feature
in PHP 5, used solely to enforce implementing classes to abide to the
prototypes. There's no issue of downwards compatibility, and there's no
other use case.- Without this, the whole mechanism of class type hints is rendered
useless. With it, it gives users the full power of class type hints
(and instanceof, for that matter) - because they always have the option
of adding an interface for their base classes.Suggested behavior:
Any method that implements (directly or indirectly) an interface method
or an abstract method, will have implementation checks fully enforced,
with anE_COMPILE_ERROR
emitted in case of an error.
Behavior for methods that override regular parent methods, that do not
have interface/abstract prototypes, will not change (E_STRICT message).Comments welcome - we'd like to sort this out before RC2...
Zeev
--
Can you help out?
Need Consulting Services or Know of a Job?
http://www.akbkhome.com
ZS>>I believe that this behavior is wrong. I believe that classes should
ZS>>not be allowed to say they implement an interface X, unless they
ZS>>actually implement all of the methods in that interface with methods
ZS>>that are compatible with its prototypes.
I agree. Since interfaces and abstract classes are new to PHP5, and do not
pose compatibility problem, I think it's good to make them strict. The old
behaviour can be always obtained by using regular classes.
Stanislav Malyshev, Zend Products Engineer
stas@zend.com http://www.zend.com/ +972-3-6139665 ext.115