Skip to content

Allow traits to implement interfaces #1773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

kevingessner
Copy link

Traits can now declare one or more interfaces. The trait must implement
each of the methods from all the interfaces it implements with
compatible declarations. Failure to do so is a fatal error.

The interfaces declared by a trait do not affect classes that use the
trait.

Implements Proposal 1 of https://wiki.php.net/rfc/traits-with-interfaces

Traits can now declare one or more interfaces.  The trait must implement
each of the methods from all the interfaces it implements with
compatible declarations.  Failure to do so is a fatal error.

The interfaces declared by a trait do not affect classes that use the
trait.

Implements Proposal 1 of https://wiki.php.net/rfc/traits-with-interfaces
@nitso
Copy link

nitso commented Dec 26, 2016

I mostly like this idea of implementing an interface in a trait. By there is one pitfall: whenever you rename methods used from trait (http://php.net/manual/en/language.oop5.traits.php#language.oop5.traits.conflict) , resulting class may not implement specified interface anymore.
IMO that should be anyway analyzed and implemented in code.

@krakjoe krakjoe removed the PHP7.1 label Jan 3, 2017
@betaglop
Copy link

This would be a really interesting feature for us!
We have created a new design pattern called "Outer-Extension" (already implemented here but its specifications are still a work in progress) that would use this intensively. We'll stay focused on how this pull-request will be integrated or not in PHP (even PHP-5.6+).

resulting class may not implement specified interface anymore.

This is already the case for classes, when one says it implements a given interface and at the end it does not. This should raise a PHP error.

@KalleZ
Copy link
Member

KalleZ commented Jan 27, 2017

@betaglop such features will only be introduced in PHP.next, which currently is 7.2 as per our policy :-)

@betaglop
Copy link

nice thx for this answer.

@Fleshgrinder
Copy link
Contributor

@kevingessner any update on this one? Would love to see this feature in PHP. Maybe start by reviving the discussion on internals?

@antonkomarev
Copy link

Is there is a possibility to see this is 7.x?

@cautionbug
Copy link

cautionbug commented Dec 2, 2017

Found the RFC for this while researching design patterns that help ensure a contract between Interface and relevant Traits within the current functionality. One thing in particular, a class executing some kind of verification to register visibility of methods required by an interface, which are provided by relevant Traits. An ignition system, of sorts, so the class can go about its business knowing the Trait/Interface contract is secured. (If anyone has suggestions where i can observe and learn how to build such a design structure, it would be appreciated.)

A couple thoughts on the RFC:

  1. i favor the Failure approach for aliasing Interface methods without an available substitute from the using class. It makes traits a bit more rigid, which isn't their intent, but the concept of Interfaces is exactly that rigidity: you're making a promise. Seems to me that a Class, using a Trait that is bound to an Interface, would lose its implementation status when a method is missing leads to more headache than graceful degradation. Maybe if it did so with emission of a Notice so there's some outward sign that a risky thing occurred?
  2. What is the impact or intended approach for Traits that use other Traits? The same structural dilemmas come into play:
    • Trait A implements Interface A that declares public foo();, and Trait A implements it.
    • Trait B implements Interface B that declares public foo();, and Trait B implements it.

The implication is each Trait is providing expected logic according to its own requirements/responsibilities, but the collision requires a resolution: only 1 of them can win the foo().

i really hope the RFC gets some traction. This would be great for 7.3 (and would have been for 7.1 and then 7.2...) 😉


Addendum:
This feature reminded me of an article from a couple years ago. Wondered what the counterpoint to the weak position of Traits to enforce Interface contracts is...
https://eliasvo.wordpress.com/2015/06/07/php-traits-if-they-werent-evil-theyd-be-funny

@php-pulls
Copy link

Comment on behalf of kalle at php.net:

Closing due to no activity, please re-open if you still intend on working on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants