Skip to content

Dont\ToString lies to its consumers in PHP 8 because it implements Stringable #34

@lexidor

Description

@lexidor

The manner in which Dont\ToString is enforced, makes instanceof tell lies.

final class Plain {}
final class DontToStringMe { use Dont\ToString; }
$plain = new Plain;
$dont = new DontToStringMe;
var_dump($plain instanceof Stringable); // false
var_dump($dont instanceof Stringable); // true

Both classes throw when cast to a string. One uses the standard PHP message, could not convert object of type X to a string. The other throw an exception from this library.

If the class you are writing is final, then you don't need this trait. You either don't inhirit a __toString, which gives you sane default behavior in PHP. If you do inherit one, you violate liskov substitution by using this trait. If the class you are writing is not final (and intended to be extended by library users), why limit them in being able to implement their own __toString()?

Dont\Serialise does not implement Serializable > #21 (comment) <, since this would be lying to consumers. I believe that Dont\ToString isn't like the other traits for this reason.

I am interested to know whether others have an opposing view. I don't check a lot of things using instanceof nor do I use Stringable as a typehint, so it took a while for this to dawn on me. I have since stopped using Dont\JustDont and made my own trait which includes all traits, except for ToString, because of this behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions