Skip to content
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

Add Stringable interface #5083

Merged
merged 2 commits into from Mar 2, 2020
Merged

Add Stringable interface #5083

merged 2 commits into from Mar 2, 2020

Conversation

nicolas-grekas
Copy link
Contributor

@nicolas-grekas nicolas-grekas commented Jan 13, 2020

Copy link
Contributor

@Ocramius Ocramius left a comment

Would require .phpt additions to verify the static definitions of the interface (see #2535 for examples)

Zend/zend_interfaces.stub.php Outdated Show resolved Hide resolved
@ntzm
Copy link
Contributor

@ntzm ntzm commented Jan 13, 2020

Can I ask why you don't also support other types that can be cast to a string? e.g. everything but arrays and object that don't have __toString declared?

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Jan 13, 2020

Can I ask why you don't also support other types that can be cast to a string? e.g. everything but arrays and object that don't have __toString declared?

I'm sorry I totally miss your question. There is no such thing as "supporting other types".

@Ocramius
Copy link
Contributor

@Ocramius Ocramius commented Jan 13, 2020

@ntzm (array), (int), (float) and (bool) casts do not go through magic methods: there has been a separate discussion about that at https://externals.io/message/105589

@nicolas-grekas nicolas-grekas force-pushed the stringable branch 3 times, most recently from d7a345c to 52d1736 Compare Jan 13, 2020
@slavcodev
Copy link

@slavcodev slavcodev commented Jan 13, 2020

On purpose also, for BC, classes that implement __toString aren't required to declare the interface.
Such classes wouldn't pass the above union type, but that's expected, as that's the semantics of the language.

Is there any reason to keep the magic method __toString in new interface then?

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Jan 13, 2020

Is there any reason to keep the magic method __toString in new interface then?

of course there is: we want to be sure, from a type pov, that the object implements the casting magic method.

@slavcodev
Copy link

@slavcodev slavcodev commented Jan 13, 2020

But for example JsonSerializable does not require magic method.

@nicolas-grekas nicolas-grekas force-pushed the stringable branch 6 times, most recently from 5d9cb20 to 75eae57 Compare Jan 13, 2020
ext/spl/spl_directory.h Outdated Show resolved Hide resolved
@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Jan 13, 2020

Is there any reason to keep the magic method __toString in new interface then?
But for example JsonSerializable does not require magic method.

I think I don't understand your question. I have a few ideas about what you may mean but can't decide which one is the good one. Can you give examples of what you mean? Or more details, please?

@slavcodev
Copy link

@slavcodev slavcodev commented Jan 13, 2020

Sure, I mean something like

interface Stringable
{
   function toString(): string;
}

seems this also solves the issue with return type and BC.

lassemettovaara referenced this issue in laravel/framework Jan 14, 2020
@nicolas-grekas nicolas-grekas force-pushed the stringable branch 4 times, most recently from aa675c5 to 0789a35 Compare Jan 14, 2020
@GrahamCampbell
Copy link
Contributor

@GrahamCampbell GrahamCampbell commented Jan 14, 2020

Is there an RFC for this. Maybe pose the two options for a vote, with three choices. No interface, option one, option two?

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Jan 14, 2020

@GrahamCampbell it's way too early to think about voting options. There has been very little discussion on the matter, and there has been none on php-internals, which is still the only official way AFAIK.

Zend/zend_interfaces.c Outdated Show resolved Hide resolved
Zend/zend_compile.c Outdated Show resolved Hide resolved
@nikic
Copy link
Member

@nikic nikic commented Feb 6, 2020

Just as a heads up, I rebased and force pushed.

Regarding the automatic implementation of Stringable, I initially thought we could simply add this at the very end of inheritance ... but then I realized that this automatic implementation could be relevant for variance checks:

class Foo {
    public function test(): Stringable {}
}
class Bar extends Foo {
    public function test(): Bar {}
    public function __toString() {}
}

Which would be legal if Bar automatically implements Stringable. To allow that, we need to add it as a proper interface during initial compilation.

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Feb 6, 2020

Thanks for the heads up.

we need to add it as a proper interface during initial compilation.

how do we achieve this? in zend_compile.c? Did you give it a try?

@nikic
Copy link
Member

@nikic nikic commented Feb 6, 2020

@nicolas-grekas I pushed a new commit that should do it for user classes.

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Feb 6, 2020

Great, thank you! I'm going to update the RFC then.
About extensions, we're OK to let them add the interface explicitly, isn't it?

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Feb 11, 2020

PR rebased to fix some conflicts reported by GitHub. RFC updated to mention that the interface is added automatically once __toString is found.

@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Feb 13, 2020

Vote is now open btw: https://wiki.php.net/rfc/stringable

@nicolas-grekas nicolas-grekas force-pushed the stringable branch 3 times, most recently from b88af93 to f815dd2 Compare Feb 27, 2020
Zend/tests/bug26166.phpt Show resolved Hide resolved
@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Mar 2, 2020

@nikic Now that the RFC has been accepted, would you mind merging this PR, please? (or someone else with merge right?) Or do I need to do anything else before?

@KalleZ
Copy link
Member

@KalleZ KalleZ commented Mar 2, 2020

@nicolas-grekas I granted you php-src karma so you can merge it yourself[1], see the wiki here[2] for merging from Github.

It should take about 15min or so tops for these new karma rights to syncronize.

[1] http://svn.php.net/viewvc?view=revision&revision=349278
[2] https://wiki.php.net/vcs/gitworkflow

@php-pulls php-pulls merged commit 336eb48 into php:master Mar 2, 2020
0 of 5 checks passed
@nicolas-grekas
Copy link
Contributor Author

@nicolas-grekas nicolas-grekas commented Mar 2, 2020

Thanks @KalleZ. Thank you everyone for the feedback here!

@nicolas-grekas nicolas-grekas deleted the stringable branch Mar 2, 2020
@carusogabriel carusogabriel added this to the PHP 8.0 milestone May 29, 2020
jrfnl added a commit to PHPCompatibility/PHPCompatibility that referenced this issue Jul 19, 2020
> Added Stringable interface, which is automatically implemented if a class defines a __toString() method.

Refs:
* https://wiki.php.net/rfc/stringable
* php/php-src#5083
* php/php-src@336eb48
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.

None yet