Hi,
I would like to propose a new syntax that let's you implement an interface
only if it exists.
class MyClass extends ?OptionalInterface {}
If the OptionalInterface
exists, the class implements it. If no such
interface can be found, it is ignored.
https://wiki.php.net/rfc/optional-interfaces
The need to declare compatibility with a certain interface without requiring
the interface itself comes up when you're writing code that should work with
various versions of other libraries or PHP itself and when a library
provides interoperability with some other library or a PHP extension, but
does not require it.
Although this would mainly be used by library developers, the consumers of
those libraries would also benefit as this syntax would clearly communicate
the intention of optional interoperability. IDEs and static analysis tools
could also have easier time with ?OptionalInterface
instead of class
definitions inside an if (interface_exists(.)) { . } else {.}
.
I've not entirely sure about the naming as an "optional interface" feels
like an oxymoron. I've also considered names like non-required interfaces,
conditional interfaces, optional/conditional implementation or even soft
interfaces/soft implementation. Please let me know if the naming itself
bothers you.
Previous discussion: https://externals.io/message/125967
WIP implementation: https://github.com/php/php-src/pull/17288
Looking forward to your feedback and suggestions!
Juris
Hi,
I would like to propose a new syntax that let’s you implement an
interface only if it exists.
class MyClass extends ?OptionalInterface {}
If the
OptionalInterface
exists, the class implements it. If no such
interface can be found, it is ignored.https://wiki.php.net/rfc/optional-interfaces
The need to declare compatibility with a certain interface without
requiring the interface itself comes up when you’re writing code that
should work with various versions of other libraries or PHP itself and
when a library provides interoperability with some other library or a
PHP extension, but does not require it.Although this would mainly be used by library developers, the consumers
of those libraries would also benefit as this syntax would clearly
communicate the intention of optional interoperability. IDEs and static
analysis tools could also have easier time with?OptionalInterface
instead of class definitions inside anif (interface_exists(…)) { … } else {…}
.I’ve not entirely sure about the naming as an “optional interface”
feels like an oxymoron. I’ve also considered names like non-required
interfaces, conditional interfaces, optional/conditional implementation
or even soft interfaces/soft implementation. Please let me know if the
naming itself bothers you.Previous discussion: https://externals.io/message/125967
WIP implementation: https://github.com/php/php-src/pull/17288Looking forward to your feedback and suggestions!
Juris
Going by the design/RFC, this seems reasonable to me, and I can see the use for it. My only concern would be if the implementation makes anything more complex for the engine or compiler that could cause future optimization problems, but I'm not qualified to answer that.
It may help the RFC to include some non-trivial real-world-ish examples, in addition to the A and B stuff. (You can probably steal some from the projects linked to.)
--Larry Garfield
Hi,
I would like to propose a new syntax that let’s you implement an interface
only if it exists.
class MyClass extends ?OptionalInterface {}
If the
OptionalInterface
exists, the class implements it. If no such
interface can be found, it is ignored.https://wiki.php.net/rfc/optional-interfaces
Hi Juris,
I think the proposal looks good but I some some points to be discussed:
From what I understand, the autoloading mechanism would be triggered for
the optional interface, but it would not be an error if it would not
succeed. I think we should explicitly spell this out in the RFC, to make it
clear that autoloading will be attempted.
If an interface was not available at class declaration time, the function
class_implements (on both class and object) will return false going
forward, as if the class definition did not contain the interface at all?
Similarly, if at runtime the object would be passed to a function/method
that has the parameter type of that interface, would it fail saying that
the object is not an instance of that interface?
Note: autoloading is not triggered when just using an interface/class name
in a parameter type or as return type.
I think completely erasing the interface sounds good, I just think it
should be explicitly spelled out in the RFC, and all the implications that
follows.
If a second class will implement the same optional interface, will it
trigger autoloading again? I think it should.
If in the meantime, between defining two such classes, the interface would
be defined (using a hack or some sort), would it cause problems? I think
that given the current existing workarounds this is a valid concern.
To avoid problems, it would be wise to completely erase the interface from
first class definition when it was not available, even if the second class
might have it.
-- Alex
Hi,
I would like to propose a new syntax that let’s you implement an interface only if it exists.
class MyClass extends ?OptionalInterface {}
If the
OptionalInterface
exists, the class implements it. If no such interface can be found, it is ignored.
https://wiki.php.net/rfc/optional-interfaces https://wiki.php.net/rfc/optional-interfaces
The need to declare compatibility with a certain interface without requiring the interface itself comes up when you’re writing code that should work with various versions of other libraries or PHP itself and when a library provides interoperability with some other library or a PHP extension, but does not require it.
Although this would mainly be used by library developers, the consumers of those libraries would also benefit as this syntax would clearly communicate the intention of optional interoperability. IDEs and static analysis tools could also have easier time with
?OptionalInterface
instead of class definitions inside anif (interface_exists(…)) { … } else {…}
.
I’ve not entirely sure about the naming as an “optional interface” feels like an oxymoron. I’ve also considered names like non-required interfaces, conditional interfaces, optional/conditional implementation or even soft interfaces/soft implementation. Please let me know if the naming itself bothers you.
Previous discussion: https://externals.io/message/125967 https://externals.io/message/125967
WIP implementation: https://github.com/php/php-src/pull/17288 https://github.com/php/php-src/pull/17288
Looking forward to your feedback and suggestions!
Juris
Hi
I've left some remarks on your PR to help you further with the opcache stuff.
This should fix the tests and answer some questions.
I also left a concern regarding the caching, and in particular I'm thinking about the inheritance cache. I'll copy it here:
Suppose this scenario:
- You do a request and an optional interface is not available, this class is cached without that interface.
- A future request comes in, and reuses the cache, but since this may be via a different code path it's possible that the interface is now available. Yet because the class was cached, this won't implement the interface now even though it's available at this point in time. I'm not entirely sure if this is a real problem but it should be checked. I also don't know what assumptions in the engine this may break.
Kind regards
Niels