Hello,
I was looking at DateTimeInterface in order to provide my own
implementation of it, when I hit this:
"Fatal error: DateTimeInterface can't be implemented by user classes in"
Is there any actual reason for this kind of limitation?
Can it be removed before going stable?
I also wasn't able to find any RFC information around it on
https://wiki.php.net/rfc#php_55 - is there any previous discussion around
this, or did it just sneak its way in?
Greets,
Marco Pivetta
On Tue, 21 Jul 2015 15:01:06 +0400, Marco Pivetta ocramius@gmail.com
wrote:
Hello,
I was looking at DateTimeInterface in order to provide my own
implementation of it, when I hit this:"Fatal error: DateTimeInterface can't be implemented by user classes
in"Is there any actual reason for this kind of limitation?
Can it be removed before going stable?I also wasn't able to find any RFC information around it on
https://wiki.php.net/rfc#php_55 - is there any previous discussion around
this, or did it just sneak its way in?Greets,
Marco Pivetta
Hey Marco,
The discussion was here https://github.com/php/php-src/pull/512
tl;dr core functions that accept DateTime and DateTimeImmutable
(DateTimeInterface basically) operate directly on timelib structures hence
they will break if you pass them a user-defined class. There's a
workaround though - it's to always call user-defined class's method
directly from built-in functions, so if you would call (new
DateTime())->diff(new UserDefinedDateTime()) it would call
UserDefinedDateTime#diff in the end which would need to implement the
logic.
Hey Niktia,
There's a workaround though - it's to always call user-defined class's
method directly from built-in functions
That's not the workaround, that's the actual fix: the current fix breaks
the OO model basics by introducing a limitation in the interface, rather
than in the broken implementations.
Greets,
Marco Pivetta
I should also add that this breaking change was introduced in a patch
release (5.5.8).
What has happened has happened, and I don't want to blame anyone, but this
is actually really broken :-\
Marco Pivetta
Hey Niktia,
There's a workaround though - it's to always call user-defined class's
method directly from built-in functionsThat's not the workaround, that's the actual fix: the current fix breaks
the OO model basics by introducing a limitation in the interface, rather
than in the broken implementations.Greets,
Marco Pivetta
I should also add that this breaking change was introduced in a patch
release (5.5.8).
That wasn't good, but I don't see how it was a breaking change. It
never worked before this change either. You now just told you're doing
something inappropriate.
What has happened has happened, and I don't want to blame anyone, but
this is actually really broken :-\
It's not a check that can be easily removed though. As Nikita says, this
all operate on internal structures. DateTimeInterface is meant so that
both DateTime and DateTimeImmutable can be type hinted for, and not
really for user land. Retrofitting PHP's DateTime stuff with user
extended classes and implementations is not going to be a trivial thing.
cheers,
Derick
I should also add that this breaking change was introduced in a patch
release (5.5.8).That wasn't good, but I don't see how it was a breaking change. It
never worked before this change either. You now just told you're doing
something inappropriate.
It's an interface, it doesn't "work", it simply gets implemented (then the
implementing code "works").
What has happened has happened, and I don't want to blame anyone, but
this is actually really broken :-\It's not a check that can be easily removed though. As Nikita says, this
all operate on internal structures. DateTimeInterface is meant so that
both DateTime and DateTimeImmutable can be type hinted for, and not
really for user land. Retrofitting PHP's DateTime stuff with user
extended classes and implementations is not going to be a trivial thing.
Then make DateTime and DateTimeImmutable only interact with DateTime and
DateTimeImmutable (or child classes), but don't rely on the interface if
you're not actually respecting it internally in first place, no?
Marco Pivetta
Marco Pivetta wrote on 21/07/2015 13:29:
Then make DateTime and DateTimeImmutable only interact with DateTime and
DateTimeImmutable (or child classes), but don't rely on the interface if
you're not actually respecting it internally in first place, no?
What exactly are you suggesting? That DateTimeInterface shouldn't exist
at all?
It's useful to be able to check if a given variable is an instance of
either DateTime or DateTimeImmutable, and an Interface is an obvious way
to do this, regardless of what else can be done with that interface.
As you can see here: http://3v4l.org/SU1Xq this was definitely a bug in
early 5.5.x releases (the error is a frankly baffling "Fatal error:
DateTime::diff() must be derived from DateTimeImmutable::diff"), so the
change in behaviour in a point release seems justified. HHVM apparently
still allows the implementation, then fatals when you try to diff
against it.
So, userland implementations of the interface have never worked; it
might be nice to add the ability in, but in answer to the original
question, yes, there's a reason behind this limitation.
Regards,
Rowan Collins
[IMSoP]